<commit_before>/*global chai:true, describe:true, it:true, before: true, beforeEach:true, after:true, afterEach:true, expect:true, should:true, sinon:true */
define(['Squire'], function (Squire) {
  "use strict";
  describe('Router - jQuery Mobile Implementation', function () {
    var injector, model, collection;

      before(function (done) {

        model = function (id) {
          return {
            id: id,
            prepareForView: sinon.stub().returns({
              then: function () {return {}}
            }),
            set: sinon.stub().returns({})
          }
        }

        collection = {};

        injector = new Squire();
        injector.mock('model-application', {
          set: function () {return {}},
          interactions: {
            get: function (id) {
              if (!collection[id]) {
                collection[id] = model(id);
              }
              return collection[id];
            },
            set: function () {return {}}
          }
        });
        injector.mock('view-interaction', {
          render: function () {return {}}
        });
        done();

      });

    // THIS HAS BEEN MOVED TO MODEL-APPLICATION!!!
    describe('initialize()', function () {
      //it("should create binding to pagebeforeload that passes the event data object to routeRequest", function () {
        //context(['router'], function (router) {
          //sinon.stub(router, "routeRequest");
          //$(document).trigger('pagebeforeload', {});
          //router.routeRequest.called.should.be.true;
          //router.routeRequest.calledWith({}).should.be.true;
          //router.routeRequest.restore();
        //});
      //});
    });

    describe('routeRequest(data)', function () {
      var router, testmodel;

      beforeEach(function (done) {
        require(['feature!promises'], function (Promise) {
          injector.require(['../scripts/router'], function (module) {
            testmodel = model(1);
            sinon.stub(module, "inheritanceChain", function () {return testmodel});
            sinon.stub(module, "parseArgs", function () {return {}});
            router = module;
            router.routeRequest({
              dataUrl: "/test",
              deferred: Promise.resolve()
            });
            done();
          });
        });
      });

      afterEach(function () {
        router.inheritanceChain.restore();
        router.parseArgs.restore();
        testmodel.prepareForView.reset();
      });

      it("should call the inheritanceChain function to get the correct interaction model", function () {
        router.inheritanceChain.called.should.be.true;
      });

      it("should start the parseArgs function", function () {
        router.parseArgs.called.should.be.true;
      });

      it("should instruct the model to prepareForView", function () {
        router.inheritanceChain.called.should.be.true;
        testmodel.prepareForView.called.should.be.true;
      });

      //it("should create a new view", function () {
        //context(['view-interaction'], function (view) {
          //view.render.should.be.true;
          //view.reset();
        //});
      //});

      //it("should resolve the event deferred (transitioning the view onscreen)", function (done) {
        //dfrd.always(function () {
          //done();
        //});
      //});

      //it("should remove old views from the DOM");
    });

    describe('inheritanceChain(urlString)', function () {
      var router;

      beforeEach(function (done) {
        injector.require(['../scripts/router'], function (module) {
          router = module;
          done();
        });
      });

      afterEach(function () {});

      it("should parse the path given to find the current interaction", function () {
        var data = "/councils/traffic";
        router.inheritanceChain(data).id.should.equal('traffic');
      });

      //it("should detect interactions specified by ID (instead of name)");

      it("should use the path to determine the inheritance chain", function () {
        var data = "/councils/traffic";
        var model = router.inheritanceChain(data);
        model.set.called.should.be.true;
        model.set.calledWith({parent: 'councils'}).should.be.true;
      });

      //it("should set the parent of each interaction in the chain on the associated model", function () {
        //var interaction = router.inheritanceChain("/test/second");
        //interaction.get('parent').should.be.string(interactionSetSpy.secondCall.args[0].parent);
      //});

      //it("should set the topmost interaction in the chain to have a parent of the answerspace", function () {
        //router.inheritanceChain("/test").get('parent').should.be.string("app");
      //});

      //it("should return the correct interaction to attach the view to", function () {
        //router.inheritanceChain("/test").should.be.instanceOf(Backbone.Model);
      //});

      it("should handle the same interaction being listed twice (last winning out)", function () {
        var data = "/councils/traffic/trafficcams/traffic";
        router.inheritanceChain(data).id.should.equal('traffic');
      });

      it("should drop blank trailing values from the array", function () {
        var data = "/councils/traffic/";
        router.inheritanceChain(data).id.should.equal('traffic');
      });
    });

    //describe('parseArgs(argsString, model)', function () {
      //it("should identify any GET arguments in the input string");
      //it("should parse found arguments into an object");
      //it("should set the object on the model as 'args'");
    //});
  });
});
<commit_msg>Fix the router test suite<commit_after>/*global chai:true, describe:true, it:true, before: true, beforeEach:true, after:true, afterEach:true, expect:true, should:true, sinon:true */
define(['Squire'], function (Squire) {
  "use strict";
  describe('Router - jQuery Mobile Implementation', function () {
    var injector, model, collection;

      before(function (done) {

        model = function (id) {
          return {
            id: id,
            prepareForView: sinon.stub().returns({
              then: function () {return {}}
            }),
            set: sinon.stub().returns({})
          }
        }

        collection = {};

        injector = new Squire();
        injector.mock('model-application', {
          set: function () {return {}},
          interactions: {
            get: function (id) {
              if (!collection[id]) {
                collection[id] = model(id);
              }
              return collection[id];
            },
            set: function () {return {}}
          },
          datastore: function () {return this},
          collections: function () {return Promise.resolve()},
          setup: function () {return Promise.resolve()},
          populate: function () {return Promise.resolve()},
          initialRender: function () {}
        });
        injector.mock('view-interaction', {
          render: function () {return {}}
        });
        done();

      });

    // THIS HAS BEEN MOVED TO MODEL-APPLICATION!!!
    describe('initialize()', function () {
      //it("should create binding to pagebeforeload that passes the event data object to routeRequest", function () {
        //context(['router'], function (router) {
          //sinon.stub(router, "routeRequest");
          //$(document).trigger('pagebeforeload', {});
          //router.routeRequest.called.should.be.true;
          //router.routeRequest.calledWith({}).should.be.true;
          //router.routeRequest.restore();
        //});
      //});
    });

    describe('routeRequest(data)', function () {
      var router, testmodel;

      beforeEach(function (done) {
        require(['feature!promises'], function (Promise) {
          injector.require(['../scripts/router'], function (module) {
            testmodel = model(1);
            sinon.stub(module, "inheritanceChain", function () {return testmodel});
            sinon.stub(module, "parseArgs", function () {return {}});
            router = module;
            router.routeRequest({
              dataUrl: "/test",
              deferred: Promise.resolve()
            });
            done();
          });
        });
      });

      afterEach(function () {
        router.inheritanceChain.restore();
        router.parseArgs.restore();
        testmodel.prepareForView.reset();
      });

      it("should call the inheritanceChain function to get the correct interaction model", function () {
        router.inheritanceChain.called.should.be.true;
      });

      it("should start the parseArgs function", function () {
        router.parseArgs.called.should.be.true;
      });

      it("should instruct the model to prepareForView", function () {
        router.inheritanceChain.called.should.be.true;
        testmodel.prepareForView.called.should.be.true;
      });

      //it("should create a new view", function () {
        //context(['view-interaction'], function (view) {
          //view.render.should.be.true;
          //view.reset();
        //});
      //});

      //it("should resolve the event deferred (transitioning the view onscreen)", function (done) {
        //dfrd.always(function () {
          //done();
        //});
      //});

      //it("should remove old views from the DOM");
    });

    describe('inheritanceChain(urlString)', function () {
      var router;

      beforeEach(function (done) {
        injector.require(['../scripts/router'], function (module) {
          router = module;
          done();
        });
      });

      afterEach(function () {});

      it("should parse the path given to find the current interaction", function () {
        var data = "/councils/traffic";
        router.inheritanceChain(data).id.should.equal('traffic');
      });

      //it("should detect interactions specified by ID (instead of name)");

      it("should use the path to determine the inheritance chain", function () {
        var data = "/councils/traffic";
        var model = router.inheritanceChain(data);
        model.set.called.should.be.true;
        model.set.calledWith({parent: 'councils'}).should.be.true;
      });

      //it("should set the parent of each interaction in the chain on the associated model", function () {
        //var interaction = router.inheritanceChain("/test/second");
        //interaction.get('parent').should.be.string(interactionSetSpy.secondCall.args[0].parent);
      //});

      //it("should set the topmost interaction in the chain to have a parent of the answerspace", function () {
        //router.inheritanceChain("/test").get('parent').should.be.string("app");
      //});

      //it("should return the correct interaction to attach the view to", function () {
        //router.inheritanceChain("/test").should.be.instanceOf(Backbone.Model);
      //});

      it("should handle the same interaction being listed twice (last winning out)", function () {
        var data = "/councils/traffic/trafficcams/traffic";
        router.inheritanceChain(data).id.should.equal('traffic');
      });

      it("should drop blank trailing values from the array", function () {
        var data = "/councils/traffic/";
        router.inheritanceChain(data).id.should.equal('traffic');
      });
    });

    //describe('parseArgs(argsString, model)', function () {
      //it("should identify any GET arguments in the input string");
      //it("should parse found arguments into an object");
      //it("should set the object on the model as 'args'");
    //});
  });
});
<|endoftext|>


<commit_before>const assert = require('assert');
readFolder(process.cwd(), 0);
var Database
console.log(process.cwd())
try {
    Database = require('../src/database.js');
} catch(e) {
    //not sure why git isn't picking up the difference here
    Database = require('../src/dataBase.js');
}

const testOne = {
    _id: "0",
    justText: "things"
};

const testTwo = {
    _id: "1",
    more: "than",
    just: "text",
    n: 8
};

const testThree = {
    _id: "2",
    with: "a",
    click() { return 'things!' }
};

const unixEpoch = new Date(1970,0,1,0,0,0,0);
const birthday = new Date(1983,0,31,4,30,0,0);
const ani = new Date(2014, 0,18,11,30,0,0);
const dateArray = [
    unixEpoch,
    birthday,
    ani
]

const testFour = {
    _id: "4",
    sub: {
        i: 'am',
        a: [
            'nested',
            'object'
        ],
        with: function() {
            return 'stuff'
        },
        and: dateArray
    }
}

const testFive = {
    _id: "5",
    sub: {
        sub: {
            sub: {
                data: [
                    'one',
                    'two',
                    'three'
                ]
            }
        }
    }
}

tests = {};
tests[testOne._id] = testOne;
tests[testTwo._id] = testTwo;
tests[testThree._id] = testThree;
tests[testFour._id] = testFour;
tests[testFive._id] = testFive;

describe('Database', function() {
    it('init', function() {
        var db = new Database('testing', ['none']);
    })
    describe('Collection', function() {
        describe('insert', function() {
            it('singleElement', function(done) {
                var db = new Database('testing', ['single']);
                db.single.insert(testOne, (err, doc) => {
                    if (err) return done(err);
                    done();
                })
            })
            it('array', function(done) {
                var db = new Database('testing', ['array']);
                var testsArray = [testOne, testTwo, testThree, testFour, testFive];
                db.array.insert(testsArray, (err, docs) => {
                    if (err) return done(err);
                    done();
                })
            })
        })
        describe('find', function() {
            it('all', function(done) {
                var db = new Database('testing', ['array']);
                db.array.find({}, (err, docs) => {
                    if(err) return done(err)
                    docs.forEach((doc) => {
                        var test = tests[doc._id];
                        assert(equals(doc, test));
                    });
                    assert(docs.length == 5, `array db does not have 5 elements: ${docs.length}`);
                    done();
                })
            })
        })
        describe('findOne', function() {
            it('and only one', function(done) {
                var db = new Database('testing', ['array']);
                db.array.findOne({}, (err, doc) => {
                    if (err) return done(err);
                    assert(doc != undefined, 'doc was undefined');
                    assert(!Array.isArray(doc), 'Doc was not an array')
                    done();
                })
            })
        })
        describe('update', function() {
            it('new values', function(done) {
                var db = new Database('testing', ['array']);
                db.array.update({_id: '2'}, {click: 'stuff'}, (err, doc) => {
                    if (err) return done(err);
                    db.array.find({_id: '2'}, (err, found) => {
                        if (err) return doc(err);
                        assert(doc['click'] == found['click'], 'Updated var does not match');
                        done();
                    })
                })
            })
        })
        describe('delete', function() {
            it('removes single value', function(done) {
                var db = new Database('testing', ['single']);
                db.single.delete({_id: '0'}, (err, num) => {
                    if (err) return done(err);
                    assert(num == 1, `elements deleted is not 1: ${num}`);
                    done();
                })
            })
            it('removes more than one', function(done) {
                var db = new Database('testing', ['array']);
                db.array.delete({}, (err, num) => {
                    if (err) return done(err);
                    assert(num == 5, `elements deleted is not 5: ${num}`);
                    done();
                })
            })
        })
    })
})

after(cleanUp);

before(cleanUp);

function cleanUp(done) {
    var fs = require('fs');

    var dataPath = __dirname + '/../assets/data/';
    fs.readdir(dataPath, (err, files) => {
        if (err) return done(err);
        files.forEach(file => {
            if (file.includes('testing')) {
                try {
                    fs.unlinkSync(dataPath + file);
                } catch (e) {}
            }
        })
        done();
    })
}

function readFolder(path, n) {
    var tabs = '';
    if (!n || n === 0) tabs = '';
    else tabs = '  '.repeat(n);
    var fs = require('fs')
    var files = fs.readdirSync(path)
    for (var i = 0; i < files.length; i++) {
        var file = `${path}/${files[i]}`;
        var stat = fs.statSync(file);
        if (stat.isDirectory()) {
            console.log(tabs + file);
            if (files[i] == 'node_modules') continue;
            if (files[i] == '.git') continue
            readFolder(file, ++n)
        } else {
            console.log(tabs + file);
        }
    }
}

function equals(lhs, rhs) {
    if (Array.isArray(lhs)) {
        if (!Array.isArray(rhs)) return false;
        if (lhs.length != rhs.length) return false;
        for (var i = 0; i < lhs.length; i++) {
            if (!equals(lhs[i], rhs[i])) return false
        }
        return true
    } else if (typeof lhs == 'function') {
        return this.length == func.length &&
            this() == this();
    } else if (lhs instanceof Date) {
        if (!(rhs instanceof Date)) return false
        return lhs == rhs;
    } else if (typeof lhs == 'object') {
        if (typeof rhs != 'object')
        for (var k in lhs) {
            if (!rhs[k]) return false;
            if (!equals(lhs[k] != rhs[k])) return false
        }
        return true
    } else {
        return lhs == rhs;
    }
}<commit_msg>remove travis logging<commit_after>const assert = require('assert');
var Database
Database = require('../src/database.js');

const testOne = {
    _id: "0",
    justText: "things"
};

const testTwo = {
    _id: "1",
    more: "than",
    just: "text",
    n: 8
};

const testThree = {
    _id: "2",
    with: "a",
    click() { return 'things!' }
};

const unixEpoch = new Date(1970,0,1,0,0,0,0);
const birthday = new Date(1983,0,31,4,30,0,0);
const ani = new Date(2014, 0,18,11,30,0,0);
const dateArray = [
    unixEpoch,
    birthday,
    ani
]

const testFour = {
    _id: "4",
    sub: {
        i: 'am',
        a: [
            'nested',
            'object'
        ],
        with: function() {
            return 'stuff'
        },
        and: dateArray
    }
}

const testFive = {
    _id: "5",
    sub: {
        sub: {
            sub: {
                data: [
                    'one',
                    'two',
                    'three'
                ]
            }
        }
    }
}

tests = {};
tests[testOne._id] = testOne;
tests[testTwo._id] = testTwo;
tests[testThree._id] = testThree;
tests[testFour._id] = testFour;
tests[testFive._id] = testFive;

describe('Database', function() {
    it('init', function() {
        var db = new Database('testing', ['none']);
    })
    describe('Collection', function() {
        describe('insert', function() {
            it('singleElement', function(done) {
                var db = new Database('testing', ['single']);
                db.single.insert(testOne, (err, doc) => {
                    if (err) return done(err);
                    done();
                })
            })
            it('array', function(done) {
                var db = new Database('testing', ['array']);
                var testsArray = [testOne, testTwo, testThree, testFour, testFive];
                db.array.insert(testsArray, (err, docs) => {
                    if (err) return done(err);
                    done();
                })
            })
        })
        describe('find', function() {
            it('all', function(done) {
                var db = new Database('testing', ['array']);
                db.array.find({}, (err, docs) => {
                    if(err) return done(err)
                    docs.forEach((doc) => {
                        var test = tests[doc._id];
                        assert(equals(doc, test));
                    });
                    assert(docs.length == 5, `array db does not have 5 elements: ${docs.length}`);
                    done();
                })
            })
        })
        describe('findOne', function() {
            it('and only one', function(done) {
                var db = new Database('testing', ['array']);
                db.array.findOne({}, (err, doc) => {
                    if (err) return done(err);
                    assert(doc != undefined, 'doc was undefined');
                    assert(!Array.isArray(doc), 'Doc was not an array')
                    done();
                })
            })
        })
        describe('update', function() {
            it('new values', function(done) {
                var db = new Database('testing', ['array']);
                db.array.update({_id: '2'}, {click: 'stuff'}, (err, doc) => {
                    if (err) return done(err);
                    db.array.find({_id: '2'}, (err, found) => {
                        if (err) return doc(err);
                        assert(doc['click'] == found['click'], 'Updated var does not match');
                        done();
                    })
                })
            })
        })
        describe('delete', function() {
            it('removes single value', function(done) {
                var db = new Database('testing', ['single']);
                db.single.delete({_id: '0'}, (err, num) => {
                    if (err) return done(err);
                    assert(num == 1, `elements deleted is not 1: ${num}`);
                    done();
                })
            })
            it('removes more than one', function(done) {
                var db = new Database('testing', ['array']);
                db.array.delete({}, (err, num) => {
                    if (err) return done(err);
                    assert(num == 5, `elements deleted is not 5: ${num}`);
                    done();
                })
            })
        })
    })
})

after(cleanUp);

before(cleanUp);

function cleanUp(done) {
    var fs = require('fs');

    var dataPath = __dirname + '/../assets/data/';
    fs.readdir(dataPath, (err, files) => {
        if (err) return done(err);
        files.forEach(file => {
            if (file.includes('testing')) {
                try {
                    fs.unlinkSync(dataPath + file);
                } catch (e) {}
            }
        })
        done();
    })
}

function readFolder(path, n) {
    var tabs = '';
    if (!n || n === 0) tabs = '';
    else tabs = '  '.repeat(n);
    var fs = require('fs')
    var files = fs.readdirSync(path)
    for (var i = 0; i < files.length; i++) {
        var file = `${path}/${files[i]}`;
        var stat = fs.statSync(file);
        if (stat.isDirectory()) {
            console.log(tabs + file);
            if (files[i] == 'node_modules') continue;
            if (files[i] == '.git') continue
            readFolder(file, ++n)
        } else {
            console.log(tabs + file);
        }
    }
}

function equals(lhs, rhs) {
    if (Array.isArray(lhs)) {
        if (!Array.isArray(rhs)) return false;
        if (lhs.length != rhs.length) return false;
        for (var i = 0; i < lhs.length; i++) {
            if (!equals(lhs[i], rhs[i])) return false
        }
        return true
    } else if (typeof lhs == 'function') {
        return this.length == func.length &&
            this() == this();
    } else if (lhs instanceof Date) {
        if (!(rhs instanceof Date)) return false
        return lhs == rhs;
    } else if (typeof lhs == 'object') {
        if (typeof rhs != 'object')
        for (var k in lhs) {
            if (!rhs[k]) return false;
            if (!equals(lhs[k] != rhs[k])) return false
        }
        return true
    } else {
        return lhs == rhs;
    }
}<|endoftext|>


<commit_before>module.exports = function (grunt) {
    var
        project_folder = grunt.option('project') ? grunt.option('project') + '/' : './',
        path = require('path'),
        pkg = grunt.file.readJSON(path.join(project_folder, 'package.json')),
        bower_pkg = grunt.file.readJSON(path.join(project_folder, 'bower.json'));
    bower_dependencies = grunt.file.readJSON(path.join(project_folder, 'bower.json')).dependencies,
    bower_comp = Object.keys(bower_dependencies),
    theme_bower_pkg = '',
    theme_bower_root = '../../../bower_components/',
    theme_bower_scss = '',
    theme_bower_favicon = '';

    // Load all grunt tasks.
    require('load-grunt-tasks')(grunt, { config: path.join(project_folder, 'package.json') });

    // Show elapsed time at the end.
    require('time-grunt')(grunt);

    // Application configuration.
    grunt.initConfig({
        pkg: pkg,

        banner: '/*!\n' +
            ' * <%= pkg.name %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
            ' * <%= pkg.homepage %>\n' +
            ' * @license <%= pkg.license %>\n' +
            ' * v<%= pkg.version %>\n */\n',

        'string-replace': {
            'material-design-iconic-font': {
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss/',
                    src: '**/*',
                    dest: 'bower_components/material-design-iconic-font/scss/'
                }],
                options: {
                    replacements: [{
                        pattern: '$md-css-prefix: md;',
                        replacement: '$md-css-prefix: mdi;'
                    }]
                }
            },
            'default-tags': {
                files: [{
                    expand: true,
                    cwd: 'app/',
                    src: [
                        '**/*',
                        '!assets/scss/app.scss',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'app/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: /fkjs_\(name\)/ig,
                            replacement: '<%= pkg.name %>'
                        },
                        {
                            pattern: /fkjs_\(title\)/ig,
                            replacement: '<%= pkg.title %>'
                        },
                        {
                            pattern: /fkjs_\(description\)/ig,
                            replacement: '<%= pkg.description %>'
                        },
                        {
                            pattern: /fkjs_\(version\)/ig,
                            replacement: '<%= pkg.version %>'
                        },
                        {
                            pattern: /fkjs_\(theme\)/ig,
                            replacement: bower_pkg.fkjs_theme
                        },
                        {
                            pattern: /fkjs_\(theme_root\)/ig,
                            replacement: function () { return theme_bower_root }
                        },
                        {
                            pattern: /fkjs_\(theme_main\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/' + theme_bower_scss }
                        },
                        {
                            pattern: /fkjs_\(theme_fonts\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/app/assets/fonts/' }
                        },
                        {
                            pattern: /fkjs_\(theme_images\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/app/assets/images/' }
                        },
                        {
                            pattern: /fkjs_\(favicon\)/ig,
                            replacement: function () { return theme_bower_favicon }
                        }
                    ]
                }
            },
            'dist-tags': {
                files: [{
                    expand: true,
                    cwd: 'dist/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'dist/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: /fkjs_\(name\)/ig,
                            replacement: '<%= pkg.name %>'
                        },
                        {
                            pattern: /fkjs_\(title\)/ig,
                            replacement: '<%= pkg.title %>'
                        },
                        {
                            pattern: /fkjs_\(description\)/ig,
                            replacement: '<%= pkg.description %>'
                        },
                        {
                            pattern: /fkjs_\(version\)/ig,
                            replacement: '<%= pkg.version %>'
                        },
                        {
                            pattern: /fkjs_\(theme\)/ig,
                            replacement: bower_pkg.fkjs_theme
                        },
                        {
                            pattern: /fkjs_\(theme_root\)/ig,
                            replacement: function () { return theme_bower_root }
                        },
                        {
                            pattern: /fkjs_\(theme_main\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/' + theme_bower_scss }
                        },
                        {
                            pattern: /fkjs_\(theme_fonts\)/ig,
                            replacement: '../fonts/'
                        },
                        {
                            pattern: /fkjs_\(theme_images\)/ig,
                            replacement: '../images/'
                        },
                        {
                            pattern: /fkjs_\(favicon\)/ig,
                            replacement: function () { return theme_bower_favicon }
                        }
                    ]
                }
            }
        },
        copy: {
            'bootstrap-fonts': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/bootstrap/fonts',
                dest: 'app/assets/fonts'
            },
            'material-design-iconic-font': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/material-design-iconic-font/fonts',
                dest: 'app/assets/fonts'
            },
            dist: {
                src: [
                    '**/*',
                    '!**/test/**',
                    '!**/docs/**',
                    '!**/assets/css/**',
                    '!**/src/**/*.js'
                ],
                expand: true,
                cwd: 'app',
                dest: 'dist'
            }
        },
        wiredep: {
            build: {
                src: [
                    'app/index.html'
                ],
                options: {

                }
            }
        },
        sass: {
            'material-design-iconic-font': {
                options: {
                    style: 'expanded',
                    noCache: true
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss',
                    src: ['**/*.scss'],
                    dest: 'bower_components/material-design-iconic-font/css',
                    ext: '.css'
                }]
            },
            'compile-scss': {
                options: {
                    style: 'expanded',
                    lineNumbers: true,
                    cacheLocation: 'app/assets/scss/.sass-cache'
                },
                files: [{
                    expand: true,
                    cwd: 'app/assets/scss/',
                    src: [
                        '**/*.scss',
                        '!app.scss'
                    ],
                    dest: 'app/assets/scss/.temp',
                    ext: '.css'
                }]
            }
        },
        bower_concat: {
            all: {
                dest: 'dist/_bower.js',
                cssDest: 'dist/_bower.css',
                exclude: [

                ],
                mainFiles: {
                    'bootstrap': 'dist/css/bootstrap.css'
                },
                dependencies: {
                    'angular': ['jquery']
                },
                bowerOptions: {
                    relative: false
                },
                callback: function (main_files, component) {
                    var component_dependencies,
                        dependencies = [];

                    if (grunt.file.exists(path.join('bower_components/', component, 'bower.json'))) {
                        component_dependencies = grunt.file.readJSON(path.join('bower_components/', component, 'bower.json')).dependencies;
                        dependencies = component_dependencies ? Object.keys(component_dependencies) : [];
                    }

                    return main_files.map(function (filepath) {
                        return ((bower_comp.indexOf(component) > -1 || dependencies.length > -1) && component != 'script.js') ? filepath : false;
                    });
                }
            }
        },
        ngAnnotate: {
            dist: {
                files: {
                    'dist/app.js.files.js': [
                        'app/src/**/*.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                //separator: ';'
            },
            'compile-css-first': {
                src: [
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'app/assets/css/app.css',
            },
            'compile-css-last': {
                src: [
                    'app/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'app/assets/css/app.css'
            },
            'dist-libraries': {
                src: [
                    'dist/_bower.js'
                ],
                dest: 'dist/app.libraries.js'
            },
            'dist-js-files': {
                src: [
                    'dist/app.libraries.js',
                    'dist/app.js.files.js'
                ],
                dest: 'dist/app.js'
            },
            'dist-stylesheets': {
                src: [
                    'dist/_bower.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-first': {
                src: [
                    'dist/_bower.css',
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-last': {
                src: [
                    'dist/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            }
        },
        uglify: {
            options: {
                compress: {
                    global_defs: {
                        "DEBUG": false
                    },
                    dead_code: true
                },
                banner: '<%= banner %>'
            },
            libraries: {
                src: 'dist/app.js',
                dest: 'dist/app.min.js'
            }
        },
        cssmin: {
            css: {
                src: 'dist/assets/css/app.css',
                dest: 'dist/assets/css/app.min.css'
            }
        },
        processhtml: {
            options: {
                data: {
                    html_tag: '<html ng-app="<%= pkg.name %>">'
                }
            },
            dist: {
                files: {
                    'dist/index.html': ['dist/index.html']
                }
            }
        },
        clean: {
            'default-after': [
                'app/assets/scss/app-temp-default.scss'
            ],
            'compile-scss-after': [
                'app/assets/scss/app-temp-default.scss'
            ],
            'dist-before': [
                'dist/'
            ],
            'dist-after': [
                'app/assets/scss/.temp',
                'app/assets/scss/app-temp-dist.scss',
                'dist/app.js',
                'dist/app.libraries.js',
                'dist/app.js.files.js',
                'dist/assets/css/app.css',
                'dist/assets/scss',
                'dist/_bower.js',
                'dist/_bower.css',
                'dist/src/services'
            ],
            'docs': [
                'dist/docs'
            ]
        },
        watch: {
            debug: {
                files: [
                    'app/**/*',
					'!app/assets/scss/.sass-cache',
					'!app/assets/scss/.temp'
                ],
                tasks: ['compile-scss'],
                options: {
                    // Start a live reload server on the default port 35729
                    livereload: true,
                    spawn: false
                }
            }
        },
        ngdocs: {
            options: {
                dest: 'app/docs',
                startPage: '/api/app',
                html5Mode: false,
                title: '<%= pkg.title %> Docs',
                titleLink: '#/api/app',
                bestMatch: true,
                sourceLink: '../../{{file}}'
            },
            api: {
                src: [
                    'app/src/**/*.js',
                    'app/app.js',
                    'app/docs/content/api/*.ngdoc'
                ]
            }
        },
        karma: {
            unit: {
                configFile: 'app/test/karma.conf.js'
            }
        }
    });

    /**
	 * @description
	 *   Now that we have loaded the package.json and the node_modules we set the base path
     *   for the actual execution of the tasks.
	 *
	 */
    grunt.file.setBase(project_folder);

    grunt.event.on('watch', function (action, filepath, target) {
        grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
    });

    /**
	 * @description
	 *   Running theme init task(s).
	 *
	 */
    grunt.registerTask('theme-init', '', function () {
        if (bower_pkg.fkjs_theme != '') {
            theme_bower_pkg = grunt.file.readJSON(path.join('bower_components/', bower_pkg.fkjs_theme, '/bower.json'));

            if (theme_bower_pkg.main.length > 0) {
                theme_bower_pkg.main.forEach(function (entry) {
                    var result = entry.match(/\.[0-9a-z]+$/i);

                    if (result) {
                        switch (result[0]) {
                            case '.ico':
                                if (entry.match(/favicon.ico/i))
                                    theme_bower_favicon = entry;
                                break;
                            case '.scss':
                                if (entry.match(/_app.scss/i))
                                    theme_bower_scss = entry;
                                break;
                        }
                    }
                    else {
                        //console.log(entry);
                    }
                });
            }
        }
    });

    /**
	 * @description
	 *   Running theme copy task(s).
	 *
	 */
    grunt.registerTask('theme-copy', '', function () {
        if (bower_pkg.fkjs_theme != '') {
            var srcPath = 'bower_components/' + bower_pkg.fkjs_theme + '/app/assets/',
				destPath = 'app/assets',
				options = {
				    cwd: srcPath,
				    filter: 'isFile',
				    dot: true
				},
				glob = '**/*';

            grunt.file.expand(options, glob).forEach(function (file) {
                grunt.file.copy(path.join(srcPath, file), path.join(destPath, file));
            });
        }
    });

    /**
	 * @description
	 *   Running before default tags task(s).
	 *
	 */
    grunt.registerTask('before-default-tags', '', function () {
        var srcPath = 'app/assets/scss/',
			destPath = 'app/assets/scss/';

        grunt.file.copy(path.join(srcPath, 'app.scss'), path.join(destPath, 'app-temp-default.scss'));
    });

    /**
	 * @description
	 *   Running before dist task(s).
	 *
	 */
    grunt.registerTask('after-dist-tags', '', function () {
        var srcPath = 'dist/assets/scss/',
			destPath = 'app/assets/scss/';

        grunt.file.copy(path.join(srcPath, 'app.scss'), path.join(destPath, 'app-temp-dist.scss'));
    });

    /**
	 * @description
	 *   Running test task(s).
	 *
	 */
    grunt.registerTask('test', [
		'karma'
    ]);

    /**
	 * @description
	 *   Generate documentation (ngDocs) task(s).
	 *
	 */
    grunt.registerTask('docs', [
		'clean:docs',
        'ngdocs'
    ]);

    /**
	 * @description
	 *   Compile SCSS task(s).
	 *
	 */
    grunt.registerTask('compile-scss', [
        'theme-init',
        'before-default-tags',
        'string-replace:default-tags',
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last',
        'clean:compile-scss-after'
    ]);

    /**
	 * @description
	 *   Dist task(s).
	 *
	 */
    grunt.registerTask('dist', [
        'clean:dist-before',
		'theme-init',
        'copy:dist',
        'string-replace:dist-tags',
		'after-dist-tags',
        'processhtml',
        'bower_concat',
        'sass:compile-scss',
        'concat:dist-stylesheets',
        'concat:dist-css-first',
        'concat:dist-css-last',
        'cssmin',
        'ngAnnotate:dist',
        'concat:dist-libraries',
        'concat:dist-js-files',
        'uglify',
        'clean:dist-after'
    ]);

    /**
	 * @description
	 *   Default task(s).
	 *
	 */
    grunt.registerTask('default', [
        'theme-init',
        'theme-copy',
        'copy:material-design-iconic-font',
        'string-replace:material-design-iconic-font',
        'sass:material-design-iconic-font',
        'before-default-tags',
        'string-replace:default-tags',
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last',
        'wiredep:build',
        'clean:default-after'
    ]);
};<commit_msg>Fix: missing fonts<commit_after>module.exports = function (grunt) {
    var project_folder = grunt.option('project') ? grunt.option('project') + '/' : './',
        path = require('path'),
        pkg = grunt.file.readJSON(path.join(project_folder, 'package.json')),
        bower_pkg = grunt.file.readJSON(path.join(project_folder, 'bower.json'));
        bower_dependencies = grunt.file.readJSON(path.join(project_folder, 'bower.json')).dependencies,
        bower_comp = Object.keys(bower_dependencies),
        theme_bower_pkg = '',
        theme_bower_root = '../../../bower_components/',
        theme_bower_scss = '',
        theme_bower_favicon = '';

    // Load all grunt tasks.
    require('load-grunt-tasks')(grunt, { config: path.join(project_folder, 'package.json') });

    // Show elapsed time at the end.
    require('time-grunt')(grunt);

    // Application configuration.
    grunt.initConfig({
        pkg: pkg,

        banner: '/*!\n' +
            ' * <%= pkg.name %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
            ' * <%= pkg.homepage %>\n' +
            ' * @license <%= pkg.license %>\n' +
            ' * v<%= pkg.version %>\n */\n',

        'string-replace': {
            'material-design-iconic-font': {
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss/',
                    src: '**/*',
                    dest: 'bower_components/material-design-iconic-font/scss/'
                }],
                options: {
                    replacements: [{
                        pattern: '$md-css-prefix: md;',
                        replacement: '$md-css-prefix: mdi;'
                    }]
                }
            },
            'default-tags': {
                files: [{
                    expand: true,
                    cwd: 'app/',
                    src: [
                        '**/*',
                        '!assets/scss/app.scss',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'app/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: /fkjs_\(name\)/ig,
                            replacement: '<%= pkg.name %>'
                        },
                        {
                            pattern: /fkjs_\(title\)/ig,
                            replacement: '<%= pkg.title %>'
                        },
                        {
                            pattern: /fkjs_\(description\)/ig,
                            replacement: '<%= pkg.description %>'
                        },
                        {
                            pattern: /fkjs_\(version\)/ig,
                            replacement: '<%= pkg.version %>'
                        },
                        {
                            pattern: /fkjs_\(theme\)/ig,
                            replacement: bower_pkg.fkjs_theme
                        },
                        {
                            pattern: /fkjs_\(theme_root\)/ig,
                            replacement: function () { return theme_bower_root }
                        },
                        {
                            pattern: /fkjs_\(theme_main\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/' + theme_bower_scss }
                        },
                        {
                            pattern: /fkjs_\(theme_fonts\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/app/assets/fonts/' }
                        },
                        {
                            pattern: /fkjs_\(theme_images\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/app/assets/images/' }
                        },
                        {
                            pattern: /fkjs_\(favicon\)/ig,
                            replacement: function () { return theme_bower_favicon }
                        }
                    ]
                }
            },
            'dist-tags': {
                files: [{
                    expand: true,
                    cwd: 'dist/',
                    src: [
                        '**/*',
                        '!**/assets/fonts/**',
                        '!**/assets/images/**'
                    ],
                    dest: 'dist/'
                }],
                options: {
                    replacements: [
                        {
                            pattern: /fkjs_\(name\)/ig,
                            replacement: '<%= pkg.name %>'
                        },
                        {
                            pattern: /fkjs_\(title\)/ig,
                            replacement: '<%= pkg.title %>'
                        },
                        {
                            pattern: /fkjs_\(description\)/ig,
                            replacement: '<%= pkg.description %>'
                        },
                        {
                            pattern: /fkjs_\(version\)/ig,
                            replacement: '<%= pkg.version %>'
                        },
                        {
                            pattern: /fkjs_\(theme\)/ig,
                            replacement: bower_pkg.fkjs_theme
                        },
                        {
                            pattern: /fkjs_\(theme_root\)/ig,
                            replacement: function () { return theme_bower_root }
                        },
                        {
                            pattern: /fkjs_\(theme_main\)/ig,
                            replacement: function () { return theme_bower_root + bower_pkg.fkjs_theme + '/' + theme_bower_scss }
                        },
                        {
                            pattern: /fkjs_\(theme_fonts\)/ig,
                            replacement: '../fonts/'
                        },
                        {
                            pattern: /fkjs_\(theme_images\)/ig,
                            replacement: '../images/'
                        },
                        {
                            pattern: /fkjs_\(favicon\)/ig,
                            replacement: function () { return theme_bower_favicon }
                        }
                    ]
                }
            }
        },
        copy: {
            'bootstrap-fonts': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/bootstrap/fonts',
                dest: 'app/assets/fonts'
            },
            'material-design-iconic-font': {
                src: [
                    '**/*'
                ],
                expand: true,
                cwd: 'bower_components/material-design-iconic-font/fonts',
                dest: 'app/assets/fonts'
            },
            dist: {
                src: [
                    '**/*',
                    '!**/test/**',
                    '!**/docs/**',
                    '!**/assets/css/**',
                    '!**/src/**/*.js'
                ],
                expand: true,
                cwd: 'app',
                dest: 'dist'
            }
        },
        wiredep: {
            build: {
                src: [
                    'app/index.html'
                ],
                options: {

                }
            }
        },
        sass: {
            'material-design-iconic-font': {
                options: {
                    style: 'expanded',
                    noCache: true
                },
                files: [{
                    expand: true,
                    cwd: 'bower_components/material-design-iconic-font/scss',
                    src: ['**/*.scss'],
                    dest: 'bower_components/material-design-iconic-font/css',
                    ext: '.css'
                }]
            },
            'compile-scss': {
                options: {
                    style: 'expanded',
                    lineNumbers: true,
                    cacheLocation: 'app/assets/scss/.sass-cache'
                },
                files: [{
                    expand: true,
                    cwd: 'app/assets/scss/',
                    src: [
                        '**/*.scss',
                        '!app.scss'
                    ],
                    dest: 'app/assets/scss/.temp',
                    ext: '.css'
                }]
            }
        },
        bower_concat: {
            all: {
                dest: 'dist/_bower.js',
                cssDest: 'dist/_bower.css',
                exclude: [

                ],
                mainFiles: {
                    'bootstrap': 'dist/css/bootstrap.css'
                },
                dependencies: {
                    'angular': ['jquery']
                },
                bowerOptions: {
                    relative: false
                },
                callback: function (main_files, component) {
                    var component_dependencies,
                        dependencies = [];

                    if (grunt.file.exists(path.join('bower_components/', component, 'bower.json'))) {
                        component_dependencies = grunt.file.readJSON(path.join('bower_components/', component, 'bower.json')).dependencies;
                        dependencies = component_dependencies ? Object.keys(component_dependencies) : [];
                    }

                    return main_files.map(function (filepath) {
                        return ((bower_comp.indexOf(component) > -1 || dependencies.length > -1) && component != 'script.js') ? filepath : false;
                    });
                }
            }
        },
        ngAnnotate: {
            dist: {
                files: {
                    'dist/app.js.files.js': [
                        'app/src/**/*.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                //separator: ';'
            },
            'compile-css-first': {
                src: [
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'app/assets/css/app.css',
            },
            'compile-css-last': {
                src: [
                    'app/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'app/assets/css/app.css'
            },
            'dist-libraries': {
                src: [
                    'dist/_bower.js'
                ],
                dest: 'dist/app.libraries.js'
            },
            'dist-js-files': {
                src: [
                    'dist/app.libraries.js',
                    'dist/app.js.files.js'
                ],
                dest: 'dist/app.js'
            },
            'dist-stylesheets': {
                src: [
                    'dist/_bower.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-first': {
                src: [
                    'dist/_bower.css',
                    'app/assets/scss/.temp/*.css',
                    'app/assets/css/**/*.css',
                    '!**/app/assets/css/app.css',
                    '!**/app/assets/css/**/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            },
            'dist-css-last': {
                src: [
                    'dist/assets/css/app.css',
                    'app/assets/css/custom.css'
                ],
                dest: 'dist/assets/css/app.css',
            }
        },
        uglify: {
            options: {
                compress: {
                    global_defs: {
                        "DEBUG": false
                    },
                    dead_code: true
                },
                banner: '<%= banner %>'
            },
            libraries: {
                src: 'dist/app.js',
                dest: 'dist/app.min.js'
            }
        },
        cssmin: {
            css: {
                src: 'dist/assets/css/app.css',
                dest: 'dist/assets/css/app.min.css'
            }
        },
        processhtml: {
            options: {
                data: {
                    html_tag: '<html ng-app="<%= pkg.name %>">'
                }
            },
            dist: {
                files: {
                    'dist/index.html': ['dist/index.html']
                }
            }
        },
        clean: {
            'default-after': [
                'app/assets/scss/app-temp-default.scss'
            ],
            'compile-scss-after': [
                'app/assets/scss/app-temp-default.scss'
            ],
            'dist-before': [
                'dist/'
            ],
            'dist-after': [
                'app/assets/scss/.temp',
                'app/assets/scss/app-temp-dist.scss',
                'dist/app.js',
                'dist/app.libraries.js',
                'dist/app.js.files.js',
                'dist/assets/css/app.css',
                'dist/assets/scss',
                'dist/_bower.js',
                'dist/_bower.css',
                'dist/src/services'
            ],
            'docs': [
                'dist/docs'
            ]
        },
        watch: {
            debug: {
                files: [
                    'app/**/*',
					'!app/assets/scss/.sass-cache',
					'!app/assets/scss/.temp'
                ],
                tasks: ['compile-scss'],
                options: {
                    // Start a live reload server on the default port 35729
                    livereload: true,
                    spawn: false
                }
            }
        },
        ngdocs: {
            options: {
                dest: 'app/docs',
                startPage: '/api/app',
                html5Mode: false,
                title: '<%= pkg.title %> Docs',
                titleLink: '#/api/app',
                bestMatch: true,
                sourceLink: '../../{{file}}'
            },
            api: {
                src: [
                    'app/src/**/*.js',
                    'app/app.js',
                    'app/docs/content/api/*.ngdoc'
                ]
            }
        },
        karma: {
            unit: {
                configFile: 'app/test/karma.conf.js'
            }
        }
    });

    /**
	 * @description
	 *   Now that we have loaded the package.json and the node_modules we set the base path
     *   for the actual execution of the tasks.
	 *
	 */
    grunt.file.setBase(project_folder);

    grunt.event.on('watch', function (action, filepath, target) {
        grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
    });

    /**
	 * @description
	 *   Running theme init task(s).
	 *
	 */
    grunt.registerTask('theme-init', '', function () {
        if (bower_pkg.fkjs_theme != '') {
            theme_bower_pkg = grunt.file.readJSON(path.join('bower_components/', bower_pkg.fkjs_theme, '/bower.json'));

            if (theme_bower_pkg.main.length > 0) {
                theme_bower_pkg.main.forEach(function (entry) {
                    var result = entry.match(/\.[0-9a-z]+$/i);

                    if (result) {
                        switch (result[0]) {
                            case '.ico':
                                if (entry.match(/favicon.ico/i))
                                    theme_bower_favicon = entry;
                                break;
                            case '.scss':
                                if (entry.match(/_app.scss/i))
                                    theme_bower_scss = entry;
                                break;
                        }
                    }
                    else {
                        //console.log(entry);
                    }
                });
            }
        }
    });

    /**
	 * @description
	 *   Running theme copy task(s).
	 *
	 */
    grunt.registerTask('theme-copy', '', function () {
        if (bower_pkg.fkjs_theme != '') {
            var srcPath = 'bower_components/' + bower_pkg.fkjs_theme + '/app/assets/',
				destPath = 'app/assets',
				options = {
				    cwd: srcPath,
				    filter: 'isFile',
				    dot: true
				},
				glob = '**/*';

            grunt.file.expand(options, glob).forEach(function (file) {
                grunt.file.copy(path.join(srcPath, file), path.join(destPath, file));
            });
        }
    });

    /**
	 * @description
	 *   Running before default tags task(s).
	 *
	 */
    grunt.registerTask('before-default-tags', '', function () {
        var srcPath = 'app/assets/scss/',
			destPath = 'app/assets/scss/';

        grunt.file.copy(path.join(srcPath, 'app.scss'), path.join(destPath, 'app-temp-default.scss'));
    });

    /**
	 * @description
	 *   Running before dist task(s).
	 *
	 */
    grunt.registerTask('after-dist-tags', '', function () {
        var srcPath = 'dist/assets/scss/',
			destPath = 'app/assets/scss/';

        grunt.file.copy(path.join(srcPath, 'app.scss'), path.join(destPath, 'app-temp-dist.scss'));
    });

    /**
	 * @description
	 *   Running test task(s).
	 *
	 */
    grunt.registerTask('test', [
		'karma'
    ]);

    /**
	 * @description
	 *   Generate documentation (ngDocs) task(s).
	 *
	 */
    grunt.registerTask('docs', [
		'clean:docs',
        'ngdocs'
    ]);

    /**
	 * @description
	 *   Compile SCSS task(s).
	 *
	 */
    grunt.registerTask('compile-scss', [
        'theme-init',
        'before-default-tags',
        'string-replace:default-tags',
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last',
        'clean:compile-scss-after'
    ]);

    /**
	 * @description
	 *   Dist task(s).
	 *
	 */
    grunt.registerTask('dist', [
        'clean:dist-before',
		'theme-init',
        'copy:dist',
        'string-replace:dist-tags',
		'after-dist-tags',
        'processhtml',
        'bower_concat',
        'sass:compile-scss',
        'concat:dist-stylesheets',
        'concat:dist-css-first',
        'concat:dist-css-last',
        'cssmin',
        'ngAnnotate:dist',
        'concat:dist-libraries',
        'concat:dist-js-files',
        'uglify',
        'clean:dist-after'
    ]);

    /**
	 * @description
	 *   Default task(s).
	 *
	 */
    grunt.registerTask('default', [
        'theme-init',
        'theme-copy',
        'copy:material-design-iconic-font',
        'string-replace:material-design-iconic-font',
        'sass:material-design-iconic-font',
        'before-default-tags',
        'string-replace:default-tags',
        'sass:compile-scss',
        'concat:compile-css-first',
        'concat:compile-css-last',
        'wiredep:build',
        'clean:default-after'
    ]);
};<|endoftext|>


<commit_before>export default class FavoriteUsecase {

  /**
   * @param {TwitterClient} twitterClient
   */
  constructor(twitterClient) {
    this.twitterClient = twitterClient;
  }

  add(tweetId) {
    return this.twitterClient.favoritesCreate({tweetId});
  }

  remove(tweetId) {
    return this.twitterClient.favoritesDestroy({tweetId});
  }

  getList(myId) {
    return this.twitterClient.favoriteList({ userId: myId });
  }

}
<commit_msg>Implement FavoriteUsecase#getListOlderThan<commit_after>export default class FavoriteUsecase {

  /**
   * @param {TwitterClient} twitterClient
   */
  constructor(twitterClient) {
    this.twitterClient = twitterClient;
  }

  add(tweetId) {
    return this.twitterClient.favoritesCreate({tweetId});
  }

  remove(tweetId) {
    return this.twitterClient.favoritesDestroy({tweetId});
  }

  getList(myId) {
    return this.twitterClient.favoriteList({ userId: myId });
  }

  getListOlderThan(myId, maxTweetId) {
    return this.twitterClient
      .favoriteList({ userId: myId, maxTweetId: maxTweetId })
      .then(({ tweets }) => {
        const filteredOffsetTweet = tweets.filter(t => t.id_str !== maxTweetId);
        return { tweets: filteredOffsetTweet };
      });
  }

}
<|endoftext|>


<commit_before>angular.module("ehelseEditor")
    .config(function($stateProvider, $urlRouterProvider) {

        //redirect to "/" if nothing else matches
        $urlRouterProvider.otherwise("/");

        $stateProvider
            .state("login", {
                controller: "LoginController",
                url: "/",
                templateUrl: "app/components/login/loginView.html"
            }).state("main-view", {
                controller: "MainController",
                url: "/main-view",
                templateUrl: "app/components/main/mainView.html"
            })
            .state("main-view.editor-view", {
                controller: "EditorController",
                url: "/editor-view",
                templateUrl: "app/components/editor/editorView.html"
            })
            .state("main-view.min-side", {
                controller: "MyPageController",
                url: "/min-side",
                templateUrl: "app/components/myPage/myPageView.html"
            })
            .state("main-view.administrer-brukere", {
                controller: "AdministerUsersController",
                url: "/administrer-brukere",
                templateUrl: "app/components/administerUsers/administerUsersView.html"
            });
    });<commit_msg>Deleted unnecessary lines<commit_after>angular.module("ehelseEditor")
    .config(function($stateProvider, $urlRouterProvider) {

        //redirect to "/" if nothing else matches
        $urlRouterProvider.otherwise("/");

        $stateProvider
            .state("login", {
                controller: "LoginController",
                url: "/",
                templateUrl: "app/components/login/loginView.html"
            }).state("main-view", {
                controller: "MainController",
                url: "/main-view",
                templateUrl: "app/components/main/mainView.html"
            })
            .state("main-view.editor-view", {
                controller: "EditorController",
                url: "/editor-view",
                templateUrl: "app/components/editor/editorView.html"
            });
    });<|endoftext|>


<commit_before>var _ = require('lodash');
var chai = require('chai');
var async = require('async');
var sinon = require('sinon');
chai.use(require('sinon-chai'));
var mongoose = require('mongoose');
var httpMocks = require('node-mocks-http');
var expect = chai.expect;

var jsonapify = require('../');
var Resource = jsonapify.Resource;
var Response = jsonapify.Response;
var Transaction = jsonapify.Transaction;
var ResourceView = jsonapify.ResourceView;

mongoose.connect('mongodb://localhost/test');

describe('ResourceView', function() {
	var model, response;
	before(function() {
		model = mongoose.model('ResourceViewTest', new mongoose.Schema);
		var res = httpMocks.createResponse();
		response = new Response(res);
	});

	describe('#model', function() {
		it('gives resource model', function() {
			var resource = new Resource(model, { type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			expect(resview).to.have.property('model', resource.model);
		});
	});

	describe('#type', function() {
		it('gives resource type', function() {
			var resource = new Resource({ type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			expect(resview).to.have.property('type', resource.type);
		});
	});

	describe('#field', function() {
		it('gives specified field', function() {
			var resource = new Resource({ type: 'test', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives attribute field', function() {
			var resource = new Resource({
				type: 'test',
				attributes: {
					name: 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'attributes.name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives relationship field', function() {
			var resource = new Resource({
				type: 'test',
				relationships: {
					name: 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'relationships.name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives null if invalid field', function() {
			var resource = new Resource({ type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('invalid');
			expect(field).to.not.exist;
		});
	});

	describe('#select', function() {
		it('includes only specified fields in view', function() {
			var resource = new Resource({
				type: 'test',
				attributes: {
					selected: 'value',
					'not-selected': 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('selected');
			expect(resview.field('selected')).to.exist;
			expect(resview.field('not-selected')).to.not.exist;
		});

		it('always includes type field', function() {
			var resource = new Resource({ type: 'test', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('name');
			expect(resview.field('type')).to.exist;
		});

		it('always includes id field', function() {
			var resource = new Resource({ type: 'test', id: 'id', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('name');
			expect(resview.field('id')).to.exist;
		});
	});

	describe('#findOne', function() {
		var resource, transaction, object;
		beforeEach(function(done) {
			resource = new Resource(model, { type: 'test' });
			transaction = new Transaction(resource, response);
			model.create({}, function(err, result) {
				if (err) return done(err);
				object = result;
				done();
			});
		});

		afterEach(function(done) {
			mongoose.connection.db.dropDatabase(done);
		});

		it('retrieves mongoose document from the database', function(done) {
			var resview = resource.view(transaction);
			resview.findOne(transaction, { _id: object._id }, function(err, data) {
				if (err) return done(err);
				expect(data).to.have.property('id');
				expect(data._id).to.satisfy(function(id) {
					return id.equals(object._id);
				});
				done();
			});
		});

		it('runs transaction query handlers', function() {
			var handler = sinon.stub().returnsArg(1);
			transaction.subscribe(resource.type, 'query', handler);
			var resview = resource.view(transaction);
			var query = resview.findOne(transaction, { _id: object._id });
			expect(handler).to.have.been.calledWith(resource, query);
		});
	});

	describe('#findMany', function() {
		var resource, transaction, objects;
		beforeEach(function(done) {
			resource = new Resource(model, { type: 'test' });
			transaction = new Transaction(resource, response);
			async.parallel([
				function(next) { model.create({}, next); },
				function(next) { model.create({}, next); },
				function(next) { model.create({}, next); },
			], function(err, results) {
				if (err) return done(err);
				objects = results;
				done();
			});
		});

		afterEach(function(done) {
			mongoose.connection.db.dropDatabase(done);
		});

		it('retrieves mongoose documents from the database', function(done) {
			var resview = resource.view(transaction);
			resview.findMany(transaction, {}, function(err, results) {
				if (err) return done(err);
				expect(results).to.have.length(objects.length);
				_.each(results, function(result) {
					var obj = _.find(objects, function(obj) {
						return obj._id.equals(result._id);
					});
					expect(obj).to.exist;
				});
				done();
			});
		});

		it('runs transaction query handlers', function() {
			var handler = sinon.stub().returnsArg(1);
			transaction.subscribe(resource.type, 'query', handler);
			var resview = resource.view(transaction);
			var query = resview.findMany(transaction, {});
			expect(handler).to.have.been.calledWith(resource, query);
		});
	});

	describe('#serialize', function() {
		it('invokes serialize method on field', function(done) {
			var object = {};
			var accessor = createAccessor();
			accessor.serialize.callsArgWithAsync(3, null, 'value');
			var resource = new Resource({ type: 'test', field: accessor });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			resview.serialize(transaction, object, function(err, resdata) {
				if (err) return done(err);
				expect(accessor.serialize).to.have.been.called.once;
				done();
			});
		});
	});

	describe('#deserialize', function() {
		it('invokes deserialize method on field', function(done) {
			var object = {};
			var accessor = createAccessor();
			var resdata = { type: 'test', field: 'value' };
			accessor.deserialize.callsArgWithAsync(4, null, object);
			var resource = new Resource({ type: 'test', field: accessor });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			resview.deserialize(transaction, resdata, object, function(err, resdata) {
				if (err) return done(err);
				expect(accessor.deserialize).to.have.been.called.once;
				done();
			});
		});
	});
});

function createAccessor() {
	return {
		adjustQuery: sinon.stub(),
		serialize: sinon.stub(),
		deserialize: sinon.stub(),
	};
}
<commit_msg>Minor changes<commit_after>var _ = require('lodash');
var chai = require('chai');
var async = require('async');
var sinon = require('sinon');
chai.use(require('sinon-chai'));
var mongoose = require('mongoose');
var httpMocks = require('node-mocks-http');
var expect = chai.expect;

var jsonapify = require('../');
var Resource = jsonapify.Resource;
var Response = jsonapify.Response;
var Transaction = jsonapify.Transaction;
var ResourceView = jsonapify.ResourceView;

mongoose.connect('mongodb://localhost/test');

describe('ResourceView', function() {
	var model, response;
	before(function() {
		model = mongoose.model('ResourceViewTest', new mongoose.Schema);
		var res = httpMocks.createResponse();
		response = new Response(res);
	});

	describe('#model', function() {
		it('gives resource model', function() {
			var resource = new Resource(model, { type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			expect(resview).to.have.property('model', resource.model);
		});
	});

	describe('#type', function() {
		it('gives resource type', function() {
			var resource = new Resource({ type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			expect(resview).to.have.property('type', resource.type);
		});
	});

	describe('#field', function() {
		it('gives specified field', function() {
			var resource = new Resource({ type: 'test', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives attribute field', function() {
			var resource = new Resource({
				type: 'test',
				attributes: {
					name: 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'attributes.name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives relationship field', function() {
			var resource = new Resource({
				type: 'test',
				relationships: {
					name: 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('name');
			expect(field).to.have.property('name', 'relationships.name');
			expect(field).to.have.property('resource', resource);
		});

		it('gives null if invalid field', function() {
			var resource = new Resource({ type: 'test' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			var field = resview.field('invalid');
			expect(field).to.not.exist;
		});
	});

	describe('#select', function() {
		it('includes only specified fields in view', function() {
			var resource = new Resource({
				type: 'test',
				attributes: {
					selected: 'value',
					'not-selected': 'value',
				},
			});
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('selected');
			expect(resview.field('selected')).to.exist;
			expect(resview.field('not-selected')).to.not.exist;
		});

		it('always includes type field', function() {
			var resource = new Resource({ type: 'test', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('name');
			expect(resview.field('type')).to.exist;
		});

		it('always includes id field', function() {
			var resource = new Resource({ type: 'test', id: 'id', name: 'value' });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction).select('name');
			expect(resview.field('id')).to.exist;
		});
	});

	describe('#findOne', function() {
		var resource, transaction, object;
		before(function() {
			resource = new Resource(model, { type: 'test' });
			transaction = new Transaction(resource, response);
		});

		beforeEach(function(done) {
			model.create({}, function(err, result) {
				if (err) return done(err);
				object = result;
				done();
			});
		});

		afterEach(function(done) {
			mongoose.connection.db.dropDatabase(done);
		});

		it('retrieves mongoose document from the database', function(done) {
			var resview = resource.view(transaction);
			resview.findOne(transaction, { _id: object._id }, function(err, data) {
				if (err) return done(err);
				expect(data).to.have.property('id');
				expect(data._id).to.satisfy(function(id) {
					return id.equals(object._id);
				});
				done();
			});
		});

		it('runs transaction query handlers', function() {
			var handler = sinon.stub().returnsArg(1);
			transaction.subscribe(resource.type, 'query', handler);
			var resview = resource.view(transaction);
			var query = resview.findOne(transaction, { _id: object._id });
			expect(handler).to.have.been.calledWith(resource, query);
		});
	});

	describe('#findMany', function() {
		var resource, transaction, objects;
		before(function() {
			resource = new Resource(model, { type: 'test' });
			transaction = new Transaction(resource, response);
		});

		beforeEach(function(done) {
			async.parallel([
				function(next) { model.create({}, next); },
				function(next) { model.create({}, next); },
				function(next) { model.create({}, next); },
			], function(err, results) {
				if (err) return done(err);
				objects = results;
				done();
			});
		});

		afterEach(function(done) {
			mongoose.connection.db.dropDatabase(done);
		});

		it('retrieves mongoose documents from the database', function(done) {
			var resview = resource.view(transaction);
			resview.findMany(transaction, {}, function(err, results) {
				if (err) return done(err);
				expect(results).to.have.length(objects.length);
				_.each(results, function(result) {
					var obj = _.find(objects, function(obj) {
						return obj._id.equals(result._id);
					});
					expect(obj).to.exist;
				});
				done();
			});
		});

		it('runs transaction query handlers', function() {
			var handler = sinon.stub().returnsArg(1);
			transaction.subscribe(resource.type, 'query', handler);
			var resview = resource.view(transaction);
			var query = resview.findMany(transaction, {});
			expect(handler).to.have.been.calledWith(resource, query);
		});
	});

	describe('#serialize', function() {
		it('invokes serialize method on field', function(done) {
			var object = {};
			var accessor = createAccessor();
			accessor.serialize.callsArgWithAsync(3, null, 'value');
			var resource = new Resource({ type: 'test', field: accessor });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			resview.serialize(transaction, object, function(err, resdata) {
				if (err) return done(err);
				expect(accessor.serialize).to.have.been.called.once;
				done();
			});
		});
	});

	describe('#deserialize', function() {
		it('invokes deserialize method on field', function(done) {
			var object = {};
			var accessor = createAccessor();
			var resdata = { type: 'test', field: 'value' };
			accessor.deserialize.callsArgWithAsync(4, null, object);
			var resource = new Resource({ type: 'test', field: accessor });
			var transaction = new Transaction(resource, response);
			var resview = resource.view(transaction);
			resview.deserialize(transaction, resdata, object, function(err, resdata) {
				if (err) return done(err);
				expect(accessor.deserialize).to.have.been.called.once;
				done();
			});
		});
	});
});

function createAccessor() {
	return {
		adjustQuery: sinon.stub(),
		serialize: sinon.stub(),
		deserialize: sinon.stub(),
	};
}
<|endoftext|>


<commit_before>import Router from './router';
import {$, Backbone, _} from 'DefaultImports';
import tether from 'tether';
import {AppSetup} from './appsetup';
import appevents from './appevents';
import {app as simpleshelfApp} from './app';

/**
 * Main entry point to simpleshelf app.
 */

// To support Bootstrap, add jQuery & Tether to the global namespace.
window.$ = window.jQuery = $;
window.Tether = tether;

$(function() {
    // Load plugins and widgets on the global $.
    // require(["widgets/tags"]);

    // Override BB sync.
    AppSetup.overrideBackboneSync(Backbone, _);

    this.app = simpleshelfApp; // singleton

    // Setup top-level app objects.
    this.app.router = new Router({
        views: this.app.views,
        catalog: this.app.catalog,
        configuration: this.app.configuration
    });
    appevents.setupAppEvents(this.app);
    appevents.hookupAppEvents(this.app);

    // Start Backbone routing.
    // NOTE: when silent===true, no views are automatically invoked.
    // So if the hash is on an existing route (like ``#login``), nothing will appear to happen.
    // Read this before enabling pushState: http://stackoverflow.com/questions/9328513/backbone-js-and-pushstate
    let currentPath = location.pathname;
    let historyStart = Backbone.history.start({
        // pushState: true,
        root: currentPath
    });
    console.info("[main]", "Backbone.history.start",
        historyStart, (historyStart ? "Found initial matching route" : "No initial matching route"),
        'currentPath', currentPath
    );

    // Start app.
    this.app.promises.initialConfiguration.then(
        this.app.run
    );
});
<commit_msg>Shorten console log<commit_after>import Router from './router';
import {$, Backbone, _} from 'DefaultImports';
import tether from 'tether';
import {AppSetup} from './appsetup';
import appevents from './appevents';
import {app as simpleshelfApp} from './app';

/**
 * Main entry point to simpleshelf app.
 */

// To support Bootstrap, add jQuery & Tether to the global namespace.
window.$ = window.jQuery = $;
window.Tether = tether;

$(function() {
    // Load plugins and widgets on the global $.
    // require(["widgets/tags"]);

    // Override BB sync.
    AppSetup.overrideBackboneSync(Backbone, _);

    this.app = simpleshelfApp; // singleton

    // Setup top-level app objects.
    this.app.router = new Router({
        views: this.app.views,
        catalog: this.app.catalog,
        configuration: this.app.configuration
    });
    appevents.setupAppEvents(this.app);
    appevents.hookupAppEvents(this.app);

    // Start Backbone routing.
    // NOTE: when silent===true, no views are automatically invoked.
    // So if the hash is on an existing route (like ``#login``), nothing will appear to happen.
    // Read this before enabling pushState: http://stackoverflow.com/questions/9328513/backbone-js-and-pushstate
    let currentPath = location.pathname;
    let historyStart = Backbone.history.start({
        // pushState: true,
        root: currentPath
    });
    console.info("[main]", "Backbone.history.start",
        historyStart, (historyStart ? "Found initial matching route" : "No initial matching route"),
        currentPath
    );

    // Start app.
    this.app.promises.initialConfiguration.then(
        this.app.run
    );
});
<|endoftext|>