<commit_before>// Generated on 2014-06-25 using generator-angular 0.9.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function(grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    // Configurable paths for the application
    var appConfig = {
        app: require('./bower.json').appPath || 'app',
        dist: 'dist',
        buildDist: '../../dist/editors/dist'
    };

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: appConfig,

        // Watches files for changes and runs tasks based on the changed files
        watch: {
            sass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['sass:server']
            },
            template: {
                files: [
                    '<%= yeoman.app %>/views/{,*/}*.html',
                    '<%= yeoman.app %>/views/cliche/{,*/}*.html',
                    '<%= yeoman.app %>/views/app/{,*/}*.html',
                    '<%= yeoman.app %>/views/repo/{,*/}*.html',
                    '<%= yeoman.app %>/views/task/{,*/}*.html'
                ],
                tasks: ['templates']
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish'),
                ignores: ['**/*template.js', 'bower_components/**/*']
            },
            all: {
                src: [
                    'Gruntfile.js',
                    '<%= yeoman.app %>/scripts/**/*.js'
                ]
            },
            test: {
                options: {
                    jshintrc: 'test/.jshintrc'
                },
                src: ['test/spec/{,*/}*.js']
            }
        },

        sass: {
            server: {
                options: {
                    style: 'expanded',
                    sourcemap: 'auto'
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/styles',
                    src: ['*.scss'],
                    dest: '<%= yeoman.app %>/styles',
                    ext: '.css'
                }]
            },
            dist: {
                options: {
                    style: 'compressed',
                    sourcemap: 'none'
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/styles',
                    src: ['*.scss'],
                    dest: '.tmp/styles',
                    ext: '.css'
                }]
            }
        },

        // The following *-min tasks will produce minified files in the dist folder
        // By default, your `index.html`'s <!-- Usemin block --> will take care of
        // minification. These next options are pre-configured if you do not wish
        // to use the Usemin blocks.
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/{,*/}*.css'
                    ]
                }
            }
        },
        uglify: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/scripts/vendor.min.js': [
                        '<%= yeoman.dist %>/scripts/vendor.js'
                    ],
                   /* '<%= yeoman.dist %>/scripts/raphael.min.js': [
                        '<%= yeoman.dist %>/scripts/raphael.js'
                    ],*/
                    '<%= yeoman.dist %>/scripts/dyole.min.js': [
                        '<%= yeoman.dist %>/scripts/util.js',
                        '<%= yeoman.dist %>/scripts/integration.js',
                        '<%= yeoman.dist %>/scripts/cliche.js',
                        '<%= yeoman.dist %>/scripts/dyole.js'
                    ],
                    '<%= yeoman.dist %>/scripts/cliche.min.js': [
                        '<%= yeoman.dist %>/scripts/util.js',
                        '<%= yeoman.dist %>/scripts/integration.js',
                        '<%= yeoman.dist %>/scripts/cliche.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                separator: ';'
            },
            common: {
                src: [
                    '<%= yeoman.app %>/scripts/util/*.js',
                    '<%= yeoman.app %>/scripts/util/**/*.js',
                    '<%= yeoman.app %>/scripts/app/*.js',
                    '<%= yeoman.app %>/scripts/app/**/*.js',
                    '<%= yeoman.app %>/scripts/repo/*.js',
                    '<%= yeoman.app %>/scripts/repo/**/*.js',
                    '<%= yeoman.app %>/scripts/common/*.js',
                    '<%= yeoman.app %>/scripts/common/**/*.js'
                ],
                dest: 'dist/scripts/util.js'
            },
            dyole: {
                src: [
                    '<%= yeoman.app %>/scripts/cliche/**/*.js',
                    '<%= yeoman.app %>/scripts/dyole-app/*.js',
                    '<%= yeoman.app %>/scripts/dyole/dyole.config.js',
                    '<%= yeoman.app %>/scripts/dyole/**/*.js'
                ],
                dest: 'dist/scripts/dyole.js'
            },
            cliche: {
                src: [
                    '<%= yeoman.app %>/scripts/cliche-app/*.js',
                    '<%= yeoman.app %>/scripts/cliche/*.js',
                    '<%= yeoman.app %>/scripts/cliche/**/*.js'
                ],
                dest: 'dist/scripts/cliche.js'
            },
            integration: {
                src: [
                    '<%= yeoman.app %>/scripts/integration/*.js',
                    '<%= yeoman.app %>/scripts/integration/**/*.js'
                ],
                dest: 'dist/scripts/integration.js'
            },
            vendor: {
                src: [
                    '<%= yeoman.app %>/vendor/chronicle/chronicle.js',
                    '<%= yeoman.app %>/vendor/jsandbox/src/jsandbox.js',
                    '<%= yeoman.app %>/vendor/angular-ui-sortable/sortable.min.js'
                ],
                dest: 'dist/scripts/vendor.js'
            }
              /*  raphael: {

                    src: [
                        '<%= yeoman.app %>/vendor/raphael/!*.js'
                    ],
                    dest: 'dist/scripts/raphael.js'
                }*/
        },

        clean: {
            options: {
                force: true
            },
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/{,*!/}*',
                        '!<%= yeoman.dist %>/.git*',
                        '!<%= yeoman.dist %>/fonts'
                    ]
                }]
            },
            server: '.tmp'
        },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    //dest: '<%= yeoman.buildDist %>',
                    src: [
                        '*.{ico,png,txt}',
                        '.htaccess',
                        '*.html',
                        //'views/{,*/}*.html',
                        '!**/views/**',
                        'images/{,*/}*.{png,jpg,jpeg,gif,webp,svg,ico}',
                        'fonts/*',
                        //                            'bower_components/*'
                        'bower_components/es5-shim/es5-shim.js',
                        'bower_components/json3/lib/json3.min.js',
                        'bower_components/zeroclipboard/dist/ZeroClipboard.swf',
                        'data/*',
                        'vendor/jsandbox/src/jsandbox-worker.js',
                        'vendor/raphael/*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp/images',
                    dest: '<%= yeoman.dist %>/images',
                    src: ['generated/*']
                }]
            }
        },

        ngtemplates: {

            cliche: {
                cwd: '<%= yeoman.app %>',
                src: [
                    'views/{,*/}*.html',
                    'views/cliche/{,*/}*.html',
                    'views/app/{,*/}*.html',
                    'views/repo/{,*/}*.html',
                    'views/task/{,*/}*.html'
                ],
                dest: '<%= yeoman.app %>/scripts/cliche/template.js',
                options: {
                    module: 'registryApp.cliche',
                    htmlmin: {
                        collapseWhitespace: true,
                        collapseBooleanAttributes: true
                    }
                }
            },

            dyole: {
                cwd: '<%= yeoman.app %>',
                src: [
                    'views/{,*/}*.html',
                    'views/dyole/{,*/}*.html',
                    'views/cliche/{,*/}*.html',
                    'views/app/{,*/}*.html',
                    'views/repo/{,*/}*.html',
                    'views/task/{,*/}*.html'
                ],
                dest: '<%= yeoman.app %>/scripts/dyole/template.js',
                options: {
                    module: 'registryApp.dyole',
                    htmlmin: {
                        collapseWhitespace: true,
                        collapseBooleanAttributes: true
                    }
                }
            }
        }

    });

    grunt.registerTask('build', [
        'clean:dist',
        //        'useminPrepare',
       // 'concurrent:dist',
        'ngtemplates:dyole',
        'ngtemplates:cliche',
        //'autoprefixer',
        'concat',
        //'ngAnnotate',
        'copy:dist',
        'cssmin',
        'uglify'
    ]);

    grunt.registerTask('templates', [
        'ngtemplates:cliche',
        'ngtemplates:dyole'
    ])
};

<commit_msg>Refactor(editors): Removed unused task from Gruntfile<commit_after>// Generated on 2014-06-25 using generator-angular 0.9.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function(grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    // Configurable paths for the application
    var appConfig = {
        app: require('./bower.json').appPath || 'app',
        dist: 'dist',
        buildDist: '../../dist/editors/dist'
    };

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: appConfig,

        // Watches files for changes and runs tasks based on the changed files
        watch: {
            sass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['sass:server']
            },
            template: {
                files: [
                    '<%= yeoman.app %>/views/{,*/}*.html',
                    '<%= yeoman.app %>/views/cliche/{,*/}*.html',
                    '<%= yeoman.app %>/views/app/{,*/}*.html',
                    '<%= yeoman.app %>/views/repo/{,*/}*.html',
                    '<%= yeoman.app %>/views/task/{,*/}*.html'
                ],
                tasks: ['templates']
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish'),
                ignores: ['**/*template.js', 'bower_components/**/*']
            },
            all: {
                src: [
                    'Gruntfile.js',
                    '<%= yeoman.app %>/scripts/**/*.js'
                ]
            },
            test: {
                options: {
                    jshintrc: 'test/.jshintrc'
                },
                src: ['test/spec/{,*/}*.js']
            }
        },

        sass: {
            server: {
                options: {
                    style: 'expanded',
                    sourcemap: 'auto'
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/styles',
                    src: ['*.scss'],
                    dest: '<%= yeoman.app %>/styles',
                    ext: '.css'
                }]
            },
            dist: {
                options: {
                    style: 'compressed',
                    sourcemap: 'none'
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/styles',
                    src: ['*.scss'],
                    dest: '.tmp/styles',
                    ext: '.css'
                }]
            }
        },

        // The following *-min tasks will produce minified files in the dist folder
        // By default, your `index.html`'s <!-- Usemin block --> will take care of
        // minification. These next options are pre-configured if you do not wish
        // to use the Usemin blocks.
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/{,*/}*.css'
                    ]
                }
            }
        },
        uglify: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/scripts/vendor.min.js': [
                        '<%= yeoman.dist %>/scripts/vendor.js'
                    ],
                    '<%= yeoman.dist %>/scripts/dyole.min.js': [
                        '<%= yeoman.dist %>/scripts/util.js',
                        '<%= yeoman.dist %>/scripts/integration.js',
                        '<%= yeoman.dist %>/scripts/cliche.js',
                        '<%= yeoman.dist %>/scripts/dyole.js'
                    ],
                    '<%= yeoman.dist %>/scripts/cliche.min.js': [
                        '<%= yeoman.dist %>/scripts/util.js',
                        '<%= yeoman.dist %>/scripts/integration.js',
                        '<%= yeoman.dist %>/scripts/cliche.js'
                    ]
                }
            }
        },
        concat: {
            options: {
                separator: ';'
            },
            common: {
                src: [
                    '<%= yeoman.app %>/scripts/util/*.js',
                    '<%= yeoman.app %>/scripts/util/**/*.js',
                    '<%= yeoman.app %>/scripts/app/*.js',
                    '<%= yeoman.app %>/scripts/app/**/*.js',
                    '<%= yeoman.app %>/scripts/repo/*.js',
                    '<%= yeoman.app %>/scripts/repo/**/*.js',
                    '<%= yeoman.app %>/scripts/common/*.js',
                    '<%= yeoman.app %>/scripts/common/**/*.js'
                ],
                dest: 'dist/scripts/util.js'
            },
            dyole: {
                src: [
                    '<%= yeoman.app %>/scripts/cliche/**/*.js',
                    '<%= yeoman.app %>/scripts/dyole-app/*.js',
                    '<%= yeoman.app %>/scripts/dyole/dyole.config.js',
                    '<%= yeoman.app %>/scripts/dyole/**/*.js'
                ],
                dest: 'dist/scripts/dyole.js'
            },
            cliche: {
                src: [
                    '<%= yeoman.app %>/scripts/cliche-app/*.js',
                    '<%= yeoman.app %>/scripts/cliche/*.js',
                    '<%= yeoman.app %>/scripts/cliche/**/*.js'
                ],
                dest: 'dist/scripts/cliche.js'
            },
            integration: {
                src: [
                    '<%= yeoman.app %>/scripts/integration/*.js',
                    '<%= yeoman.app %>/scripts/integration/**/*.js'
                ],
                dest: 'dist/scripts/integration.js'
            },
            vendor: {
                src: [
                    '<%= yeoman.app %>/vendor/chronicle/chronicle.js',
                    '<%= yeoman.app %>/vendor/jsandbox/src/jsandbox.js',
                    '<%= yeoman.app %>/vendor/angular-ui-sortable/sortable.min.js'
                ],
                dest: 'dist/scripts/vendor.js'
            }
        },

        clean: {
            options: {
                force: true
            },
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/{,*!/}*',
                        '!<%= yeoman.dist %>/.git*',
                        '!<%= yeoman.dist %>/fonts'
                    ]
                }]
            },
            server: '.tmp'
        },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    //dest: '<%= yeoman.buildDist %>',
                    src: [
                        '*.{ico,png,txt}',
                        '.htaccess',
                        '*.html',
                        //'views/{,*/}*.html',
                        '!**/views/**',
                        'images/{,*/}*.{png,jpg,jpeg,gif,webp,svg,ico}',
                        'fonts/*',
                        //                            'bower_components/*'
                        'bower_components/es5-shim/es5-shim.js',
                        'bower_components/json3/lib/json3.min.js',
                        'bower_components/zeroclipboard/dist/ZeroClipboard.swf',
                        'data/*',
                        'vendor/jsandbox/src/jsandbox-worker.js',
                        'vendor/raphael/*'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp/images',
                    dest: '<%= yeoman.dist %>/images',
                    src: ['generated/*']
                }]
            }
        },

        ngtemplates: {

            cliche: {
                cwd: '<%= yeoman.app %>',
                src: [
                    'views/{,*/}*.html',
                    'views/cliche/{,*/}*.html',
                    'views/app/{,*/}*.html',
                    'views/repo/{,*/}*.html',
                    'views/task/{,*/}*.html'
                ],
                dest: '<%= yeoman.app %>/scripts/cliche/template.js',
                options: {
                    module: 'registryApp.cliche',
                    htmlmin: {
                        collapseWhitespace: true,
                        collapseBooleanAttributes: true
                    }
                }
            },

            dyole: {
                cwd: '<%= yeoman.app %>',
                src: [
                    'views/{,*/}*.html',
                    'views/dyole/{,*/}*.html',
                    'views/cliche/{,*/}*.html',
                    'views/app/{,*/}*.html',
                    'views/repo/{,*/}*.html',
                    'views/task/{,*/}*.html'
                ],
                dest: '<%= yeoman.app %>/scripts/dyole/template.js',
                options: {
                    module: 'registryApp.dyole',
                    htmlmin: {
                        collapseWhitespace: true,
                        collapseBooleanAttributes: true
                    }
                }
            }
        }

    });

    grunt.registerTask('build', [
        'clean:dist',
        //        'useminPrepare',
       // 'concurrent:dist',
        'ngtemplates:dyole',
        'ngtemplates:cliche',
        //'autoprefixer',
        'concat',
        //'ngAnnotate',
        'copy:dist',
        'cssmin',
        'uglify'
    ]);

    grunt.registerTask('templates', [
        'ngtemplates:cliche',
        'ngtemplates:dyole'
    ])
};

<|endoftext|>


<commit_before>const { getOnboardingConfig } = require('./config');
const {
  configFileNames,
  onboardingBranch,
} = require('../../../../config/app-strings');

const defaultConfigFile = configFileNames[0];

async function rebaseOnboardingBranch(config) {
  logger.debug('Checking if onboarding branch needs rebasing');
  const pr = await platform.getBranchPr(onboardingBranch);
  if (!pr.canRebase) {
    logger.info('Onboarding branch has been edited and cannot be rebased');
    return;
  }
  const existingContents = await platform.getFile(
    defaultConfigFile,
    onboardingBranch
  );
  const contents = await getOnboardingConfig(config);
  if (contents === existingContents && !pr.isStale) {
    logger.info('Onboarding branch is up to date');
    return;
  }
  logger.info('Rebasing onboarding branch');
  let commitMessage;
  // istanbul ignore if
  if (config.semanticCommits) {
    commitMessage = config.semanticCommitType;
    if (config.semanticCommitScope) {
      commitMessage += `(${config.semanticCommitScope})`;
    }
    commitMessage += ': ';
    commitMessage += 'add ' + defaultConfigFile;
  } else {
    commitMessage = 'Add ' + defaultConfigFile;
  }
  // istanbul ignore if
  if (config.dryRun) {
    logger.info('DRY-RUN: Would rebase files in onboarding branch');
  } else {
    await platform.commitFilesToBranch(
      onboardingBranch,
      [
        {
          name: defaultConfigFile,
          contents: existingContents || contents,
        },
      ],
      commitMessage
    );
  }
}

module.exports = {
  rebaseOnboardingBranch,
};
<commit_msg>refactor: getCommitMessage<commit_after>const { getOnboardingConfig } = require('./config');
const {
  configFileNames,
  onboardingBranch,
} = require('../../../../config/app-strings');

const defaultConfigFile = configFileNames[0];

function getCommitMessage(config) {
  let commitMessage;
  // istanbul ignore if
  if (config.semanticCommits) {
    commitMessage = config.semanticCommitType;
    if (config.semanticCommitScope) {
      commitMessage += `(${config.semanticCommitScope})`;
    }
    commitMessage += ': ';
    commitMessage += 'add ' + defaultConfigFile;
  } else {
    commitMessage = 'Add ' + defaultConfigFile;
  }
  return commitMessage;
}

async function rebaseOnboardingBranch(config) {
  logger.debug('Checking if onboarding branch needs rebasing');
  const pr = await platform.getBranchPr(onboardingBranch);
  if (!pr.canRebase) {
    logger.info('Onboarding branch has been edited and cannot be rebased');
    return;
  }
  const existingContents = await platform.getFile(
    defaultConfigFile,
    onboardingBranch
  );
  const contents = await getOnboardingConfig(config);
  if (contents === existingContents && !pr.isStale) {
    logger.info('Onboarding branch is up to date');
    return;
  }
  logger.info('Rebasing onboarding branch');
  // istanbul ignore next
  const commitMessage = getCommitMessage(config);

  // istanbul ignore if
  if (config.dryRun) {
    logger.info('DRY-RUN: Would rebase files in onboarding branch');
  } else {
    await platform.commitFilesToBranch(
      onboardingBranch,
      [
        {
          name: defaultConfigFile,
          contents: existingContents || contents,
        },
      ],
      commitMessage
    );
  }
}

module.exports = {
  rebaseOnboardingBranch,
};
<|endoftext|>


<commit_before>/* jshint node: true */

"use strict";

/*
   This script tries to focus on just making a query and doing some simiple analysis. The libraries it
   uses help somewhat. There is still too much overhead to make a simple query of VersionOne.
 */

var v1oauth = require('v1oauth');
var express = require('express');
var AuthApp = v1oauth.app;
var secrets = require('../client_secrets');
var app = express();
var auth = new AuthApp(secrets, {appBaseUrl: "http://localhost:8088", secureCookies: false});
var debug = require('debug')('query-v1');
var request = require('superagent');
var serverBaseUri = secrets.web.server_base_uri;
var url = auth.url();
var exec = require('child_process').exec;
var path = require('path');
var queryObject = require(path.join(__dirname, '../node_modules/sample-v1-queries/scope-state-exploration.json'));

queryObject.page.size = 1000;

app.use(auth.router);
app.listen(8088);

var browserProcess = exec('open ' + url, function (error, stdout, stderr) {
  if (error !== null) {
    debug('error', error);
  }
});

auth.once('refreshToken', function (tokens) {
  debug('got tokens');
  var token = tokens.access_token;
  request
    .get(serverBaseUri + '/query.v1')
    .set('Authorization', 'Bearer ' + token)
    .send(queryObject)
    .end(function (res) {
      var names = {};

      if (res.ok) {
        //debug('successful request!', JSON.stringify(res.body, null, 2));
        queryObject.select.forEach(function (propName) {
          var values = {};
          res.body[0].forEach(function (scope) {
            var propValue = scope[propName];
            values[propValue] = (values[propValue] || 0) + 1;
          });
          var allUnique = true;
          var uniqueValues = 0;
          Object.keys(values).forEach(function (propValue) {
            var count = values[propValue];
            if (count > 1) {
              debug('%s: %s, count: %d', propName, propValue, count);
              allUnique = false;
            } else {
              uniqueValues++;
            }
          });

          if (allUnique) {
            debug('%s: all values were unique', propName);
          } else {
            debug('%s: %d unique value(s) omitted', propName, uniqueValues);
          }
        });
      } else {
        debug("failed to get data", res.text);
      }
    });

});

<commit_msg>Clump together token code.<commit_after>/* jshint node: true */

"use strict";

/*
   This script tries to focus on just making a query and doing some simiple analysis. The libraries it
   uses help somewhat. There is still too much overhead to make a simple query of VersionOne.
 */

var v1oauth = require('v1oauth');
var express = require('express');
var AuthApp = v1oauth.app;
var secrets = require('../client_secrets');
var debug = require('debug')('query-v1');
var request = require('superagent');
var exec = require('child_process').exec;
var path = require('path');
var queryObject = require(path.join(__dirname, '../node_modules/sample-v1-queries/scope-state-exploration.json'));
var Q = require('q');

queryObject.page.size = 1000;

function getToken(secrets) {
  var app = express();
  var auth = new AuthApp(secrets, {appBaseUrl: "http://localhost:8088", secureCookies: false});
  var dfd = Q.defer();
  var serverBaseUri = secrets.web.server_base_uri;
  var url = auth.url();

  app.use(auth.router);
  app.listen(8088);

  auth.once('refreshToken', function (tokens) {
    debug('got tokens');
    var token = tokens.access_token;
    dfd.resolve(token);
  });

  var browserProcess = exec('open ' + url, function (error, stdout, stderr) {
    if (error !== null) {
      debug('error', error);
    }
  });

  return dfd.promise;
}

getToken(secrets).then(function (token) {
  request
    .get(serverBaseUri + '/query.v1')
    .set('Authorization', 'Bearer ' + token)
    .send(queryObject)
    .end(function (res) {
      var names = {};

      if (res.ok) {
        //debug('successful request!', JSON.stringify(res.body, null, 2));
        queryObject.select.forEach(function (propName) {
          var values = {};
          res.body[0].forEach(function (scope) {
            var propValue = scope[propName];
            values[propValue] = (values[propValue] || 0) + 1;
          });
          var allUnique = true;
          var uniqueValues = 0;
          Object.keys(values).forEach(function (propValue) {
            var count = values[propValue];
            if (count > 1) {
              debug('%s: %s, count: %d', propName, propValue, count);
              allUnique = false;
            } else {
              uniqueValues++;
            }
          });

          if (allUnique) {
            debug('%s: all values were unique', propName);
          } else {
            debug('%s: %d unique value(s) omitted', propName, uniqueValues);
          }
        });
      } else {
        debug("failed to get data", res.text);
      }
    });
});

<|endoftext|>


<commit_before>module.exports = function (grunt) {

    var config = {};

    config.jshint = {
        // define the files to lint
        files: ['src/**/*.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
            // more options here if you want to override JSHint defaults
            globals: {
                loopfunc: true
            }
        }
    };

    config.compile = {
        unittest: {
            banner: "<%= banner %>",
            wrap: 'hb',
            build: 'tests/build',
            filename: 'hb-unittest',
            scripts: {
                inspect: ['tests/spec/util/**/**.js'],
                includes: ['tests/helpers/define.js'],
                src: ['src/**/**.js']
            }
        }
    };

    config.jasmine = {
        tests: {
            src: ['tests/build/hb-unittest.js'],
            options: {
                //helpers: '**/*-helper.js',
//                    specs: 'tests/spec/**/*.js'
                specs: [
                    'tests/spec/util/**/*_Spec.js'
                ]
            }
        },
        spec: {
            src: ['tests/build/hb-unittest.js'],
            options: {
                //helpers: '**/*-helper.js',
//                    specs: 'tests/spec/**/*.js'
                specs: [
                    'tests/spec/<%= specData.file %>_Spec.js'
                ]
            }
        }
    };

    config.jsdoc = {
        dist: {
            src: ['src/utils/ajax/**/*.js'],
            jsdoc: './node_modules/.bin/jsdoc',
            options: {
                destination: 'doc',
                //configure: './node_modules/jsdoc/conf.json',
                //template: './node_modules/ink-docstrap/template'
            }
        }
    };

    grunt.initConfig(config);

    grunt.loadTasks('tasks');

    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.loadNpmTasks('grunt-jsdoc');

    grunt.registerTask('jshint', ['jshint']);
    grunt.registerTask('test', [/*'jshint', */'compile:unittest', 'jasmine:tests']);
    grunt.registerTask('docs', ['jsdoc']);

    // to use do
    // grunt spec:pathToFile
    // it adds the _Spec.js to each file. and each file starts in the spec/util directory
    grunt.registerTask('spec', 'Runs a task on a specified file', function (fileName) {
        specData.file = fileName;
        grunt.task.run("compile:unittest");// build the unit tests
        grunt.task.run('jasmine:spec');// run that spec.
    });
};<commit_msg>Updated Gruntfile to auto-load tasks<commit_after>module.exports = function (grunt) {

    // load tasks
    require('load-grunt-tasks')(grunt);

    var config = {};

    config.jshint = {
        // define the files to lint
        files: ['src/**/*.js'],
        // configure JSHint (documented at http://www.jshint.com/docs/)
        options: {
            // more options here if you want to override JSHint defaults
            globals: {
                loopfunc: true
            }
        }
    };

    config.compile = {
        unittest: {
            banner: "<%= banner %>",
            wrap: 'hb',
            build: 'tests/build',
            filename: 'hb-unittest',
            scripts: {
                inspect: ['tests/spec/util/**/**.js'],
                includes: ['tests/helpers/define.js'],
                src: ['src/**/**.js']
            }
        }
    };

    config.jasmine = {
        tests: {
            src: ['tests/build/hb-unittest.js'],
            options: {
                //helpers: '**/*-helper.js',
//                    specs: 'tests/spec/**/*.js'
                specs: [
                    'tests/spec/util/**/*_Spec.js'
                ]
            }
        },
        spec: {
            src: ['tests/build/hb-unittest.js'],
            options: {
                //helpers: '**/*-helper.js',
//                    specs: 'tests/spec/**/*.js'
                specs: [
                    'tests/spec/<%= specData.file %>_Spec.js'
                ]
            }
        }
    };

    config.jsdoc = {
        dist: {
            src: ['src/utils/ajax/**/*.js'],
            jsdoc: './node_modules/.bin/jsdoc',
            options: {
                destination: 'doc',
                //configure: './node_modules/jsdoc/conf.json',
                //template: './node_modules/ink-docstrap/template'
            }
        }
    };

    // Bumps the version on certain files, puahses changes and tags package
    // IF YOU TOUCH THIS MAKE SURE YOU KNOW WHAT YOU'RE DOING
    // See "grunt-bump" for more information
    config.bump = {
        options: {
            files: ['package.json'],
            updateConfigs: [],
            commit: true,
            commitMessage: 'Release v%VERSION%',
            commitFiles: ['package.json'],
            createTag: true,
            tagName: 'v%VERSION%',
            tagMessage: 'Version %VERSION%',
            push: true,
            pushTo: 'origin',
            gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
            globalReplace: false,
            prereleaseName: false,
            regExp: false
        }
    };

    grunt.initConfig(config);

    grunt.loadTasks('tasks');

    grunt.registerTask('jshint', ['jshint']);
    grunt.registerTask('test', [/*'jshint', */'compile:unittest', 'jasmine:tests']);
    grunt.registerTask('docs', ['jsdoc']);

    // to use do
    // grunt spec:pathToFile
    // it adds the _Spec.js to each file. and each file starts in the spec/util directory
    grunt.registerTask('spec', 'Runs a task on a specified file', function (fileName) {
        specData.file = fileName;
        grunt.task.run("compile:unittest");// build the unit tests
        grunt.task.run('jasmine:spec');// run that spec.
    });
};<|endoftext|>


<commit_before>importModule('core.JSON');
importFromModule('helma.file', 'File');
importFromModule('helma.functional', 'partial');
importModule('helma.logging', 'logging');
var log = logging.getLogger(__name__);

var __shared__ = true;

/**
 * The base/wrapper prototype for persistent minibase objects
 *
 * @param obj the raw javascript object to wrap
 * @param properties the persistent object properties (optional)
 */
function makeStorable(obj, properties) {

    if (!(obj instanceof Object) || !(obj.constructor instanceof Function))
        throw new Error("object must be an object, was: " + properties);
    if (!(obj.constructor instanceof Function))
        throw new Error("object must have a constructor property, has: "  + obj.constructor);
    if (properties === undefined)
        properties = {};
    if (!(properties instanceof Object))
        throw new Error("properties must be an object, was: " + properties);

    var ctor = obj.constructor;
    var type = ctor.name;
    var id;

    if (typeof type != "string")
        throw new Error("couldn't get type: " + type);

    obj.__get__ = function(name) {
        if (name == "_id") {
            return id;
        } else if (name == "_type") {
            return type;
        }
        if (this[name]) return this[name];
        var value = properties[name];
        if (isKey(value)) {
            value = ctor.store.get(value._type, value._id);
        }
        return value;
    };

    obj.__set__ = function(name, value) {
        if (name == "_id") {
            if (id != undefined) {
                throw new Error("Cannot change _id on storable object");
            }
            id = value;
            return;
        }
        if (typeof value == "function") {
            this[name] = value;
            return;
        } else if (isPersistentStorable(value)) {
            value = value.getKey();
        }
        properties[name] = value;
    };

    obj.__delete__ = function(name) {
        delete properties[name];
    };

    obj.__has__ = function(name) {
        return properties[name] !== undefined ||
               this[name] !== undefined;
    };

    obj.__getIds__ = function() {
        var ids = [];
        for (var id in properties) {
            ids[ids.length] = id
        }
        return ids;
    };

    obj.save = function(txn) {
        ctor.save(txn, this, properties);
    };

    obj.remove = function(txn) {
        ctor.remove(txn, this);
    };

    obj.getKey = function() {
        if (!(typeof id == "string")) {
            throw new Error("getKey() called on non-persistent object");
        }
        return {_id: id, _type: type};
    }

    // only define toString if object doesn't have one already
    if (obj.toString == Object.prototype.toString) {
        obj.toString = function() {
            return type + "[" + id + "]";
        };
    }
}

/**
 * File Store class
 * @param path the database directory
 */
function Store(path) {

    // the class registry
    var typeRegistry = {};

    // map of type to current id tip
    var idMap = {};

    this.registerType = function(ctor) {
        if (typeof ctor != "function") {
           throw new Error("registerType() called with non-function argument: " + ctor);
        }
        if (typeof ctor.name != "string") {
           throw new Error("constructor must not be an anonymous function");
        }
        // add class to registry
        typeRegistry[ctor.name] = ctor;
        // install filter, all, and get methods on constructor
        ctor.list = partial(list, ctor.name);
        ctor.all = partial(getAll, ctor.name);
        ctor.get = partial(get, ctor.name);
        ctor.save = partial(save);
        ctor.remove = partial(remove);
        ctor.store = this;
    };

    this.getRegisteredType = function(name) {
        return typeRegistry[name];
    }

    var list = function(type, options) {
        var array = getAll(type);
        if (options) {
            // first filter out the the items we're not interested in
            var filter = options.filter;
            if (typeof filter == "function") {
                array = array.filter(filter);
            }
            // then put them into order
            var [orderBy, ascDesc] = [options.orderBy, options.order == "desc" ? -1 : 1];
            if (options.orderBy) {
                array = array.sort(function(o1, o2) {
                    var [p1, p2] = [o1[orderBy], o2[orderBy]];
                    if (p1 < p2) return -1 * ascDesc;
                    if (p1 > p2) return  1 * ascDesc;
                    return 0;
                })
            }
            // finally apply pagination/slicing
            var [start, max] = [parseInt(options.start, 10), parseInt(options.max, 10)];
            if (isFinite(start) || isFinite(max)) {
                var start = start || 0;
                array = array.slice(start, start + max || array.length);
            }
        }
        return array;
    };

    var getAll = function(type) {
       var dir = new File(base, type);
       if (!dir.exists() || !dir.isDirectory()) {
           return [];
       }
       var files = dir.listFiles();
       var list = [];

       for each (var file in files) {
           if (!file.isFile() || file.isHidden()) {
               continue;
           }
           list.push(persister.retrieve(type, new File(file)));
       }
       return list;
    }

    var get = function(type, id) {
       var dir = new File(base, type);
       var file = new File(dir, id);

       if (!file.exists()) {
           return null;
       } else if (!file.isFile()) {
           throw new Error("Is not a regular file: " + file);
       }
       return persister.retrieve(type, file);
    }

    var save = function(txn, obj, properties) {
        var wrapTransaction = !txn;
        if (wrapTransaction) {
            txn = new Transaction();
        }
        for (var i in properties) {
            var v = properties[i];
            if (isStorable(v)) {
                if (isTransientStorable(v)) {
                    v.save(txn);
                }
                properties[i] = v.getKey();
            }
        }
        var [type, id] = [obj._type, obj._id];
        var dir = new File(base, type);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                throw new Error("Can't create directory for type " + type);
            }
        }
        if (id == undefined) {
            obj._id = id = persister.generateId(type, dir);
        }

        var file = new File(dir, id);
        var tempFileName = type + id + ".";
        var tempfile = base.createTempFile(tempFileName, ".tmp");

        persister.store(properties, tempfile);

        if (file.exists() && !file.canWrite()) {
            throw new Error("No write permission for " + file);
        }

        txn.updateResource({ file: file, tempfile: tempfile });

        if (wrapTransaction) {
            txn.commit();
        }
    };

    var remove = function(txn, obj) {
        var wrapTransaction = !txn;
        if (wrapTransaction) {
            txn = new Transaction();
        }
        for (var i in obj) {
            var v = obj[i];
            if (isPersistentStorable(v)) {
                // cascading delete (just to show it works)
                v.remove(txn);
            }
        }
        var [type, id] = [obj._type, obj._id];
        if (!type) {
            throw new Error("type not defined in object " + obj);
        }
        if (!id) {
            throw new Error("id not defined in object " + obj);
        }

        var file = new File(new File(base, type), id);
        txn.deleteResource({ file: file });

        if (wrapTransaction) {
            txn.commit();
        }
    };

    // the persister
    var persister = {

        store: function(object, file) {
            log.debug("Storing object: " + object.toSource());
            file.open({ append: true });
            file.write(object.toJSON());
            file.close();
        },

        retrieve: function(type, file) {
            var content = file.readAll();
            var properties = content.parseJSON();
            var ctor = typeRegistry[type];
            if (!ctor) {
                throw new Error("constructor not registered for type " + type);
            }
            var obj = new ctor(properties);
            obj._id = file.getName();
            return obj;
        },

        generateId: function(type, dir) {
            var id = idMap[type] || 1;
            var file = new File(dir, id.toString(36));
            while(file.exists()) {
                id += 1;
                file = new File(dir, id.toString(36));
            }

            idMap[type] = id + 1;
            return file.getName();
        }

    };

    var base = new File(path);
    log.debug("Set up new store: " + base);

};

var isKey = function(value) {
    return value instanceof Object
            && typeof value._id == 'string'
            && typeof value._type == 'string';
}

var isStorable = function(value) {
    return value instanceof JSAdapter
            && typeof value._type == 'string';
}

var isPersistentStorable = function(value) {
    return isStorable(value)
            && typeof value._id == 'string';
}

var isTransientStorable = function(value) {
    return isStorable(value)
            && typeof value._id == 'undefined';
}

function Transaction() {

   var updateList = [];
   var deleteList = [];

   this.deleteResource = function(res) {
      deleteList.push(res);
   }

   this.updateResource = function(res) {
      updateList.push(res);
   }

   this.commit = function() {
      for each (var res in updateList) {
         // because of a Java/Windows quirk, we have to delete
         // the existing file before trying to overwrite it
         if (res.file.exists()) {
             res.file.remove();
         }
         // move temporary file to permanent name
         if (res.tempfile.renameTo(res.file)) {
             // success - delete tmp file
            res.tempfile.remove();
         } else {
            // error - leave tmp file and print a message
            log.error("Couldn't move file, committed version is in " + res.tempfile);
         }
      }

      for each (var res in deleteList) {
         res.file.remove();
      }

      updateList = [];
      deleteList = [];
   }

   this.abort = function() {
      for each (var res in updateList) {
         res.tempfile.remove();
      }
   }
}<commit_msg>fixed filestore's save method to use the File::makeDirectory js method since mkdirs is only a Java method and the object in this context is no longer a Java File object<commit_after>importModule('core.JSON');
importFromModule('helma.file', 'File');
importFromModule('helma.functional', 'partial');
importModule('helma.logging', 'logging');
var log = logging.getLogger(__name__);

var __shared__ = true;

/**
 * The base/wrapper prototype for persistent minibase objects
 *
 * @param obj the raw javascript object to wrap
 * @param properties the persistent object properties (optional)
 */
function makeStorable(obj, properties) {

    if (!(obj instanceof Object) || !(obj.constructor instanceof Function))
        throw new Error("object must be an object, was: " + properties);
    if (!(obj.constructor instanceof Function))
        throw new Error("object must have a constructor property, has: "  + obj.constructor);
    if (properties === undefined)
        properties = {};
    if (!(properties instanceof Object))
        throw new Error("properties must be an object, was: " + properties);

    var ctor = obj.constructor;
    var type = ctor.name;
    var id;

    if (typeof type != "string")
        throw new Error("couldn't get type: " + type);

    obj.__get__ = function(name) {
        if (name == "_id") {
            return id;
        } else if (name == "_type") {
            return type;
        }
        if (this[name]) return this[name];
        var value = properties[name];
        if (isKey(value)) {
            value = ctor.store.get(value._type, value._id);
        }
        return value;
    };

    obj.__set__ = function(name, value) {
        if (name == "_id") {
            if (id != undefined) {
                throw new Error("Cannot change _id on storable object");
            }
            id = value;
            return;
        }
        if (typeof value == "function") {
            this[name] = value;
            return;
        } else if (isPersistentStorable(value)) {
            value = value.getKey();
        }
        properties[name] = value;
    };

    obj.__delete__ = function(name) {
        delete properties[name];
    };

    obj.__has__ = function(name) {
        return properties[name] !== undefined ||
               this[name] !== undefined;
    };

    obj.__getIds__ = function() {
        var ids = [];
        for (var id in properties) {
            ids[ids.length] = id
        }
        return ids;
    };

    obj.save = function(txn) {
        ctor.save(txn, this, properties);
    };

    obj.remove = function(txn) {
        ctor.remove(txn, this);
    };

    obj.getKey = function() {
        if (!(typeof id == "string")) {
            throw new Error("getKey() called on non-persistent object");
        }
        return {_id: id, _type: type};
    }

    // only define toString if object doesn't have one already
    if (obj.toString == Object.prototype.toString) {
        obj.toString = function() {
            return type + "[" + id + "]";
        };
    }
}

/**
 * File Store class
 * @param path the database directory
 */
function Store(path) {

    // the class registry
    var typeRegistry = {};

    // map of type to current id tip
    var idMap = {};

    this.registerType = function(ctor) {
        if (typeof ctor != "function") {
           throw new Error("registerType() called with non-function argument: " + ctor);
        }
        if (typeof ctor.name != "string") {
           throw new Error("constructor must not be an anonymous function");
        }
        // add class to registry
        typeRegistry[ctor.name] = ctor;
        // install filter, all, and get methods on constructor
        ctor.list = partial(list, ctor.name);
        ctor.all = partial(getAll, ctor.name);
        ctor.get = partial(get, ctor.name);
        ctor.save = partial(save);
        ctor.remove = partial(remove);
        ctor.store = this;
    };

    this.getRegisteredType = function(name) {
        return typeRegistry[name];
    }

    var list = function(type, options) {
        var array = getAll(type);
        if (options) {
            // first filter out the the items we're not interested in
            var filter = options.filter;
            if (typeof filter == "function") {
                array = array.filter(filter);
            }
            // then put them into order
            var [orderBy, ascDesc] = [options.orderBy, options.order == "desc" ? -1 : 1];
            if (options.orderBy) {
                array = array.sort(function(o1, o2) {
                    var [p1, p2] = [o1[orderBy], o2[orderBy]];
                    if (p1 < p2) return -1 * ascDesc;
                    if (p1 > p2) return  1 * ascDesc;
                    return 0;
                })
            }
            // finally apply pagination/slicing
            var [start, max] = [parseInt(options.start, 10), parseInt(options.max, 10)];
            if (isFinite(start) || isFinite(max)) {
                var start = start || 0;
                array = array.slice(start, start + max || array.length);
            }
        }
        return array;
    };

    var getAll = function(type) {
       var dir = new File(base, type);
       if (!dir.exists() || !dir.isDirectory()) {
           return [];
       }
       var files = dir.listFiles();
       var list = [];

       for each (var file in files) {
           if (!file.isFile() || file.isHidden()) {
               continue;
           }
           list.push(persister.retrieve(type, new File(file)));
       }
       return list;
    }

    var get = function(type, id) {
       var dir = new File(base, type);
       var file = new File(dir, id);

       if (!file.exists()) {
           return null;
       } else if (!file.isFile()) {
           throw new Error("Is not a regular file: " + file);
       }
       return persister.retrieve(type, file);
    }

    var save = function(txn, obj, properties) {
        var wrapTransaction = !txn;
        if (wrapTransaction) {
            txn = new Transaction();
        }
        for (var i in properties) {
            var v = properties[i];
            if (isStorable(v)) {
                if (isTransientStorable(v)) {
                    v.save(txn);
                }
                properties[i] = v.getKey();
            }
        }
        var [type, id] = [obj._type, obj._id];
        var dir = new File(base, type);
        if (!dir.exists()) {
            if (!dir.makeDirectory()) {
                throw new Error("Can't create directory for type " + type);
            }
        }
        if (id == undefined) {
            obj._id = id = persister.generateId(type, dir);
        }

        var file = new File(dir, id);
        var tempFileName = type + id + ".";
        var tempfile = base.createTempFile(tempFileName, ".tmp");

        persister.store(properties, tempfile);

        if (file.exists() && !file.canWrite()) {
            throw new Error("No write permission for " + file);
        }

        txn.updateResource({ file: file, tempfile: tempfile });

        if (wrapTransaction) {
            txn.commit();
        }
    };

    var remove = function(txn, obj) {
        var wrapTransaction = !txn;
        if (wrapTransaction) {
            txn = new Transaction();
        }
        for (var i in obj) {
            var v = obj[i];
            if (isPersistentStorable(v)) {
                // cascading delete (just to show it works)
                v.remove(txn);
            }
        }
        var [type, id] = [obj._type, obj._id];
        if (!type) {
            throw new Error("type not defined in object " + obj);
        }
        if (!id) {
            throw new Error("id not defined in object " + obj);
        }

        var file = new File(new File(base, type), id);
        txn.deleteResource({ file: file });

        if (wrapTransaction) {
            txn.commit();
        }
    };

    // the persister
    var persister = {

        store: function(object, file) {
            log.debug("Storing object: " + object.toSource());
            file.open({ append: true });
            file.write(object.toJSON());
            file.close();
        },

        retrieve: function(type, file) {
            var content = file.readAll();
            var properties = content.parseJSON();
            var ctor = typeRegistry[type];
            if (!ctor) {
                throw new Error("constructor not registered for type " + type);
            }
            var obj = new ctor(properties);
            obj._id = file.getName();
            return obj;
        },

        generateId: function(type, dir) {
            var id = idMap[type] || 1;
            var file = new File(dir, id.toString(36));
            while(file.exists()) {
                id += 1;
                file = new File(dir, id.toString(36));
            }

            idMap[type] = id + 1;
            return file.getName();
        }

    };

    var base = new File(path);
    log.debug("Set up new store: " + base);

};

var isKey = function(value) {
    return value instanceof Object
            && typeof value._id == 'string'
            && typeof value._type == 'string';
}

var isStorable = function(value) {
    return value instanceof JSAdapter
            && typeof value._type == 'string';
}

var isPersistentStorable = function(value) {
    return isStorable(value)
            && typeof value._id == 'string';
}

var isTransientStorable = function(value) {
    return isStorable(value)
            && typeof value._id == 'undefined';
}

function Transaction() {

   var updateList = [];
   var deleteList = [];

   this.deleteResource = function(res) {
      deleteList.push(res);
   }

   this.updateResource = function(res) {
      updateList.push(res);
   }

   this.commit = function() {
      for each (var res in updateList) {
         // because of a Java/Windows quirk, we have to delete
         // the existing file before trying to overwrite it
         if (res.file.exists()) {
             res.file.remove();
         }
         // move temporary file to permanent name
         if (res.tempfile.renameTo(res.file)) {
             // success - delete tmp file
            res.tempfile.remove();
         } else {
            // error - leave tmp file and print a message
            log.error("Couldn't move file, committed version is in " + res.tempfile);
         }
      }

      for each (var res in deleteList) {
         res.file.remove();
      }

      updateList = [];
      deleteList = [];
   }

   this.abort = function() {
      for each (var res in updateList) {
         res.tempfile.remove();
      }
   }
}<|endoftext|>


<commit_before>'use strict';

const chai = require('chai');
const request = require('request');
const expect = chai.expect;
const nock = require('nock');

// ====== App init

const appPort = 4000;
const appUrl = 'http://localhost:' + appPort + '/';
const appApiKey = 'testing';

const normalNumber = '44NORMAL';
const adminNumber = '44ADMIN';

before(function(done) {
	process.env.PORT = appPort;
	process.env.API_KEY = appApiKey;
	process.env.ALLOWED_NUMBERS = adminNumber;

	const app = require('../index');
	app(done);
});

// ====== Test helpers

function sendSMS(params) {
	params = params || {};
	params.from = params.from || normalNumber;

	return request.post({
		url: appUrl,
		form: params
	});
}

function expectSMS(param) {
	param = param || {};
	param.key = appApiKey;

	let apiCall = nock('https://api.clockworksms.com')
		.post('/http/send.aspx', param)
		.reply(200, 'XXX Fill me out properly');

	return apiCall;
}

// ====== Testing bits

function turnOnResponses(it, before) {
	it('(assuming responses are turned on)')
	before(function(done) {
		sendSMS({ content: 'on', from: adminNumber })
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(200);
				done();
			});
	})
}

// ====== Testing proper

describe('If I post to the endpoint', function() {
	it('(assuming RESTRICT_IP=1) I should receive an error', function(done) {
		process.env.RESTRICT_IP = 1;
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(401);
				done();
			});
	})

	it('(assuming RESTRICT_IP=0) I should not receive an error', function(done) {
		process.env.RESTRICT_IP = 0;
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(200);
				done();
			});
	})
})

describe('Testing commands.  If I send an SMS', function() {
	afterEach(function() {
		nock.cleanAll();
	})

	describe('starting with "on" from an admin number', function() {

		it('I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /on/ });

			sendSMS({
				content: 'on',
				from: adminNumber
			})
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		// This test is identical to the one above except with a 'keyword' added
		it('(with shortcode) I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /on/ });

			sendSMS({
				keyword: 'keyword',
				content: 'keyword on',
				from: adminNumber
			})
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		it('sending another SMS (from non admin number) should get me a message', function(done) {
			let responseSMS = expectSMS();

			return sendSMS()
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "off" from an admin number', function() {
		it('I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /off/ });

			sendSMS({ content: 'off', from: adminNumber })
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		it('sending another SMS (from non admin number) should get me no message', function(done) {
			let responseSMS = expectSMS();

			return sendSMS()
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(false);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "update"', function() {
		const newMessage = 'Testing 1234';

		turnOnResponses(it, before);

		describe('from a non admin number', function() {
			it('it should be treated as an empty text & I should receive a reply', function(done) {
				let responseSMS = expectSMS({ content: 'Testing' }); // XXX this is a magic constant

				sendSMS({ content: 'update ' + newMessage })
					.on('error', done)
					.on('response', response => {
						expect(responseSMS.isDone()).to.equal(true);
						expect(response.statusCode).to.equal(200);
						done();
					});
			})
		})

		describe('from an admin number', function() {
			it('I should receive confirmation of change', function(done) {
				let confirmationSMS = expectSMS({ content: /updated/ });

				sendSMS({ content: 'update ' + newMessage, from: adminNumber })
					.on('error', done)
					.on('response', response => {
						expect(confirmationSMS.isDone()).to.equal(true);
						expect(response.statusCode).to.equal(200);
						done();
					});
			})

			it('sending another SMS (from a non admin number) should get me the new message', function(done) {
				let responseSMS = expectSMS({ content: newMessage });

				return sendSMS()
					.on('error', done)
					.on('response', response => {
						expect(responseSMS.isDone()).to.equal(true);
						expect(response.statusCode).to.equal(200);
						done();
					});
			})
		})

	})

})

describe('Testing update distribution', function() {

	turnOnResponses(it, before);

	it('if I send an empty SMS from a non admin number', function(done) {
		let responseSMS = expectSMS();
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(responseSMS.isDone()).to.equal(true);
				done();
			})
	})

	it('and then update the message text, the update should be sent to the non admin number', function(done) {
		let confirmationSMS = expectSMS({ to: adminNumber });
		let updateSMS = expectSMS({ content: /amazingtime/, to: normalNumber });

		sendSMS({ content: 'update amazingtime', from: adminNumber })
			.on('error', done)
			.on('response', response => {
				expect(confirmationSMS.isDone()).to.equal(true);
				expect(updateSMS.isDone()).to.equal(true);
				done();
			});
	})
})

<commit_msg>Add failing test for update with keyword<commit_after>'use strict';

const chai = require('chai');
const request = require('request');
const expect = chai.expect;
const nock = require('nock');

// ====== App init

const appPort = 4000;
const appUrl = 'http://localhost:' + appPort + '/';
const appApiKey = 'testing';

const normalNumber = '44NORMAL';
const adminNumber = '44ADMIN';

before(function(done) {
	process.env.PORT = appPort;
	process.env.API_KEY = appApiKey;
	process.env.ALLOWED_NUMBERS = adminNumber;

	const app = require('../index');
	app(done);
});

// ====== Test helpers

function sendSMS(params) {
	params = params || {};
	params.from = params.from || normalNumber;

	return request.post({
		url: appUrl,
		form: params
	});
}

function expectSMS(param) {
	param = param || {};
	param.key = appApiKey;

	let apiCall = nock('https://api.clockworksms.com')
		.post('/http/send.aspx', param)
		.reply(200, 'XXX Fill me out properly');

	return apiCall;
}

// ====== Testing bits

function turnOnResponses(it, before) {
	it('(assuming responses are turned on)')
	before(function(done) {
		sendSMS({ content: 'on', from: adminNumber })
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(200);
				done();
			});
	})
}

// ====== Testing proper

describe('If I post to the endpoint', function() {
	it('(assuming RESTRICT_IP=1) I should receive an error', function(done) {
		process.env.RESTRICT_IP = 1;
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(401);
				done();
			});
	})

	it('(assuming RESTRICT_IP=0) I should not receive an error', function(done) {
		process.env.RESTRICT_IP = 0;
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(response.statusCode).to.equal(200);
				done();
			});
	})
})

describe('Testing commands.  If I send an SMS', function() {
	afterEach(function() {
		nock.cleanAll();
	})

	describe('starting with "on" from an admin number', function() {

		it('I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /on/ });

			sendSMS({
				content: 'on',
				from: adminNumber
			})
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		// This test is identical to the one above except with a 'keyword' added
		it('(with keyword) I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /on/ });

			sendSMS({
				keyword: 'keyword',
				content: 'keyword on',
				from: adminNumber
			})
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		it('sending another SMS (from non admin number) should get me a message', function(done) {
			let responseSMS = expectSMS();

			return sendSMS()
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "off" from an admin number', function() {
		it('I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /off/ });

			sendSMS({ content: 'off', from: adminNumber })
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		it('sending another SMS (from non admin number) should get me no message', function(done) {
			let responseSMS = expectSMS();

			return sendSMS()
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(false);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "update" from a non admin number', function() {
		turnOnResponses(it, before);

		it('it should be treated as an empty text & I should receive a reply', function(done) {
			let responseSMS = expectSMS({ content: 'Testing' }); // XXX this is a magic constant

			sendSMS({ content: 'update blah' })
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "update" from an admin number (no keyword)', function() {
		const newMessage = 'Testing 1234';

		it('I should receive confirmation of change', function(done) {
			let confirmationSMS = expectSMS({ content: /updated/ });

			sendSMS({ content: 'update ' + newMessage, from: adminNumber })
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})

		it('sending another SMS (from a non admin number) should get me the new message', function(done) {
			let responseSMS = expectSMS({ content: newMessage });

			return sendSMS()
				.on('error', done)
				.on('response', response => {
					expect(responseSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})

	describe('starting with "update" from an admin number (with keyword)', function() {
		turnOnResponses(it, before);

		const newMessage = '1234';

		it('I should receive confirmation of change without "update" in the message', function(done) {
			let confirmationSMS = expectSMS(body => !body.content.includes('update 1234'));

			sendSMS({
				keyword: 'keyword',
				content: 'keyword update ' + newMessage,
				from: adminNumber
			})
				.on('error', done)
				.on('response', response => {
					expect(confirmationSMS.isDone()).to.equal(true);
					expect(response.statusCode).to.equal(200);
					done();
				});
		})
	})
})

describe('Testing update distribution', function() {
	turnOnResponses(it, before);

	it('if I send an empty SMS from a non admin number', function(done) {
		let responseSMS = expectSMS();
		sendSMS()
			.on('error', done)
			.on('response', response => {
				expect(responseSMS.isDone()).to.equal(true);
				done();
			})
	})

	it('and then update the message text, the update should be sent to the non admin number', function(done) {
		let confirmationSMS = expectSMS({ to: adminNumber });
		let updateSMS = expectSMS({ content: /amazingtime/, to: normalNumber });

		sendSMS({ content: 'update amazingtime', from: adminNumber })
			.on('error', done)
			.on('response', response => {
				expect(confirmationSMS.isDone()).to.equal(true);
				expect(updateSMS.isDone()).to.equal(true);
				done();
			});
	})
})
<|endoftext|>


<commit_before>/* global cozy, document, __APP_VERSION__ */

import { LocalStorage as Storage } from 'cozy-client-js'

const clientRevokedMsg = 'Client has been revoked'
const getStorage = () => new Storage()
const getClientName = device => `Cozy Drive Application on ${device} (${Math.random().toString(36).slice(2)})`

const getClientParams = (device) => ({
  redirectURI: 'http://localhost',
  softwareID: 'io.cozy.drive.mobile',
  clientName: getClientName(device),
  softwareVersion: __APP_VERSION__,
  clientKind: 'mobile',
  clientURI: 'https://github.com/cozy/cozy-drive/',
  logoURI: 'https://raw.githubusercontent.com/cozy/cozy-drive/master/vendor/assets/apple-touch-icon-120x120.png',
  policyURI: 'https://files.cozycloud.cc/cgu.pdf',
  scopes: ['io.cozy.files']
})

const getAuth = (onRegister, device) => ({
  storage: getStorage(),
  clientParams: getClientParams(device),
  onRegistered: onRegister
})

export const initClient = (url, onRegister = null, device = 'Device') => {
  if (url) {
    console.log(`Cozy Client initializes a connection with ${url}`)
    cozy.client.init({
      cozyURL: url,
      oauth: getAuth(onRegister, device)
    })
  }
}

export const initBar = () => {
  const root = document.querySelector('[role=application]')
  const data = root.dataset

  cozy.bar.init({
    appName: data.cozyAppName,
    appEditor: data.cozyAppEditor,
    iconPath: data.cozyIconPath,
    lang: data.cozyLocale,
    replaceTitleOnMobile: true
  })
}

export const isClientRegistered = async (client) => {
  return await cozy.client.auth.getClient(client).then(client => true).catch(err => {
    if (err.message === clientRevokedMsg) {
      return false
    }
    // this is the error sent if we are offline
    if (err.message === 'Failed to fetch') {
      return true
    }
    throw err
  })
}

export function resetClient () {
  // reset cozy-bar
  if (document.getElementById('coz-bar')) {
    document.getElementById('coz-bar').remove()
  }
  // reset pouchDB
  if (cozy.client.offline.destroyAllDatabase) {
    cozy.client.offline.destroyAllDatabase()
  }
  // reset cozy-client-js
  if (cozy.client._storage) {
    cozy.client._storage.clear()
  }
}
<commit_msg>fix: wrong way to support editor on mobile<commit_after>/* global cozy, document, __APP_VERSION__ */

import { LocalStorage as Storage } from 'cozy-client-js'

const clientRevokedMsg = 'Client has been revoked'
const getStorage = () => new Storage()
const getClientName = device => `Cozy Drive Application on ${device} (${Math.random().toString(36).slice(2)})`

const getClientParams = (device) => ({
  redirectURI: 'http://localhost',
  softwareID: 'io.cozy.drive.mobile',
  clientName: getClientName(device),
  softwareVersion: __APP_VERSION__,
  clientKind: 'mobile',
  clientURI: 'https://github.com/cozy/cozy-drive/',
  logoURI: 'https://raw.githubusercontent.com/cozy/cozy-drive/master/vendor/assets/apple-touch-icon-120x120.png',
  policyURI: 'https://files.cozycloud.cc/cgu.pdf',
  scopes: ['io.cozy.files']
})

const getAuth = (onRegister, device) => ({
  storage: getStorage(),
  clientParams: getClientParams(device),
  onRegistered: onRegister
})

export const initClient = (url, onRegister = null, device = 'Device') => {
  if (url) {
    console.log(`Cozy Client initializes a connection with ${url}`)
    cozy.client.init({
      cozyURL: url,
      oauth: getAuth(onRegister, device)
    })
  }
}

export const initBar = () => {
  cozy.bar.init({
    appName: 'Cozy Drive',
    appEditor: 'Cozy',
    iconPath: require('../../../vendor/assets/app-icon.svg'),
    lang: 'en',
    replaceTitleOnMobile: true
  })
}

export const isClientRegistered = async (client) => {
  return await cozy.client.auth.getClient(client).then(client => true).catch(err => {
    if (err.message === clientRevokedMsg) {
      return false
    }
    // this is the error sent if we are offline
    if (err.message === 'Failed to fetch') {
      return true
    }
    throw err
  })
}

export function resetClient () {
  // reset cozy-bar
  if (document.getElementById('coz-bar')) {
    document.getElementById('coz-bar').remove()
  }
  // reset pouchDB
  if (cozy.client.offline.destroyAllDatabase) {
    cozy.client.offline.destroyAllDatabase()
  }
  // reset cozy-client-js
  if (cozy.client._storage) {
    cozy.client._storage.clear()
  }
}
<|endoftext|>


<commit_before>'use strict';
/*jshint node:true*/
var normalizeEntityName = require('ember-cli-normalize-entity-name');

module.exports = {
  description: 'Generates a helper function.',
  normalizeEntityName: function(entityName) {
    return normalizeEntityName(entityName);
  }
};
<commit_msg>Fix helper<commit_after>module.exports = {
  description: 'Generates a helper function.',
  normalizeEntityName: function() {
    var blueprint = this.lookupBlueprint('helper');
    return blueprint.normalizeEntityName.apply(blueprint, arguments);
  }
};
<|endoftext|>


<commit_before>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		// Tests will be added soon
		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		sass: {
			main: {
				files: {
					'css/theme/default.css': 'css/theme/source/default.scss',
					'css/theme/beige.css': 'css/theme/source/beige.scss',
					'css/theme/night.css': 'css/theme/source/night.scss',
					'css/theme/serif.css': 'css/theme/source/serif.scss',
					'css/theme/simple.css': 'css/theme/source/simple.scss',
					'css/theme/sky.css': 'css/theme/source/sky.scss',
					'css/theme/moon.css': 'css/theme/source/moon.scss',
					'css/theme/solarized.css': 'css/theme/source/solarized.scss'
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.'
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
			main: {
				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
				tasks: 'default'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'themes'
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-contrib-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );

	// Theme task
	grunt.registerTask( 'themes', [ 'sass' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<commit_msg>grunt<commit_after>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		// Tests will be added soon
		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		sass: {
			main: {
				files: {
					'css/theme/default.css': 'css/theme/source/default.scss',
					'css/theme/beige.css': 'css/theme/source/beige.scss',
					'css/theme/night.css': 'css/theme/source/night.scss',
					'css/theme/serif.css': 'css/theme/source/serif.scss',
					'css/theme/simple.css': 'css/theme/source/simple.scss',
					'css/theme/sky.css': 'css/theme/source/sky.scss',
					'css/theme/moon.css': 'css/theme/source/moon.scss',
					'css/theme/solarized.css': 'css/theme/source/solarized.scss'
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.',
					hostname: "0.0.0.0"
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
			main: {
				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
				tasks: 'default'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'themes'
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-contrib-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );

	// Theme task
	grunt.registerTask( 'themes', [ 'sass' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<|endoftext|>


<commit_before>
//Gruntfile
module.exports = function(grunt) {

//Initializing the configuration object
  grunt.initConfig({

    // Task configuration
    concat: {
      options: {
        separator: ';',
      },
      js_frontend: {
        src: [
          './bower_components/jquery/dist/jquery.js',
          './bower_components/bootstrap/dist/js/bootstrap.js',
          './app/assets/javascript/frontend.js'
        ],
        dest: './public/assets/javascript/frontend.js',
      }
    },
    less: {
        development: {
            options: {
              compress: true,  //minifying the result
            },
            files: {
              //compiling frontend.less into frontend.css
              "./public/assets/stylesheets/frontend.css":"./app/assets/stylesheets/frontend.less",
            }
        }
    },
    uglify: {
      options: {
        mangle: false  // Use if you want the names of your functions and variables unchanged
      },
      frontend: {
        files: {
          './public/assets/javascript/frontend.js': './public/assets/javascript/frontend.js',
        }
      },
      backend: {
        files: {
          './public/assets/javascript/backend.js': './public/assets/javascript/backend.js',
        }
      },
    },
    watch: {
      js_frontend: {
          files: [
            //watched files
            './bower_components/jquery/jquery.js',
            './bower_components/bootstrap/dist/js/bootstrap.js',
            './app/assets/javascript/frontend.js'
            ],
          tasks: ['concat:js_frontend','uglify:frontend'],     //tasks to run
          options: {
            livereload: true                        //reloads the browser
          }
        },
        less: {
          files: ['./app/assets/stylesheets/*.less'],  //watched files
          tasks: ['less'],                          //tasks to run
          options: {
            livereload: true                        //reloads the browser
          }
        }
    }
  });

    // Plugin loading
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // Task definition
    grunt.registerTask('default', ['concat', 'less', 'uglify', 'watch']);

};
<commit_msg>updated the gruntfile, tried to build files that was not created<commit_after>
//Gruntfile
module.exports = function(grunt) {

//Initializing the configuration object
  grunt.initConfig({

    // Task configuration
    concat: {
      options: {
        separator: ';',
      },
      js_frontend: {
        src: [
          './bower_components/jquery/dist/jquery.js',
          './bower_components/bootstrap/dist/js/bootstrap.js',
          './app/assets/javascript/frontend.js'
        ],
        dest: './public/assets/javascript/frontend.js',
      }
    },
    less: {
        development: {
            options: {
              compress: true,  //minifying the result
            },
            files: {
              //compiling frontend.less into frontend.css
              "./public/assets/stylesheets/frontend.css":"./app/assets/stylesheets/frontend.less",
            }
        }
    },
    uglify: {
      options: {
        mangle: false  // Use if you want the names of your functions and variables unchanged
      },
      frontend: {
        files: {
          './public/assets/javascript/frontend.js': './public/assets/javascript/frontend.js',
        }
      }
    },
    watch: {
      js_frontend: {
          files: [
            //watched files
            './bower_components/jquery/jquery.js',
            './bower_components/bootstrap/dist/js/bootstrap.js',
            './app/assets/javascript/frontend.js'
            ],
          tasks: ['concat:js_frontend','uglify:frontend'],     //tasks to run
          options: {
            livereload: true                        //reloads the browser
          }
        },
        less: {
          files: ['./app/assets/stylesheets/*.less'],  //watched files
          tasks: ['less'],                          //tasks to run
          options: {
            livereload: true                        //reloads the browser
          }
        }
    }
  });

    // Plugin loading
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // Task definition
    grunt.registerTask('default', ['concat', 'less', 'uglify', 'watch']);

};
<|endoftext|>


<commit_before>var util = require('util');
var winston = require('winston');
var BaseTrigger = require('./baseTrigger.js').BaseTrigger;
/*
 Trigger that responds to messages with the amount of time the bot script has been running, adn some other useful info
 command = string - What is the command. - defaults to !botinfo
 */

var InfoTrigger = function() {
	InfoTrigger.super_.apply(this, arguments);
};

util.inherits(InfoTrigger, BaseTrigger);

var type = "InfoTrigger";
exports.triggerType = type;
exports.create = function(name, chatBot, options) {
	var trigger = new InfoTrigger(type, name, chatBot, options);
	trigger.options.command = trigger.options.command || "!botinfo";
	trigger.startTime = process.hrtime();
	return trigger;
};

// Return true if a message was sent
InfoTrigger.prototype._respondToFriendMessage = function(userId, message) {
	return this._respond(userId, message);
}

// Return true if a message was sent
InfoTrigger.prototype._respondToChatMessage = function(roomId, chatterId, message) {
	return this._respond(roomId, message);
}

InfoTrigger.prototype._respond = function(toId, message) {
	if (this.options.command && message && message.toLowerCase().indexOf(this.options.command.toLowerCase()) == 0) {
		var meminfo = process.memoryUsage();
		var curtime = process.hrtime(this.startTime);
			curtime = curtime[1] + curtime[0]*1000000000;
		var message  = "I have been running for about " + this._nanosecondsToStr(curtime);
			message += " on " + process.platform + "/" + process.arch;
			message += ", using " + this._bytesToSize(meminfo.heapUsed) + " of " + this._bytesToSize(meminfo.heapTotal) + " allocated memory (RSS: " + this._bytesToSize(meminfo.rss);
			message += "). Node.js version is "+process.version+".";
			this._sendMessageAfterDelay(toId,message);
		return true;
	}
	return false;
}

InfoTrigger.prototype._nanosecondsToStr = function(nanoseconds) {
	var milliseconds = Math.floor(nanoseconds/1000000);
    function numberEnding (number) {return (number > 1) ? 's' : '';}
    var temp = Math.floor(milliseconds / 1000);
    var days = Math.floor((temp %= 31536000) / 86400);
    if (days) return days + ' day' + numberEnding(days);
    var hours = Math.floor((temp %= 86400) / 3600);
    if (hours) return hours + ' hour' + numberEnding(hours);
    var minutes = Math.floor((temp %= 3600) / 60);
    if (minutes) return minutes + ' minute' + numberEnding(minutes);
    var seconds = temp % 60;
    if (seconds) return seconds + ' second' + numberEnding(seconds);
    return 'less than a second'; //'just now' //or other string you like;
}

InfoTrigger.prototype._bytesToSize = function(bytes) {
   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
   if (bytes == 0) return '0 Byte';
   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};<commit_msg>improve infotrigger<commit_after>var util = require('util');
var winston = require('winston');
var BaseTrigger = require('./baseTrigger.js').BaseTrigger;
/*
 Trigger that responds to messages with the amount of time the bot script has been running, adn some other useful info
 command = string - What is the command. - defaults to !botinfo
 */

var InfoTrigger = function() {
	InfoTrigger.super_.apply(this, arguments);
};

util.inherits(InfoTrigger, BaseTrigger);

var type = "InfoTrigger";
exports.triggerType = type;
exports.create = function(name, chatBot, options) {
	var trigger = new InfoTrigger(type, name, chatBot, options);
	trigger.options.command = trigger.options.command || "!botinfo";
	trigger.startTime = process.hrtime();
	return trigger;
};

// Return true if a message was sent
InfoTrigger.prototype._respondToFriendMessage = function(userId, message) {
	return this._respond(userId, message);
}

// Return true if a message was sent
InfoTrigger.prototype._respondToChatMessage = function(roomId, chatterId, message) {
	return this._respond(roomId, message);
}

InfoTrigger.prototype._respond = function(toId, message) {
	if (this.options.command && message && message.toLowerCase().indexOf(this.options.command.toLowerCase()) == 0) {
		var meminfo = process.memoryUsage();
		var curtime = process.hrtime(this.startTime);
			curtime = curtime[1] + curtime[0]*1000000000;
		var message  = "I have been running for about " + this._nanosecondsToStr(Math.floor(curtime/1000000000));
			message += " on " + process.platform + "/" + process.arch;
			message += ", using " + this._bytesToSize(meminfo.heapUsed) + " of " + this._bytesToSize(meminfo.heapTotal) + " allocated memory (RSS: " + this._bytesToSize(meminfo.rss);
			message += "). Node.js version is "+process.version+".";
			this._sendMessageAfterDelay(toId,message);
		return true;
	}
	return false;
}

InfoTrigger.prototype._nanosecondsToStr = function(seconds, goagain) {
    var temp = seconds;
    function numberEnding (number) {return (number > 1) ? 's' : '';}

    if(temp > 259200) {
        var temp = Math.floor(temp / 86400);
        var next = (goagain==true ? this._nanosecondsToStr(seconds-temp*86400,false) : "");
        return ' ' + temp + ' day' + numberEnding(temp) + next;
    } else if (temp > 10800) {
        var temp = Math.floor(temp / 3600);
        var next = (goagain==true ? this._nanosecondsToStr(seconds-temp*3600,false) : "");
        return ' ' + temp + ' hour' + numberEnding(temp) + next;
    } else if (temp > 180) {
        var temp = Math.floor(temp / 60);
        var next = (goagain==true ? this._nanosecondsToStr(seconds-temp*60,false) : "");
        return ' ' + temp + ' minute' + numberEnding(temp) + next;
    } else return (goagain==true ? " less than a minute" : "");
}
InfoTrigger.prototype._bytesToSize = function(bytes) {
    var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
    if (bytes == 0) return '0 Byte';
    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
    return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var AttributeTrigger = require('../util/attribute_trigger');

/**
 * An attribute trigger that uses subclasses of {@link BaseRelation} to define
 * a set of properties & methods dynamically. Everything that's returned from
 * the subclass's {@link BaseRelation#methods} will be added to the object on
 * which the trigger was defined.
 *
 * During invocation, this trigger creates the {@link BaseRelation} subclass
 * based on the type & arguments that were given to the initializer. The
 * relation object that's created will be constructed with the following
 * arguments: the name of the attribute being defined, the class object on
 * which it's being defined, and any `args` given to the trigger will be
 * concatenated to these arguments.
 *
 * While you could use this class directly, the convenience method
 * {@link BaseRelation.attribute}, allows creation by subclasses with a simpler
 * method call.
 *
 * @since 1.0
 * @protected
 * @constructor RelationAttr
 * @extends AttributeTrigger
 * @param {Class} type The type of relation
 * @param {Arguments} arguments Arguments to be pass through to the creation of
 * the relation type (these will be concatenated on the end of the standard
 * arguments passed to the relation constructor).
 */
var RelationAttr = AttributeTrigger.extend(/** @lends RelationAttr# */ {
  init: function(type, args) {
    this._type = type;
    this._args = _.collect(args);
  },

  /**
   * Override of {@link AttributeTrigger#invoke}.
   *
   * @since 1.0
   * @public
   * @method
   * @see {@link AttributeTrigger#invoke}
   */
  invoke: function(name, reopen, details) {
    var type = this._type;
    var modelClass = details.context.__identity__;
    var args = [name, modelClass].concat(this._args);
    var relation = type.create.apply(type, args);
    var methods = relation.methods();
    reopen(methods);
  }

});

module.exports = RelationAttr.reopenClass({ __name__: 'RelationAttr' });
<commit_msg>Refactor/documentation.<commit_after>'use strict';

var _ = require('lodash');
var AttributeTrigger = require('../util/attribute_trigger');

/**
 * An attribute trigger that uses subclasses of {@link BaseRelation} to define
 * a set of properties & methods dynamically. Everything that's returned from
 * the subclass's {@link BaseRelation#methods} will be added to the object on
 * which the trigger was defined.
 *
 * While you could use this class directly, the convenience method
 * {@link BaseRelation.attribute}, allows creation by subclasses with a simpler
 * method call.
 *
 * @since 1.0
 * @protected
 * @constructor RelationAttr
 * @extends AttributeTrigger
 * @param {Class} type The type of relation
 * @param {Arguments} arguments Arguments to be pass through to the creation of
 * the relation type (these will be concatenated on the end of the standard
 * arguments passed to the relation constructor).
 */
var RelationAttr = AttributeTrigger.extend(/** @lends RelationAttr# */ {
  init: function(type, args) {
    this._type = type;
    this._args = _.collect(args);
  },

  /**
   * Build a new relation object for determining methods to add.
   *
   * The {@link BaseRelation} subclass is created based on the type & arguments
   * that were given to the initializer. The object that's created will be
   * constructed with the following arguments: the name of the attribute being
   * defined, and the class object on which it's being defined. Any `args`
   * given to the trigger's constructor will be concatenated on to these
   * arguments.
   *
   * @since 1.0
   * @private
   * @method
   * @param {String} name The name of the attribute being defined.
   * @param {Object} details The details of the attribute, given unaltered
   * from {@link AttributeTrigger#invoke}.
   * @see {@link AttributeTrigger#invoke}
   */
  _relation: function(name, details) {
    var type = this._type;
    var modelClass = details.context.__identity__;
    var args = [name, modelClass].concat(this._args);
    return type.create.apply(type, args);
  },

  /**
   * Override of {@link AttributeTrigger#invoke}.
   *
   * @since 1.0
   * @public
   * @method
   * @see {@link AttributeTrigger#invoke}
   */
  invoke: function(name, reopen, details) {
    reopen(this._relation(name, details).methods());
  }

});

module.exports = RelationAttr.reopenClass({ __name__: 'RelationAttr' });
<|endoftext|>