Write out badFingerprints file for top 500

--- src/main.js
+++ src/main.js
@@ -3,7 +3,11 @@
 var path = require('path');
 let fs = require('fs');
 let perSiteInfo = {};
+let badFingerprints = new Set();

+function writeBadFingerprints() {
+  fs.writeFile('./badFingerprints.json', JSON.stringify(badFingerprints), 'utf-8');
+}
 let sequence = init('./node_modules/ad-info/data/easylist.txt');

 top500.forEach(siteHost => {
@@ -18,6 +22,10 @@
   });
   sequence = sequence.then(info  => {
     console.log('site results: ', siteHost, info);
+    if (info.badFingerprints) {
+      info.badFingerprints.forEach((o) => badFingerprints.add(o.badFingerprint));
+      writeBadFingerprints();
+    }
     perSiteInfo[siteHost] = info;
   });
 });

<|original_code|>
import {init, getAdInfo, exit} from 'ad-info';
import top500 from './top500';
var path = require('path');
let fs = require('fs');
let perSiteInfo = {};

let sequence = init('./node_modules/ad-info/data/easylist.txt');

top500.forEach(siteHost => {
  sequence = sequence.then(() => {
    console.log('doing lookup for site: ', siteHost);
    return new Promise((resolve, reject) => {
      getAdInfo(`http://${siteHost}`).then(resolve).catch((err) => {
        console.warn('Error obtaining info for site host:', siteHost, '. Error:', err);
        resolve();
      });
    });
  });
  sequence = sequence.then(info  => {
    console.log('site results: ', siteHost, info);
    perSiteInfo[siteHost] = info;
  });
});
sequence.then(() => {
  fs.writeFileSync('./perSiteInfo.json', JSON.stringify(perSiteInfo));
}).then(exit).catch(err => console.error('something went wrong:', err));

<|edits_diff|>
--- src/main.js
+++ src/main.js
@@ -3,7 +3,11 @@
 var path = require('path');
 let fs = require('fs');
 let perSiteInfo = {};
+let badFingerprints = new Set();

+function writeBadFingerprints() {
+  fs.writeFile('./badFingerprints.json', JSON.stringify(badFingerprints), 'utf-8');
+}
 let sequence = init('./node_modules/ad-info/data/easylist.txt');

 top500.forEach(siteHost => {
<|current_version|>
import {init, getAdInfo, exit} from 'ad-info';
import top500 from './top500';
var path = require('path');
let fs = require('fs');
let perSiteInfo = {};
let badFingerprints = new Set();

function writeBadFingerprints() {
  fs.writeFile('./badFingerprints.json', JSON.stringify(badFingerprints), 'utf-8');
}
let sequence = init('./node_modules/ad-info/data/easylist.txt');

top500.forEach(siteHost => {
  sequence = sequence.then(() => {
    console.log('doing lookup for site: ', siteHost);
    return new Promise((resolve, reject) => {
      getAdInfo(`http://${siteHost}`).then(resolve).catch((err) => {
        console.warn('Error obtaining info for site host:', siteHost, '. Error:', err);
        resolve();
      });
    });
  });
  sequence = sequence.then(info  => {
    console.log('site results: ', siteHost, info);
    perSiteInfo[siteHost] = info;
  });
});
sequence.then(() => {
  fs.writeFileSync('./perSiteInfo.json', JSON.stringify(perSiteInfo));
}).then(exit).catch(err => console.error('something went wrong:', err));

<|next_version|>
import {init, getAdInfo, exit} from 'ad-info';
import top500 from './top500';
var path = require('path');
let fs = require('fs');
let perSiteInfo = {};
let badFingerprints = new Set();

function writeBadFingerprints() {
  fs.writeFile('./badFingerprints.json', JSON.stringify(badFingerprints), 'utf-8');
}
let sequence = init('./node_modules/ad-info/data/easylist.txt');

top500.forEach(siteHost => {
  sequence = sequence.then(() => {
    console.log('doing lookup for site: ', siteHost);
    return new Promise((resolve, reject) => {
      getAdInfo(`http://${siteHost}`).then(resolve).catch((err) => {
        console.warn('Error obtaining info for site host:', siteHost, '. Error:', err);
        resolve();
      });
    });
  });
  sequence = sequence.then(info  => {
    console.log('site results: ', siteHost, info);
    if (info.badFingerprints) {
      info.badFingerprints.forEach((o) => badFingerprints.add(o.badFingerprint));
      writeBadFingerprints();
    }
    perSiteInfo[siteHost] = info;
  });
});
sequence.then(() => {
  fs.writeFileSync('./perSiteInfo.json', JSON.stringify(perSiteInfo));
}).then(exit).catch(err => console.error('something went wrong:', err));


Add https status on error

Add https status on error

--- src/controllers/seed.controller.js
+++ src/controllers/seed.controller.js
@@ -15,6 +15,7 @@
       .status(HTTPStatus.OK)
       .send(`User seed success! Created ${req.params.count} users!`);
   } catch (e) {
+    e.status = HTTPStatus.BAD_REQUEST;
     return next(e);
   }
 }
@@ -25,6 +26,7 @@

     return res.status(HTTPStatus.OK).send('User collection empty');
   } catch (e) {
+    e.status = HTTPStatus.BAD_REQUEST;
     return next(e);
   }
 }
@@ -42,6 +44,7 @@

     return res.status(HTTPStatus.OK).send('All collections clear');
   } catch (e) {
+    e.status = HTTPStatus.BAD_REQUEST;
     return next(e);
   }
 }

<|original_code|>
/**
 * Seed controller for fill your db of fake data
 */

import HTTPStatus from 'http-status';

import User from '../models/user.model';
import { userSeed, deleteUserSeed } from '../seeds/user.seed';

export async function seedUsers(req, res, next) {
  try {
    await userSeed(req.params.count);

    return res
      .status(HTTPStatus.OK)
      .send(`User seed success! Created ${req.params.count} users!`);
  } catch (e) {
    return next(e);
  }
}

export async function clearSeedUsers(req, res, next) {
  try {
    await deleteUserSeed();

    return res.status(HTTPStatus.OK).send('User collection empty');
  } catch (e) {
    return next(e);
  }
}

/**
 * Take all your model and clear it
 *
 * @param {any} req
 * @param {any} res
 * @returns {String} All collections clear
 */
export async function clearAll(req, res, next) {
  try {
    await Promise.all([User.remove()]);

    return res.status(HTTPStatus.OK).send('All collections clear');
  } catch (e) {
    return next(e);
  }
}

<|edits_diff|>
--- src/controllers/seed.controller.js
+++ src/controllers/seed.controller.js
@@ -15,6 +15,7 @@
       .status(HTTPStatus.OK)
       .send(`User seed success! Created ${req.params.count} users!`);
   } catch (e) {
+    e.status = HTTPStatus.BAD_REQUEST;
     return next(e);
   }
 }
@@ -25,6 +26,7 @@

     return res.status(HTTPStatus.OK).send('User collection empty');
   } catch (e) {
+    e.status = HTTPStatus.BAD_REQUEST;
     return next(e);
   }
 }
<|current_version|>
/**
 * Seed controller for fill your db of fake data
 */

import HTTPStatus from 'http-status';

import User from '../models/user.model';
import { userSeed, deleteUserSeed } from '../seeds/user.seed';

export async function seedUsers(req, res, next) {
  try {
    await userSeed(req.params.count);

    return res
      .status(HTTPStatus.OK)
      .send(`User seed success! Created ${req.params.count} users!`);
  } catch (e) {
    e.status = HTTPStatus.BAD_REQUEST;
    return next(e);
  }
}

export async function clearSeedUsers(req, res, next) {
  try {
    await deleteUserSeed();

    return res.status(HTTPStatus.OK).send('User collection empty');
  } catch (e) {
    e.status = HTTPStatus.BAD_REQUEST;
    return next(e);
  }
}

/**
 * Take all your model and clear it
 *
 * @param {any} req
 * @param {any} res
 * @returns {String} All collections clear
 */
export async function clearAll(req, res, next) {
  try {
    await Promise.all([User.remove()]);

    return res.status(HTTPStatus.OK).send('All collections clear');
  } catch (e) {
    return next(e);
  }
}

<|next_version|>
/**
 * Seed controller for fill your db of fake data
 */

import HTTPStatus from 'http-status';

import User from '../models/user.model';
import { userSeed, deleteUserSeed } from '../seeds/user.seed';

export async function seedUsers(req, res, next) {
  try {
    await userSeed(req.params.count);

    return res
      .status(HTTPStatus.OK)
      .send(`User seed success! Created ${req.params.count} users!`);
  } catch (e) {
    e.status = HTTPStatus.BAD_REQUEST;
    return next(e);
  }
}

export async function clearSeedUsers(req, res, next) {
  try {
    await deleteUserSeed();

    return res.status(HTTPStatus.OK).send('User collection empty');
  } catch (e) {
    e.status = HTTPStatus.BAD_REQUEST;
    return next(e);
  }
}

/**
 * Take all your model and clear it
 *
 * @param {any} req
 * @param {any} res
 * @returns {String} All collections clear
 */
export async function clearAll(req, res, next) {
  try {
    await Promise.all([User.remove()]);

    return res.status(HTTPStatus.OK).send('All collections clear');
  } catch (e) {
    e.status = HTTPStatus.BAD_REQUEST;
    return next(e);
  }
}


Add trace logs for response duration

Add trace logs for response duration

--- app.js
+++ app.js
@@ -16,6 +16,8 @@

 http.createServer(function(req, resp) {
   try {
+    var startDate = Date.now();
+
     var isGet = req.method === 'GET';

     var module = urlUtils.module(req.url);
@@ -28,6 +30,10 @@
     } else {
       api.proxyToCentralRepository(req, resp);
     }
+
+    resp.on('finish', function() {
+      logger.trace('%s: response in %sms', req.url, Date.now() - startDate);
+    });
   } catch (error) {
     logger.error(error);
   }

<|original_code|>
'use strict';

var http = require('http');

var config = require('./lib/configLoader');
var urlUtils = require('./lib/urlUtils');
var api = require('./lib/api');

var logger = config.logger;

process.on('uncaughtException', function(err) {
  logger.error('Uncaught exception: %s', JSON.stringify(err, null, 4));
});

api.initChangesSync();

http.createServer(function(req, resp) {
  try {
    var isGet = req.method === 'GET';

    var module = urlUtils.module(req.url);
    var tarball = urlUtils.tarball(req.url);

    if (isGet && tarball) {
      api.manageAttachment(req, resp, tarball);
    } else if (isGet && module) {
      api.manageModule(req, resp, module);
    } else {
      api.proxyToCentralRepository(req, resp);
    }
  } catch (error) {
    logger.error(error);
  }
}).listen(config.port, function() {
  logger.info('Server running at http://localhost:%s with config:\n%s', config.port, JSON.stringify(config, null, 4));
});

<|edits_diff|>
--- app.js
+++ app.js
@@ -16,6 +16,8 @@

 http.createServer(function(req, resp) {
   try {
+    var startDate = Date.now();
+
     var isGet = req.method === 'GET';

     var module = urlUtils.module(req.url);
<|current_version|>
'use strict';

var http = require('http');

var config = require('./lib/configLoader');
var urlUtils = require('./lib/urlUtils');
var api = require('./lib/api');

var logger = config.logger;

process.on('uncaughtException', function(err) {
  logger.error('Uncaught exception: %s', JSON.stringify(err, null, 4));
});

api.initChangesSync();

http.createServer(function(req, resp) {
  try {
    var startDate = Date.now();

    var isGet = req.method === 'GET';

    var module = urlUtils.module(req.url);
    var tarball = urlUtils.tarball(req.url);

    if (isGet && tarball) {
      api.manageAttachment(req, resp, tarball);
    } else if (isGet && module) {
      api.manageModule(req, resp, module);
    } else {
      api.proxyToCentralRepository(req, resp);
    }
  } catch (error) {
    logger.error(error);
  }
}).listen(config.port, function() {
  logger.info('Server running at http://localhost:%s with config:\n%s', config.port, JSON.stringify(config, null, 4));
});

<|next_version|>
'use strict';

var http = require('http');

var config = require('./lib/configLoader');
var urlUtils = require('./lib/urlUtils');
var api = require('./lib/api');

var logger = config.logger;

process.on('uncaughtException', function(err) {
  logger.error('Uncaught exception: %s', JSON.stringify(err, null, 4));
});

api.initChangesSync();

http.createServer(function(req, resp) {
  try {
    var startDate = Date.now();

    var isGet = req.method === 'GET';

    var module = urlUtils.module(req.url);
    var tarball = urlUtils.tarball(req.url);

    if (isGet && tarball) {
      api.manageAttachment(req, resp, tarball);
    } else if (isGet && module) {
      api.manageModule(req, resp, module);
    } else {
      api.proxyToCentralRepository(req, resp);
    }

    resp.on('finish', function() {
      logger.trace('%s: response in %sms', req.url, Date.now() - startDate);
    });
  } catch (error) {
    logger.error(error);
  }
}).listen(config.port, function() {
  logger.info('Server running at http://localhost:%s with config:\n%s', config.port, JSON.stringify(config, null, 4));
});


Add routes to get created and saved pins

--- Server/Routes/userRouter.js
+++ Server/Routes/userRouter.js
@@ -30,10 +30,12 @@
   .put(users.updateUser) //update user information

 router.route('/:userId/saved')
+  .get(users.getSavedPins)
   .post(users.createPin) //add new pin
   .delete(users.deletePin) //delete pin

 router.route('/:userId/created')
+  .get(users.getCreatedPins)
   .post(users.createSpot) //add new spot
   .delete(users.deleteSpot) //delete spot

<|original_code|>
const express = require('express')
const users = require('../Controllers/userCtrl')
const jwt = require('../Lib/jwt.js')

const router = express.Router()

const isAuthenticated = function(req, res, next) {
  const token = req.get("Authorization")

  const decoded = jwt.decode(token)

  if (typeof decoded === 'object') {
    console.log("token successfuly decoded: ", decoded)
    res.status(200)
    next()
  } else {
    console.log('ERROR, INCORRECT ACCESS TOKEN')
    res.status(400).end()
  }

}

router.use(isAuthenticated)

router.route('/')
  .post(users.createUser) //add user

router.route('/:userId')
  .get(users.getUser) //get user
  .put(users.updateUser) //update user information

router.route('/:userId/saved')
  .post(users.createPin) //add new pin
  .delete(users.deletePin) //delete pin

router.route('/:userId/created')
  .post(users.createSpot) //add new spot
  .delete(users.deleteSpot) //delete spot

module.exports = router

<|edits_diff|>
--- Server/Routes/userRouter.js
+++ Server/Routes/userRouter.js
@@ -30,6 +30,7 @@
   .put(users.updateUser) //update user information

 router.route('/:userId/saved')
+  .get(users.getSavedPins)
   .post(users.createPin) //add new pin
   .delete(users.deletePin) //delete pin

<|current_version|>
const express = require('express')
const users = require('../Controllers/userCtrl')
const jwt = require('../Lib/jwt.js')

const router = express.Router()

const isAuthenticated = function(req, res, next) {
  const token = req.get("Authorization")

  const decoded = jwt.decode(token)

  if (typeof decoded === 'object') {
    console.log("token successfuly decoded: ", decoded)
    res.status(200)
    next()
  } else {
    console.log('ERROR, INCORRECT ACCESS TOKEN')
    res.status(400).end()
  }

}

router.use(isAuthenticated)

router.route('/')
  .post(users.createUser) //add user

router.route('/:userId')
  .get(users.getUser) //get user
  .put(users.updateUser) //update user information

router.route('/:userId/saved')
  .get(users.getSavedPins)
  .post(users.createPin) //add new pin
  .delete(users.deletePin) //delete pin

router.route('/:userId/created')
  .post(users.createSpot) //add new spot
  .delete(users.deleteSpot) //delete spot

module.exports = router

<|next_version|>
const express = require('express')
const users = require('../Controllers/userCtrl')
const jwt = require('../Lib/jwt.js')

const router = express.Router()

const isAuthenticated = function(req, res, next) {
  const token = req.get("Authorization")

  const decoded = jwt.decode(token)

  if (typeof decoded === 'object') {
    console.log("token successfuly decoded: ", decoded)
    res.status(200)
    next()
  } else {
    console.log('ERROR, INCORRECT ACCESS TOKEN')
    res.status(400).end()
  }

}

router.use(isAuthenticated)

router.route('/')
  .post(users.createUser) //add user

router.route('/:userId')
  .get(users.getUser) //get user
  .put(users.updateUser) //update user information

router.route('/:userId/saved')
  .get(users.getSavedPins)
  .post(users.createPin) //add new pin
  .delete(users.deletePin) //delete pin

router.route('/:userId/created')
  .get(users.getCreatedPins)
  .post(users.createSpot) //add new spot
  .delete(users.deleteSpot) //delete spot

module.exports = router


Fix test that has conflicting globals

Fix test that has conflicting globals

--- test/feature/Syntax/ExpressionValidation.js
+++ test/feature/Syntax/ExpressionValidation.js
@@ -1,4 +1,6 @@
 'use strict';
+
+(function() {

 // test MemberLookupExpression
 function f(a) {
@@ -23,3 +25,5 @@

 a = function() { return 43; }
 assert.equal((a||b)(), 43);
+
+})();

<|original_code|>
'use strict';

// test MemberLookupExpression
function f(a) {
  var b = [42];
  return (a||b)[0];
}

assert.equal(42, f(null));
assert.equal(43, f([43]));

// test NewExpression
var a, b = function() { this.ans = 42; };
assert.equal(new (a||b)().ans, 42);

a = function() { this.ans = 43; };
assert.equal(new (a||b)().ans, 43);

// test CallExpression
a = undefined;
b = function() { return 42; }
assert.equal((a||b)(), 42);

a = function() { return 43; }
assert.equal((a||b)(), 43);

<|edits_diff|>
--- test/feature/Syntax/ExpressionValidation.js
+++ test/feature/Syntax/ExpressionValidation.js
@@ -1,4 +1,6 @@
 'use strict';
+
+(function() {

 // test MemberLookupExpression
 function f(a) {
<|current_version|>
'use strict';

(function() {

// test MemberLookupExpression
function f(a) {
  var b = [42];
  return (a||b)[0];
}

assert.equal(42, f(null));
assert.equal(43, f([43]));

// test NewExpression
var a, b = function() { this.ans = 42; };
assert.equal(new (a||b)().ans, 42);

a = function() { this.ans = 43; };
assert.equal(new (a||b)().ans, 43);

// test CallExpression
a = undefined;
b = function() { return 42; }
assert.equal((a||b)(), 42);

a = function() { return 43; }
assert.equal((a||b)(), 43);

<|next_version|>
'use strict';

(function() {

// test MemberLookupExpression
function f(a) {
  var b = [42];
  return (a||b)[0];
}

assert.equal(42, f(null));
assert.equal(43, f([43]));

// test NewExpression
var a, b = function() { this.ans = 42; };
assert.equal(new (a||b)().ans, 42);

a = function() { this.ans = 43; };
assert.equal(new (a||b)().ans, 43);

// test CallExpression
a = undefined;
b = function() { return 42; }
assert.equal((a||b)(), 42);

a = function() { return 43; }
assert.equal((a||b)(), 43);

})();


Add playlists reducer to store

Add playlists reducer to store

--- app/reducers/index.js
+++ app/reducers/index.js
@@ -1,9 +1,11 @@
 import { combineReducers } from 'redux';
 import { routerReducer as routing } from 'react-router-redux';
 import auth from './auth';
+import playlists from './user'

 const rootReducer = combineReducers({
   auth,
+  playlists,
   routing,
 });

<|original_code|>
import { combineReducers } from 'redux';
import { routerReducer as routing } from 'react-router-redux';
import auth from './auth';

const rootReducer = combineReducers({
  auth,
  routing,
});

export default rootReducer;

<|edits_diff|>
--- app/reducers/index.js
+++ app/reducers/index.js
@@ -1,6 +1,7 @@
 import { combineReducers } from 'redux';
 import { routerReducer as routing } from 'react-router-redux';
 import auth from './auth';
+import playlists from './user'

 const rootReducer = combineReducers({
   auth,
<|current_version|>
import { combineReducers } from 'redux';
import { routerReducer as routing } from 'react-router-redux';
import auth from './auth';
import playlists from './user'

const rootReducer = combineReducers({
  auth,
  routing,
});

export default rootReducer;

<|next_version|>
import { combineReducers } from 'redux';
import { routerReducer as routing } from 'react-router-redux';
import auth from './auth';
import playlists from './user'

const rootReducer = combineReducers({
  auth,
  playlists,
  routing,
});

export default rootReducer;


Disable refresh when a refresh is already in progress

--- lib/cache/addIf.js
+++ lib/cache/addIf.js
@@ -10,7 +10,10 @@
   if (item) {
     callbacks.done(item);
     if (refresh) {
+      var group = cache[type];
+      group.refresh = false;
       callbacks.add(function (element) {
+        group.refresh = true;
         add(cache, type, index, element);
       });
     }

<|original_code|>
// Includes
var add = require('./add.js');
var get = require('./get.js');

// Define
module.exports = function (cache, type, index, callbacks) {
  var got = get(cache, type, index);
  var item = got[0];
  var refresh = got[1];
  if (item) {
    callbacks.done(item);
    if (refresh) {
      callbacks.add(function (element) {
        add(cache, type, index, element);
      });
    }
  } else {
    callbacks.add(function (element) {
      add(cache, type, index, element);
      callbacks.done(element);
    });
  }
};

<|edits_diff|>
--- lib/cache/addIf.js
+++ lib/cache/addIf.js
@@ -10,6 +10,8 @@
   if (item) {
     callbacks.done(item);
     if (refresh) {
+      var group = cache[type];
+      group.refresh = false;
       callbacks.add(function (element) {
         add(cache, type, index, element);
       });
<|current_version|>
// Includes
var add = require('./add.js');
var get = require('./get.js');

// Define
module.exports = function (cache, type, index, callbacks) {
  var got = get(cache, type, index);
  var item = got[0];
  var refresh = got[1];
  if (item) {
    callbacks.done(item);
    if (refresh) {
      var group = cache[type];
      group.refresh = false;
      callbacks.add(function (element) {
        add(cache, type, index, element);
      });
    }
  } else {
    callbacks.add(function (element) {
      add(cache, type, index, element);
      callbacks.done(element);
    });
  }
};

<|next_version|>
// Includes
var add = require('./add.js');
var get = require('./get.js');

// Define
module.exports = function (cache, type, index, callbacks) {
  var got = get(cache, type, index);
  var item = got[0];
  var refresh = got[1];
  if (item) {
    callbacks.done(item);
    if (refresh) {
      var group = cache[type];
      group.refresh = false;
      callbacks.add(function (element) {
        group.refresh = true;
        add(cache, type, index, element);
      });
    }
  } else {
    callbacks.add(function (element) {
      add(cache, type, index, element);
      callbacks.done(element);
    });
  }
};


Add trace option for Sass.

Add trace option for Sass.

--- grunt/contrib-sass.js
+++ grunt/contrib-sass.js
@@ -5,6 +5,7 @@
         dev: {
             options: {
                 sourcemap: true,
+                trace: false,
                 style: 'nested',
                 precision: 5
             },
@@ -19,6 +20,7 @@
         deploy: {
             options: {
                 sourcemap: true,
+                trace: false,
                 style: 'compressed',
                 precision: 5
             },

<|original_code|>
// Compile SCSS files to CSS

module.exports = function(grunt) {
    grunt.config('sass', {
        dev: {
            options: {
                sourcemap: true,
                style: 'nested',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'styles',
                ext: '.css'
            }],
        },
        deploy: {
            options: {
                sourcemap: true,
                style: 'compressed',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'dist/styles',
                ext: '.css'
            }],
        },
    });

    grunt.loadNpmTasks('grunt-contrib-sass');
};

<|edits_diff|>
--- grunt/contrib-sass.js
+++ grunt/contrib-sass.js
@@ -5,6 +5,7 @@
         dev: {
             options: {
                 sourcemap: true,
+                trace: false,
                 style: 'nested',
                 precision: 5
             },
<|current_version|>
// Compile SCSS files to CSS

module.exports = function(grunt) {
    grunt.config('sass', {
        dev: {
            options: {
                sourcemap: true,
                trace: false,
                style: 'nested',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'styles',
                ext: '.css'
            }],
        },
        deploy: {
            options: {
                sourcemap: true,
                style: 'compressed',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'dist/styles',
                ext: '.css'
            }],
        },
    });

    grunt.loadNpmTasks('grunt-contrib-sass');
};

<|next_version|>
// Compile SCSS files to CSS

module.exports = function(grunt) {
    grunt.config('sass', {
        dev: {
            options: {
                sourcemap: true,
                trace: false,
                style: 'nested',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'styles',
                ext: '.css'
            }],
        },
        deploy: {
            options: {
                sourcemap: true,
                trace: false,
                style: 'compressed',
                precision: 5
            },
            files: [{
                expand: true,
                cwd: 'scss',
                src: ['*.scss'],
                dest: 'dist/styles',
                ext: '.css'
            }],
        },
    });

    grunt.loadNpmTasks('grunt-contrib-sass');
};


Make sure html templates are loaded by karma and preprocess them into js with html2js

--- static/karma.conf.js
+++ static/karma.conf.js
@@ -16,9 +16,16 @@
       'app/bower_components/angular-resource/angular-resource.js',
       'app/scripts/*.js',
       'app/scripts/**/*.js',
+      'app/views/*.html',
+      'app/views/directives/*.html',
       'test/mock/**/*.js',
       'test/spec/**/*.js'
     ],
+
+    preprocessors: {
+      'app/views/*.html': 'html2js',
+      'app/views/**/*.html': 'html2js'
+    },

     // list of files / patterns to exclude
     exclude: [],

<|original_code|>
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'app/bower_components/angular/angular.js',
      'app/bower_components/angular-mocks/angular-mocks.js',
      'app/bower_components/angular-resource/angular-resource.js',
      'app/scripts/*.js',
      'app/scripts/**/*.js',
      'test/mock/**/*.js',
      'test/spec/**/*.js'
    ],

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['Firefox'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};

<|edits_diff|>
--- static/karma.conf.js
+++ static/karma.conf.js
@@ -16,6 +16,8 @@
       'app/bower_components/angular-resource/angular-resource.js',
       'app/scripts/*.js',
       'app/scripts/**/*.js',
+      'app/views/*.html',
+      'app/views/directives/*.html',
       'test/mock/**/*.js',
       'test/spec/**/*.js'
     ],
<|current_version|>
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'app/bower_components/angular/angular.js',
      'app/bower_components/angular-mocks/angular-mocks.js',
      'app/bower_components/angular-resource/angular-resource.js',
      'app/scripts/*.js',
      'app/scripts/**/*.js',
      'app/views/*.html',
      'app/views/directives/*.html',
      'test/mock/**/*.js',
      'test/spec/**/*.js'
    ],

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['Firefox'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};

<|next_version|>
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'app/bower_components/angular/angular.js',
      'app/bower_components/angular-mocks/angular-mocks.js',
      'app/bower_components/angular-resource/angular-resource.js',
      'app/scripts/*.js',
      'app/scripts/**/*.js',
      'app/views/*.html',
      'app/views/directives/*.html',
      'test/mock/**/*.js',
      'test/spec/**/*.js'
    ],

    preprocessors: {
      'app/views/*.html': 'html2js',
      'app/views/**/*.html': 'html2js'
    },

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['Firefox'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};


Set votedState upon ISSUE OPEN

Set votedState upon ISSUE OPEN

--- client/src/reducers/voting.js
+++ client/src/reducers/voting.js
@@ -1,3 +1,4 @@
+import { OPEN_ISSUE } from '../../../common/actionTypes/issues';
 import { VOTING_STATE } from '../../../common/actionTypes/voting';

 const votedState = (state = false, action) => {
@@ -6,6 +7,10 @@
       return {
         voted: action.data.voted,
       };
+    case OPEN_ISSUE:
+      return {
+        voted: false,
+      };

     default:
       return state;

<|original_code|>
import { VOTING_STATE } from '../../../common/actionTypes/voting';

const votedState = (state = false, action) => {
  switch (action.type) {
    case VOTING_STATE:
      return {
        voted: action.data.voted,
      };

    default:
      return state;
  }
};

export default votedState;

<|edits_diff|>
--- client/src/reducers/voting.js
+++ client/src/reducers/voting.js
@@ -1,3 +1,4 @@
+import { OPEN_ISSUE } from '../../../common/actionTypes/issues';
 import { VOTING_STATE } from '../../../common/actionTypes/voting';

 const votedState = (state = false, action) => {
<|current_version|>
import { OPEN_ISSUE } from '../../../common/actionTypes/issues';
import { VOTING_STATE } from '../../../common/actionTypes/voting';

const votedState = (state = false, action) => {
  switch (action.type) {
    case VOTING_STATE:
      return {
        voted: action.data.voted,
      };

    default:
      return state;
  }
};

export default votedState;

<|next_version|>
import { OPEN_ISSUE } from '../../../common/actionTypes/issues';
import { VOTING_STATE } from '../../../common/actionTypes/voting';

const votedState = (state = false, action) => {
  switch (action.type) {
    case VOTING_STATE:
      return {
        voted: action.data.voted,
      };
    case OPEN_ISSUE:
      return {
        voted: false,
      };

    default:
      return state;
  }
};

export default votedState;


Update activity table to include a boolean for active or not

--- server/db/orm-model.js
+++ server/db/orm-model.js
@@ -32,6 +32,9 @@
     },
     keywords: {
       type: Sequelize.STRING
+    },
+    active: {
+      type: Sequelize.BOOLEAN
     }
     //sequelize automatically makes createdAt and updatedAt columns
   });
@@ -41,6 +44,7 @@
   Activity.belongsToMany(User, {through: 'UserActivity'});
   User.belongsToMany(Activity, {through: 'UserActivity'});

+  Activity.hasOne(User, {as:'Owner'});
   // User.sync().success(function () {
   //   console.log('User table created!');
   // });

<|original_code|>
'use strict';
var db = require('./database');
var Sequelize = require('sequelize');

module.exports = function(){
  var User = db.define('Users', {
    userId: {type: Sequelize.STRING,
      unique: true,
      notEmpty: true,
      notNull: true,
      primaryKey: true
    },
    email: Sequelize.STRING,
    picture: Sequelize.STRING,
    name: Sequelize.STRING,
    nickname: Sequelize.STRING
  });

  var Activity = db.define('Activity', {
    title: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    description: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    location: {
      type: Sequelize.STRING
    },
    keywords: {
      type: Sequelize.STRING
    }
    //sequelize automatically makes createdAt and updatedAt columns
  });

  // We don't need create a join table when we're using an ORM
  // Use a method to set relationships
  Activity.belongsToMany(User, {through: 'UserActivity'});
  User.belongsToMany(Activity, {through: 'UserActivity'});

  // User.sync().success(function () {
  //   console.log('User table created!');
  // });
  // Activity.sync().success(function () {
  //   console.log('Activity table created!');
  // });

  db.sync();
  return {User:User, Activity: Activity};
};
<|edits_diff|>
--- server/db/orm-model.js
+++ server/db/orm-model.js
@@ -32,6 +32,9 @@
     },
     keywords: {
       type: Sequelize.STRING
+    },
+    active: {
+      type: Sequelize.BOOLEAN
     }
     //sequelize automatically makes createdAt and updatedAt columns
   });
<|current_version|>
'use strict';
var db = require('./database');
var Sequelize = require('sequelize');

module.exports = function(){
  var User = db.define('Users', {
    userId: {type: Sequelize.STRING,
      unique: true,
      notEmpty: true,
      notNull: true,
      primaryKey: true
    },
    email: Sequelize.STRING,
    picture: Sequelize.STRING,
    name: Sequelize.STRING,
    nickname: Sequelize.STRING
  });

  var Activity = db.define('Activity', {
    title: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    description: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    location: {
      type: Sequelize.STRING
    },
    keywords: {
      type: Sequelize.STRING
    },
    active: {
      type: Sequelize.BOOLEAN
    }
    //sequelize automatically makes createdAt and updatedAt columns
  });

  // We don't need create a join table when we're using an ORM
  // Use a method to set relationships
  Activity.belongsToMany(User, {through: 'UserActivity'});
  User.belongsToMany(Activity, {through: 'UserActivity'});

  // User.sync().success(function () {
  //   console.log('User table created!');
  // });
  // Activity.sync().success(function () {
  //   console.log('Activity table created!');
  // });

  db.sync();
  return {User:User, Activity: Activity};
};
<|next_version|>
'use strict';
var db = require('./database');
var Sequelize = require('sequelize');

module.exports = function(){
  var User = db.define('Users', {
    userId: {type: Sequelize.STRING,
      unique: true,
      notEmpty: true,
      notNull: true,
      primaryKey: true
    },
    email: Sequelize.STRING,
    picture: Sequelize.STRING,
    name: Sequelize.STRING,
    nickname: Sequelize.STRING
  });

  var Activity = db.define('Activity', {
    title: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    description: {
      type: Sequelize.STRING,
      notEmpty: true,
      notNull: true
    },
    location: {
      type: Sequelize.STRING
    },
    keywords: {
      type: Sequelize.STRING
    },
    active: {
      type: Sequelize.BOOLEAN
    }
    //sequelize automatically makes createdAt and updatedAt columns
  });

  // We don't need create a join table when we're using an ORM
  // Use a method to set relationships
  Activity.belongsToMany(User, {through: 'UserActivity'});
  User.belongsToMany(Activity, {through: 'UserActivity'});

  Activity.hasOne(User, {as:'Owner'});
  // User.sync().success(function () {
  //   console.log('User table created!');
  // });
  // Activity.sync().success(function () {
  //   console.log('Activity table created!');
  // });

  db.sync();
  return {User:User, Activity: Activity};
};


Update test to include FactoryGuy

Update test to include FactoryGuy

--- tests/integration/components/noteworthy-and-popular-project/component-test.js
+++ tests/integration/components/noteworthy-and-popular-project/component-test.js
@@ -1,8 +1,13 @@
 import { moduleForComponent, test } from 'ember-qunit';
 import hbs from 'htmlbars-inline-precompile';
+import FactoryGuy, { manualSetup } from 'ember-data-factory-guy';

 moduleForComponent('noteworthy-and-popular-project', 'Integration | Component | noteworthy and popular project', {
     integration: true,
+
+    beforeEach() {
+        manualSetup(this.container);
+    },
 });

 test('it renders', function(assert) {

<|original_code|>
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('noteworthy-and-popular-project', 'Integration | Component | noteworthy and popular project', {
    integration: true,
});

test('it renders', function(assert) {
    this.set('project', FactoryGuy.make('node'));
    this.render(hbs`{{noteworthy-and-popular-project project=project}}`);
    assert.ok(this.$().text().trim());
});

<|edits_diff|>
--- tests/integration/components/noteworthy-and-popular-project/component-test.js
+++ tests/integration/components/noteworthy-and-popular-project/component-test.js
@@ -1,5 +1,6 @@
 import { moduleForComponent, test } from 'ember-qunit';
 import hbs from 'htmlbars-inline-precompile';
+import FactoryGuy, { manualSetup } from 'ember-data-factory-guy';

 moduleForComponent('noteworthy-and-popular-project', 'Integration | Component | noteworthy and popular project', {
     integration: true,
<|current_version|>
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import FactoryGuy, { manualSetup } from 'ember-data-factory-guy';

moduleForComponent('noteworthy-and-popular-project', 'Integration | Component | noteworthy and popular project', {
    integration: true,
});

test('it renders', function(assert) {
    this.set('project', FactoryGuy.make('node'));
    this.render(hbs`{{noteworthy-and-popular-project project=project}}`);
    assert.ok(this.$().text().trim());
});

<|next_version|>
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import FactoryGuy, { manualSetup } from 'ember-data-factory-guy';

moduleForComponent('noteworthy-and-popular-project', 'Integration | Component | noteworthy and popular project', {
    integration: true,

    beforeEach() {
        manualSetup(this.container);
    },
});

test('it renders', function(assert) {
    this.set('project', FactoryGuy.make('node'));
    this.render(hbs`{{noteworthy-and-popular-project project=project}}`);
    assert.ok(this.$().text().trim());
});


Add error listeners to socket server

Add error listeners to socket server

--- lib/WebSocketServer.js
+++ lib/WebSocketServer.js
@@ -6,6 +6,8 @@
  * @private
  */
 function _onConnection(connection) {
+  console.log('Connections is established');
+  connection.on('error', console.error.bind(console.error));
   connection.on('close', console.log.bind(console.log, 'Connection is closed -'));
 }

@@ -17,6 +19,7 @@
 function WebSocketServer(port) {
   this._setServer(ws.createServer().listen(port));
   this._getServer().on('connection', _onConnection);
+  this._getServer().on('error', console.error.bind(console.error));
 }

 /**

<|original_code|>
var ws = require('nodejs-websocket');

/**
 * Triggers when connections is established
 * @param connection
 * @private
 */
function _onConnection(connection) {
  connection.on('close', console.log.bind(console.log, 'Connection is closed -'));
}

/**
 * Returns Server
 * @param {String} port
 * @returns {Object}
 */
function WebSocketServer(port) {
  this._setServer(ws.createServer().listen(port));
  this._getServer().on('connection', _onConnection);
}

/**
 * Get native server
 * @returns {*}
 * @private
 */
WebSocketServer.prototype._getServer = function () {
  return this._server;
};

/**
 * Set new native server
 * @param server
 * @returns {WebSocketServer}
 * @private
 */
WebSocketServer.prototype._setServer = function (server) {
  this._server = server;
  return this;
};

/**
 * Send message to all connections
 * @param {*} data
 * @returns {WebSocketServer}
 */
WebSocketServer.prototype.send = function (data) {
  this._getServer().connections.forEach(function (connection) {
    connection.sendText(JSON.stringify(data));
  });

  return this;
};

module.exports = WebSocketServer;

<|edits_diff|>
--- lib/WebSocketServer.js
+++ lib/WebSocketServer.js
@@ -6,6 +6,8 @@
  * @private
  */
 function _onConnection(connection) {
+  console.log('Connections is established');
+  connection.on('error', console.error.bind(console.error));
   connection.on('close', console.log.bind(console.log, 'Connection is closed -'));
 }

<|current_version|>
var ws = require('nodejs-websocket');

/**
 * Triggers when connections is established
 * @param connection
 * @private
 */
function _onConnection(connection) {
  console.log('Connections is established');
  connection.on('error', console.error.bind(console.error));
  connection.on('close', console.log.bind(console.log, 'Connection is closed -'));
}

/**
 * Returns Server
 * @param {String} port
 * @returns {Object}
 */
function WebSocketServer(port) {
  this._setServer(ws.createServer().listen(port));
  this._getServer().on('connection', _onConnection);
}

/**
 * Get native server
 * @returns {*}
 * @private
 */
WebSocketServer.prototype._getServer = function () {
  return this._server;
};

/**
 * Set new native server
 * @param server
 * @returns {WebSocketServer}
 * @private
 */
WebSocketServer.prototype._setServer = function (server) {
  this._server = server;
  return this;
};

/**
 * Send message to all connections
 * @param {*} data
 * @returns {WebSocketServer}
 */
WebSocketServer.prototype.send = function (data) {
  this._getServer().connections.forEach(function (connection) {
    connection.sendText(JSON.stringify(data));
  });

  return this;
};

module.exports = WebSocketServer;

<|next_version|>
var ws = require('nodejs-websocket');

/**
 * Triggers when connections is established
 * @param connection
 * @private
 */
function _onConnection(connection) {
  console.log('Connections is established');
  connection.on('error', console.error.bind(console.error));
  connection.on('close', console.log.bind(console.log, 'Connection is closed -'));
}

/**
 * Returns Server
 * @param {String} port
 * @returns {Object}
 */
function WebSocketServer(port) {
  this._setServer(ws.createServer().listen(port));
  this._getServer().on('connection', _onConnection);
  this._getServer().on('error', console.error.bind(console.error));
}

/**
 * Get native server
 * @returns {*}
 * @private
 */
WebSocketServer.prototype._getServer = function () {
  return this._server;
};

/**
 * Set new native server
 * @param server
 * @returns {WebSocketServer}
 * @private
 */
WebSocketServer.prototype._setServer = function (server) {
  this._server = server;
  return this;
};

/**
 * Send message to all connections
 * @param {*} data
 * @returns {WebSocketServer}
 */
WebSocketServer.prototype.send = function (data) {
  this._getServer().connections.forEach(function (connection) {
    connection.sendText(JSON.stringify(data));
  });

  return this;
};

module.exports = WebSocketServer;


Add signUp action reducer to root reducer

--- client/reducers/index.js
+++ client/reducers/index.js
@@ -1,9 +1,11 @@
 import { combineReducers } from 'redux';
 import { routerReducer } from 'react-router-redux';
 import { reducer as formReducer } from 'redux-form';
+import auth from './userSignUp';

 const rootReducer = combineReducers({
     form: formReducer,
+    auth,
     routing: routerReducer
 });

<|original_code|>
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
    form: formReducer,
    routing: routerReducer
});

export default rootReducer;
<|edits_diff|>
--- client/reducers/index.js
+++ client/reducers/index.js
@@ -1,6 +1,7 @@
 import { combineReducers } from 'redux';
 import { routerReducer } from 'react-router-redux';
 import { reducer as formReducer } from 'redux-form';
+import auth from './userSignUp';

 const rootReducer = combineReducers({
     form: formReducer,
<|current_version|>
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import { reducer as formReducer } from 'redux-form';
import auth from './userSignUp';

const rootReducer = combineReducers({
    form: formReducer,
    routing: routerReducer
});

export default rootReducer;
<|next_version|>
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import { reducer as formReducer } from 'redux-form';
import auth from './userSignUp';

const rootReducer = combineReducers({
    form: formReducer,
    auth,
    routing: routerReducer
});

export default rootReducer;


Test that null values are also stored

Test that null values are also stored

--- test/index.js
+++ test/index.js
@@ -7,6 +7,7 @@
     almacen.local.set("boolean", true);
     almacen.local.set("array", [1,2,3,4,5,6]);
     almacen.local.set("object", { "foo": "bar" });
+    almacen.local.set("null", null);

     expect(almacen.local.has("date")).to.equal(false);
     expect(almacen.local.has("string")).to.equal(true);
@@ -14,12 +15,14 @@
     expect(almacen.local.has("boolean")).to.equal(true);
     expect(almacen.local.has("array")).to.equal(true);
     expect(almacen.local.has("object")).to.equal(true);
+    expect(almacen.local.has("null")).to.equal(true);

     expect(almacen.local.get("string")).to.equal("hello");
     expect(almacen.local.get("number")).to.equal(23);
     expect(almacen.local.get("boolean")).to.equal(true);
     expect(almacen.local.get("array")).to.have.property("length").to.equal(6);
     expect(almacen.local.get("object")).to.have.property("foo").to.equal("bar");
+    expect(almacen.local.get("null")).to.be.null;

   });

<|original_code|>
describe("Almacen", function() {

  it("should set data in the localStorage", function() {

    almacen.local.set("string", "hello");
    almacen.local.set("number", 23);
    almacen.local.set("boolean", true);
    almacen.local.set("array", [1,2,3,4,5,6]);
    almacen.local.set("object", { "foo": "bar" });

    expect(almacen.local.has("date")).to.equal(false);
    expect(almacen.local.has("string")).to.equal(true);
    expect(almacen.local.has("number")).to.equal(true);
    expect(almacen.local.has("boolean")).to.equal(true);
    expect(almacen.local.has("array")).to.equal(true);
    expect(almacen.local.has("object")).to.equal(true);

    expect(almacen.local.get("string")).to.equal("hello");
    expect(almacen.local.get("number")).to.equal(23);
    expect(almacen.local.get("boolean")).to.equal(true);
    expect(almacen.local.get("array")).to.have.property("length").to.equal(6);
    expect(almacen.local.get("object")).to.have.property("foo").to.equal("bar");

  });

});

<|edits_diff|>
--- test/index.js
+++ test/index.js
@@ -7,6 +7,7 @@
     almacen.local.set("boolean", true);
     almacen.local.set("array", [1,2,3,4,5,6]);
     almacen.local.set("object", { "foo": "bar" });
+    almacen.local.set("null", null);

     expect(almacen.local.has("date")).to.equal(false);
     expect(almacen.local.has("string")).to.equal(true);
@@ -14,6 +15,7 @@
     expect(almacen.local.has("boolean")).to.equal(true);
     expect(almacen.local.has("array")).to.equal(true);
     expect(almacen.local.has("object")).to.equal(true);
+    expect(almacen.local.has("null")).to.equal(true);

     expect(almacen.local.get("string")).to.equal("hello");
     expect(almacen.local.get("number")).to.equal(23);
<|current_version|>
describe("Almacen", function() {

  it("should set data in the localStorage", function() {

    almacen.local.set("string", "hello");
    almacen.local.set("number", 23);
    almacen.local.set("boolean", true);
    almacen.local.set("array", [1,2,3,4,5,6]);
    almacen.local.set("object", { "foo": "bar" });
    almacen.local.set("null", null);

    expect(almacen.local.has("date")).to.equal(false);
    expect(almacen.local.has("string")).to.equal(true);
    expect(almacen.local.has("number")).to.equal(true);
    expect(almacen.local.has("boolean")).to.equal(true);
    expect(almacen.local.has("array")).to.equal(true);
    expect(almacen.local.has("object")).to.equal(true);
    expect(almacen.local.has("null")).to.equal(true);

    expect(almacen.local.get("string")).to.equal("hello");
    expect(almacen.local.get("number")).to.equal(23);
    expect(almacen.local.get("boolean")).to.equal(true);
    expect(almacen.local.get("array")).to.have.property("length").to.equal(6);
    expect(almacen.local.get("object")).to.have.property("foo").to.equal("bar");

  });

});

<|next_version|>
describe("Almacen", function() {

  it("should set data in the localStorage", function() {

    almacen.local.set("string", "hello");
    almacen.local.set("number", 23);
    almacen.local.set("boolean", true);
    almacen.local.set("array", [1,2,3,4,5,6]);
    almacen.local.set("object", { "foo": "bar" });
    almacen.local.set("null", null);

    expect(almacen.local.has("date")).to.equal(false);
    expect(almacen.local.has("string")).to.equal(true);
    expect(almacen.local.has("number")).to.equal(true);
    expect(almacen.local.has("boolean")).to.equal(true);
    expect(almacen.local.has("array")).to.equal(true);
    expect(almacen.local.has("object")).to.equal(true);
    expect(almacen.local.has("null")).to.equal(true);

    expect(almacen.local.get("string")).to.equal("hello");
    expect(almacen.local.get("number")).to.equal(23);
    expect(almacen.local.get("boolean")).to.equal(true);
    expect(almacen.local.get("array")).to.have.property("length").to.equal(6);
    expect(almacen.local.get("object")).to.have.property("foo").to.equal("bar");
    expect(almacen.local.get("null")).to.be.null;

  });

});


Allow app to run standalone with internal python webserver

--- main.js
+++ main.js
@@ -20,6 +20,8 @@
 // This method will be called when Electron has finished
 // initialization and is ready to create browser windows.
 app.on('ready', function() {
+  var pythonServer = require('child_process').spawn('python', ['-m', 'SimpleHTTPServer', '3000']);
+
   // Create the browser window.
   mainWindow = new BrowserWindow({width: 800, height: 600, 'web-preferences': {'web-security': false}});
   // and load the index.html of the app.
@@ -34,5 +36,6 @@
     // in an array if your app supports multi windows, this is the time
     // when you should delete the corresponding element.
     mainWindow = null;
+    pythonServer.kill('SIGINT');
   });
 });

<|original_code|>
var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600, 'web-preferences': {'web-security': false}});
  // and load the index.html of the app.
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});

<|edits_diff|>
--- main.js
+++ main.js
@@ -20,6 +20,8 @@
 // This method will be called when Electron has finished
 // initialization and is ready to create browser windows.
 app.on('ready', function() {
+  var pythonServer = require('child_process').spawn('python', ['-m', 'SimpleHTTPServer', '3000']);
+
   // Create the browser window.
   mainWindow = new BrowserWindow({width: 800, height: 600, 'web-preferences': {'web-security': false}});
   // and load the index.html of the app.
<|current_version|>
var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  var pythonServer = require('child_process').spawn('python', ['-m', 'SimpleHTTPServer', '3000']);

  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600, 'web-preferences': {'web-security': false}});
  // and load the index.html of the app.
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});

<|next_version|>
var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  var pythonServer = require('child_process').spawn('python', ['-m', 'SimpleHTTPServer', '3000']);

  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600, 'web-preferences': {'web-security': false}});
  // and load the index.html of the app.
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
    pythonServer.kill('SIGINT');
  });
});


Remove empty object-ids from table-wrap.

--- src/converter/r2t/ConvertTableWrap.js
+++ src/converter/r2t/ConvertTableWrap.js
@@ -4,6 +4,7 @@
   expandCaption,
   expandTitle,
   expandObjectId,
+  removeEmptyElements,
   removeChild,
   addLabel
 } from './r2tHelpers'
@@ -28,6 +29,7 @@
       let label = tableWrapNode.state.label
       addLabel(tableWrap, label, 1)
       wrapCaptionTitle(tableWrap)
+      removeEmptyElements(tableWrap, 'object-id')
     })
   }
 }

<|original_code|>
import {
  extractCaptionTitle,
  wrapCaptionTitle,
  expandCaption,
  expandTitle,
  expandObjectId,
  removeChild,
  addLabel
} from './r2tHelpers'

export default class ConvertElementCitation {

  import(dom) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      removeChild(tableWrap, 'label')
      expandObjectId(tableWrap, 0)
      extractCaptionTitle(tableWrap, 1)
      expandTitle(tableWrap, 1)
      expandCaption(tableWrap, 2)
    })
  }

  export(dom, {doc}) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      let tableWrapNode = doc.get(tableWrap.id)
      let label = tableWrapNode.state.label
      addLabel(tableWrap, label, 1)
      wrapCaptionTitle(tableWrap)
    })
  }
}

<|edits_diff|>
--- src/converter/r2t/ConvertTableWrap.js
+++ src/converter/r2t/ConvertTableWrap.js
@@ -4,6 +4,7 @@
   expandCaption,
   expandTitle,
   expandObjectId,
+  removeEmptyElements,
   removeChild,
   addLabel
 } from './r2tHelpers'
<|current_version|>
import {
  extractCaptionTitle,
  wrapCaptionTitle,
  expandCaption,
  expandTitle,
  expandObjectId,
  removeEmptyElements,
  removeChild,
  addLabel
} from './r2tHelpers'

export default class ConvertElementCitation {

  import(dom) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      removeChild(tableWrap, 'label')
      expandObjectId(tableWrap, 0)
      extractCaptionTitle(tableWrap, 1)
      expandTitle(tableWrap, 1)
      expandCaption(tableWrap, 2)
    })
  }

  export(dom, {doc}) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      let tableWrapNode = doc.get(tableWrap.id)
      let label = tableWrapNode.state.label
      addLabel(tableWrap, label, 1)
      wrapCaptionTitle(tableWrap)
    })
  }
}

<|next_version|>
import {
  extractCaptionTitle,
  wrapCaptionTitle,
  expandCaption,
  expandTitle,
  expandObjectId,
  removeEmptyElements,
  removeChild,
  addLabel
} from './r2tHelpers'

export default class ConvertElementCitation {

  import(dom) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      removeChild(tableWrap, 'label')
      expandObjectId(tableWrap, 0)
      extractCaptionTitle(tableWrap, 1)
      expandTitle(tableWrap, 1)
      expandCaption(tableWrap, 2)
    })
  }

  export(dom, {doc}) {
    let tableWrap = dom.findAll('table-wrap')
    tableWrap.forEach(tableWrap => {
      let tableWrapNode = doc.get(tableWrap.id)
      let label = tableWrapNode.state.label
      addLabel(tableWrap, label, 1)
      wrapCaptionTitle(tableWrap)
      removeEmptyElements(tableWrap, 'object-id')
    })
  }
}


Reposition the graph while printing

Reposition the graph while printing

Related to
https://github.com/gaearon/redux-devtools/issues/318#issuecomment-254039
542

--- src/app/components/buttons/PrintButton.js
+++ src/app/components/buttons/PrintButton.js
@@ -19,9 +19,16 @@
     const box = d3svg.getBBox();
     d3svg.style.height = box.height;
     d3svg.style.width = box.width;
+
+    const g = d3svg.firstChild;
+    const initTransform = g.getAttribute('transform');
+    g.setAttribute('transform', initTransform.replace(/.+scale\(/, 'translate(57, 10) scale('));
+
     window.print();
+
     d3svg.style.height = initHeight;
     d3svg.style.width = initWidth;
+    g.setAttribute('transform', initTransform);
   }

   render() {

<|original_code|>
import React, { Component, PropTypes } from 'react';
import PrintIcon from 'react-icons/lib/md/print';
import Button from '../Button';

export default class PrintButton extends Component {
  shouldComponentUpdate() {
    return false;
  }

  handlePrint() {
    const d3svg = document.getElementById('d3svg');
    if (!d3svg) {
      window.print();
      return;
    }

    const initHeight = d3svg.style.height;
    const initWidth = d3svg.style.width;
    const box = d3svg.getBBox();
    d3svg.style.height = box.height;
    d3svg.style.width = box.width;
    window.print();
    d3svg.style.height = initHeight;
    d3svg.style.width = initWidth;
  }

  render() {
    return (
      <Button Icon={PrintIcon} onClick={this.handlePrint}>Print</Button>
    );
  }
}

<|edits_diff|>
--- src/app/components/buttons/PrintButton.js
+++ src/app/components/buttons/PrintButton.js
@@ -19,7 +19,13 @@
     const box = d3svg.getBBox();
     d3svg.style.height = box.height;
     d3svg.style.width = box.width;
+
+    const g = d3svg.firstChild;
+    const initTransform = g.getAttribute('transform');
+    g.setAttribute('transform', initTransform.replace(/.+scale\(/, 'translate(57, 10) scale('));
+
     window.print();
+
     d3svg.style.height = initHeight;
     d3svg.style.width = initWidth;
   }
<|current_version|>
import React, { Component, PropTypes } from 'react';
import PrintIcon from 'react-icons/lib/md/print';
import Button from '../Button';

export default class PrintButton extends Component {
  shouldComponentUpdate() {
    return false;
  }

  handlePrint() {
    const d3svg = document.getElementById('d3svg');
    if (!d3svg) {
      window.print();
      return;
    }

    const initHeight = d3svg.style.height;
    const initWidth = d3svg.style.width;
    const box = d3svg.getBBox();
    d3svg.style.height = box.height;
    d3svg.style.width = box.width;

    const g = d3svg.firstChild;
    const initTransform = g.getAttribute('transform');
    g.setAttribute('transform', initTransform.replace(/.+scale\(/, 'translate(57, 10) scale('));

    window.print();

    d3svg.style.height = initHeight;
    d3svg.style.width = initWidth;
  }

  render() {
    return (
      <Button Icon={PrintIcon} onClick={this.handlePrint}>Print</Button>
    );
  }
}

<|next_version|>
import React, { Component, PropTypes } from 'react';
import PrintIcon from 'react-icons/lib/md/print';
import Button from '../Button';

export default class PrintButton extends Component {
  shouldComponentUpdate() {
    return false;
  }

  handlePrint() {
    const d3svg = document.getElementById('d3svg');
    if (!d3svg) {
      window.print();
      return;
    }

    const initHeight = d3svg.style.height;
    const initWidth = d3svg.style.width;
    const box = d3svg.getBBox();
    d3svg.style.height = box.height;
    d3svg.style.width = box.width;

    const g = d3svg.firstChild;
    const initTransform = g.getAttribute('transform');
    g.setAttribute('transform', initTransform.replace(/.+scale\(/, 'translate(57, 10) scale('));

    window.print();

    d3svg.style.height = initHeight;
    d3svg.style.width = initWidth;
    g.setAttribute('transform', initTransform);
  }

  render() {
    return (
      <Button Icon={PrintIcon} onClick={this.handlePrint}>Print</Button>
    );
  }
}


Add finalise action handling in pages reducer

--- src/reducers/PagesReducer.js
+++ src/reducers/PagesReducer.js
@@ -5,6 +5,7 @@

 import { DataTablePageReducer } from '../pages/dataTableUtilities/reducer/DataTablePageReducer';
 import getPageInitialiser from '../pages/dataTableUtilities/getPageInitialiser';
+import { FINALISE_ACTIONS } from '../actions/FinaliseActions';

 /**
  * Redux reducer controlling the `pages` field.
@@ -20,6 +21,11 @@
       const { prevRouteName } = payload || {};
       return { ...state, currentRoute: prevRouteName };
     }
+
+    case FINALISE_ACTIONS.CONFIRM_FINALISE: {
+      return { ...state };
+    }
+
     case 'Navigation/REPLACE':
     case 'Navigation/NAVIGATE': {
       const { routeName, params } = action;
@@ -30,6 +36,7 @@

       return { ...state, [routeName]: pageInitialState, currentRoute: routeName };
     }
+
     default: {
       const { payload } = action;
       const { route } = payload || {};

<|original_code|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { DataTablePageReducer } from '../pages/dataTableUtilities/reducer/DataTablePageReducer';
import getPageInitialiser from '../pages/dataTableUtilities/getPageInitialiser';

/**
 * Redux reducer controlling the `pages` field.
 * @param {Object} state  Redux state, `pages` field.
 * @param {Object} action An action object, following the FSA-standard for action objects
 */
export const PagesReducer = (state = {}, action) => {
  const { type } = action;

  switch (type) {
    case 'Navigation/BACK': {
      const { payload } = action;
      const { prevRouteName } = payload || {};
      return { ...state, currentRoute: prevRouteName };
    }
    case 'Navigation/REPLACE':
    case 'Navigation/NAVIGATE': {
      const { routeName, params } = action;
      const { pageObject } = params;

      const pageInitialiser = getPageInitialiser(routeName);
      const pageInitialState = pageInitialiser?.(pageObject);

      return { ...state, [routeName]: pageInitialState, currentRoute: routeName };
    }
    default: {
      const { payload } = action;
      const { route } = payload || {};

      const newState = route
        ? { ...state, [route]: DataTablePageReducer(state[route], action) }
        : state;
      return newState;
    }
  }
};

<|edits_diff|>
--- src/reducers/PagesReducer.js
+++ src/reducers/PagesReducer.js
@@ -5,6 +5,7 @@

 import { DataTablePageReducer } from '../pages/dataTableUtilities/reducer/DataTablePageReducer';
 import getPageInitialiser from '../pages/dataTableUtilities/getPageInitialiser';
+import { FINALISE_ACTIONS } from '../actions/FinaliseActions';

 /**
  * Redux reducer controlling the `pages` field.
@@ -20,6 +21,11 @@
       const { prevRouteName } = payload || {};
       return { ...state, currentRoute: prevRouteName };
     }
+
+    case FINALISE_ACTIONS.CONFIRM_FINALISE: {
+      return { ...state };
+    }
+
     case 'Navigation/REPLACE':
     case 'Navigation/NAVIGATE': {
       const { routeName, params } = action;
<|current_version|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { DataTablePageReducer } from '../pages/dataTableUtilities/reducer/DataTablePageReducer';
import getPageInitialiser from '../pages/dataTableUtilities/getPageInitialiser';
import { FINALISE_ACTIONS } from '../actions/FinaliseActions';

/**
 * Redux reducer controlling the `pages` field.
 * @param {Object} state  Redux state, `pages` field.
 * @param {Object} action An action object, following the FSA-standard for action objects
 */
export const PagesReducer = (state = {}, action) => {
  const { type } = action;

  switch (type) {
    case 'Navigation/BACK': {
      const { payload } = action;
      const { prevRouteName } = payload || {};
      return { ...state, currentRoute: prevRouteName };
    }

    case FINALISE_ACTIONS.CONFIRM_FINALISE: {
      return { ...state };
    }

    case 'Navigation/REPLACE':
    case 'Navigation/NAVIGATE': {
      const { routeName, params } = action;
      const { pageObject } = params;

      const pageInitialiser = getPageInitialiser(routeName);
      const pageInitialState = pageInitialiser?.(pageObject);

      return { ...state, [routeName]: pageInitialState, currentRoute: routeName };
    }
    default: {
      const { payload } = action;
      const { route } = payload || {};

      const newState = route
        ? { ...state, [route]: DataTablePageReducer(state[route], action) }
        : state;
      return newState;
    }
  }
};

<|next_version|>
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { DataTablePageReducer } from '../pages/dataTableUtilities/reducer/DataTablePageReducer';
import getPageInitialiser from '../pages/dataTableUtilities/getPageInitialiser';
import { FINALISE_ACTIONS } from '../actions/FinaliseActions';

/**
 * Redux reducer controlling the `pages` field.
 * @param {Object} state  Redux state, `pages` field.
 * @param {Object} action An action object, following the FSA-standard for action objects
 */
export const PagesReducer = (state = {}, action) => {
  const { type } = action;

  switch (type) {
    case 'Navigation/BACK': {
      const { payload } = action;
      const { prevRouteName } = payload || {};
      return { ...state, currentRoute: prevRouteName };
    }

    case FINALISE_ACTIONS.CONFIRM_FINALISE: {
      return { ...state };
    }

    case 'Navigation/REPLACE':
    case 'Navigation/NAVIGATE': {
      const { routeName, params } = action;
      const { pageObject } = params;

      const pageInitialiser = getPageInitialiser(routeName);
      const pageInitialState = pageInitialiser?.(pageObject);

      return { ...state, [routeName]: pageInitialState, currentRoute: routeName };
    }

    default: {
      const { payload } = action;
      const { route } = payload || {};

      const newState = route
        ? { ...state, [route]: DataTablePageReducer(state[route], action) }
        : state;
      return newState;
    }
  }
};


Set subcomponent display names for proper documentation

--- src/components/overviewPage/OverviewPage.js
+++ src/components/overviewPage/OverviewPage.js
@@ -17,6 +17,8 @@
 };

 OverviewPage.Body = OverviewPageBody;
+OverviewPage.Body.displayName = 'OverviewPage.Body';
 OverviewPage.Header = OverviewPageHeader;
+OverviewPage.Header.displayName = 'OverviewPage.Header';

 export default OverviewPage;

<|original_code|>
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import OverviewPageBody from './OverviewPageBody';
import OverviewPageHeader from './OverviewPageHeader';
import Box from '../box';

class OverviewPage extends PureComponent {
  render() {
    const { children, className, ...others } = this.props;

    return <Box {...others}>{children}</Box>;
  }
}

OverviewPage.propTypes = {
  children: PropTypes.node.isRequired,
};

OverviewPage.Body = OverviewPageBody;
OverviewPage.Header = OverviewPageHeader;

export default OverviewPage;

<|edits_diff|>
--- src/components/overviewPage/OverviewPage.js
+++ src/components/overviewPage/OverviewPage.js
@@ -17,6 +17,7 @@
 };

 OverviewPage.Body = OverviewPageBody;
+OverviewPage.Body.displayName = 'OverviewPage.Body';
 OverviewPage.Header = OverviewPageHeader;

 export default OverviewPage;
<|current_version|>
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import OverviewPageBody from './OverviewPageBody';
import OverviewPageHeader from './OverviewPageHeader';
import Box from '../box';

class OverviewPage extends PureComponent {
  render() {
    const { children, className, ...others } = this.props;

    return <Box {...others}>{children}</Box>;
  }
}

OverviewPage.propTypes = {
  children: PropTypes.node.isRequired,
};

OverviewPage.Body = OverviewPageBody;
OverviewPage.Body.displayName = 'OverviewPage.Body';
OverviewPage.Header = OverviewPageHeader;

export default OverviewPage;

<|next_version|>
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import OverviewPageBody from './OverviewPageBody';
import OverviewPageHeader from './OverviewPageHeader';
import Box from '../box';

class OverviewPage extends PureComponent {
  render() {
    const { children, className, ...others } = this.props;

    return <Box {...others}>{children}</Box>;
  }
}

OverviewPage.propTypes = {
  children: PropTypes.node.isRequired,
};

OverviewPage.Body = OverviewPageBody;
OverviewPage.Body.displayName = 'OverviewPage.Body';
OverviewPage.Header = OverviewPageHeader;
OverviewPage.Header.displayName = 'OverviewPage.Header';

export default OverviewPage;


Add test to check length of domains array matches num_domains

--- test/collect.js
+++ test/collect.js
@@ -6,6 +6,7 @@
       test.ifError(err);
       test.ok(stats && typeof stats === 'object');
       test.ok(stats.num_domains >= 1);
+      test.ok(stats.domains && stats.domains.length === stats.num_domains);
       test.strictEqual(Object.keys(stats).length, 8);
       test.done();
     });
@@ -15,6 +16,7 @@
     var stats = xenstat.collectSync();
     test.ok(stats && typeof stats === 'object');
     test.ok(stats.num_domains >= 1);
+    test.ok(stats.domains && stats.domains.length === stats.num_domains);
     test.strictEqual(Object.keys(stats).length, 8);
     test.done();
   },

<|original_code|>
var xenstat = require('../build/Release/xenstat.node');

module.exports = {
  'Collect asynchronous': function(test) {
    xenstat.collect(function(err, stats) {
      test.ifError(err);
      test.ok(stats && typeof stats === 'object');
      test.ok(stats.num_domains >= 1);
      test.strictEqual(Object.keys(stats).length, 8);
      test.done();
    });
  },

  'Collect synchronous': function(test) {
    var stats = xenstat.collectSync();
    test.ok(stats && typeof stats === 'object');
    test.ok(stats.num_domains >= 1);
    test.strictEqual(Object.keys(stats).length, 8);
    test.done();
  },
};

<|edits_diff|>
--- test/collect.js
+++ test/collect.js
@@ -6,6 +6,7 @@
       test.ifError(err);
       test.ok(stats && typeof stats === 'object');
       test.ok(stats.num_domains >= 1);
+      test.ok(stats.domains && stats.domains.length === stats.num_domains);
       test.strictEqual(Object.keys(stats).length, 8);
       test.done();
     });
<|current_version|>
var xenstat = require('../build/Release/xenstat.node');

module.exports = {
  'Collect asynchronous': function(test) {
    xenstat.collect(function(err, stats) {
      test.ifError(err);
      test.ok(stats && typeof stats === 'object');
      test.ok(stats.num_domains >= 1);
      test.ok(stats.domains && stats.domains.length === stats.num_domains);
      test.strictEqual(Object.keys(stats).length, 8);
      test.done();
    });
  },

  'Collect synchronous': function(test) {
    var stats = xenstat.collectSync();
    test.ok(stats && typeof stats === 'object');
    test.ok(stats.num_domains >= 1);
    test.strictEqual(Object.keys(stats).length, 8);
    test.done();
  },
};

<|next_version|>
var xenstat = require('../build/Release/xenstat.node');

module.exports = {
  'Collect asynchronous': function(test) {
    xenstat.collect(function(err, stats) {
      test.ifError(err);
      test.ok(stats && typeof stats === 'object');
      test.ok(stats.num_domains >= 1);
      test.ok(stats.domains && stats.domains.length === stats.num_domains);
      test.strictEqual(Object.keys(stats).length, 8);
      test.done();
    });
  },

  'Collect synchronous': function(test) {
    var stats = xenstat.collectSync();
    test.ok(stats && typeof stats === 'object');
    test.ok(stats.num_domains >= 1);
    test.ok(stats.domains && stats.domains.length === stats.num_domains);
    test.strictEqual(Object.keys(stats).length, 8);
    test.done();
  },
};


Revert "Remove unnecessary lock logging"

This reverts commit ffce61611933786a9f01d01925fc154f6a7f1ecd.

--- blogic/PartitionLockManager.js
+++ blogic/PartitionLockManager.js
@@ -28,8 +28,10 @@

   if (keyLock != null) {
      keyLock.timedLock(timeoutSeconds * 1000, function (error) {
+       console.log("Locked partition " + keyStr);
        callback();
        keyLock.unlock();
+       console.log("Unlocked partition " + keyStr);
      });
   }
 };

<|original_code|>
var locks = require('locks');

//Map lock only used to create new partitionLocks entries
var mapLock = locks.createMutex();
var partitionLocks = new Object();
var timeoutSeconds = 2;

//key is unique for the namespace & partition.
module.exports.lockedOperation = function lockedOperation (key, callback) {
	var keyStr = JSON.stringify(key);
    var keyLock = partitionLocks[keyStr];

    // If lock does not exist - acquire the map lock and create new lock for this key
  if (keyLock == null) {
      mapLock.timedLock(timeoutSeconds * 1000, function (error) {
        if (error) {
            console.log('Could not get the partition map mutex lock within ' + timeoutSeconds + ' seconds, so gave up');
        } else {
            if (keyLock == null) {
                 keyLock = locks.createMutex();
                 partitionLocks[keyStr] = keyLock;
                 console.log("Created partition lock object for " + keyStr);
                 mapLock.unlock();
              }
        }
       });
  }

  if (keyLock != null) {
     keyLock.timedLock(timeoutSeconds * 1000, function (error) {
       callback();
       keyLock.unlock();
     });
  }
};

<|edits_diff|>
--- blogic/PartitionLockManager.js
+++ blogic/PartitionLockManager.js
@@ -28,6 +28,7 @@

   if (keyLock != null) {
      keyLock.timedLock(timeoutSeconds * 1000, function (error) {
+       console.log("Locked partition " + keyStr);
        callback();
        keyLock.unlock();
      });
<|current_version|>
var locks = require('locks');

//Map lock only used to create new partitionLocks entries
var mapLock = locks.createMutex();
var partitionLocks = new Object();
var timeoutSeconds = 2;

//key is unique for the namespace & partition.
module.exports.lockedOperation = function lockedOperation (key, callback) {
	var keyStr = JSON.stringify(key);
    var keyLock = partitionLocks[keyStr];

    // If lock does not exist - acquire the map lock and create new lock for this key
  if (keyLock == null) {
      mapLock.timedLock(timeoutSeconds * 1000, function (error) {
        if (error) {
            console.log('Could not get the partition map mutex lock within ' + timeoutSeconds + ' seconds, so gave up');
        } else {
            if (keyLock == null) {
                 keyLock = locks.createMutex();
                 partitionLocks[keyStr] = keyLock;
                 console.log("Created partition lock object for " + keyStr);
                 mapLock.unlock();
              }
        }
       });
  }

  if (keyLock != null) {
     keyLock.timedLock(timeoutSeconds * 1000, function (error) {
       console.log("Locked partition " + keyStr);
       callback();
       keyLock.unlock();
     });
  }
};

<|next_version|>
var locks = require('locks');

//Map lock only used to create new partitionLocks entries
var mapLock = locks.createMutex();
var partitionLocks = new Object();
var timeoutSeconds = 2;

//key is unique for the namespace & partition.
module.exports.lockedOperation = function lockedOperation (key, callback) {
	var keyStr = JSON.stringify(key);
    var keyLock = partitionLocks[keyStr];

    // If lock does not exist - acquire the map lock and create new lock for this key
  if (keyLock == null) {
      mapLock.timedLock(timeoutSeconds * 1000, function (error) {
        if (error) {
            console.log('Could not get the partition map mutex lock within ' + timeoutSeconds + ' seconds, so gave up');
        } else {
            if (keyLock == null) {
                 keyLock = locks.createMutex();
                 partitionLocks[keyStr] = keyLock;
                 console.log("Created partition lock object for " + keyStr);
                 mapLock.unlock();
              }
        }
       });
  }

  if (keyLock != null) {
     keyLock.timedLock(timeoutSeconds * 1000, function (error) {
       console.log("Locked partition " + keyStr);
       callback();
       keyLock.unlock();
       console.log("Unlocked partition " + keyStr);
     });
  }
};


Add validation to check the country code to be replaced

--- src/replace_country_code.js
+++ src/replace_country_code.js
@@ -4,6 +4,11 @@
   number,
 ) {
   const dialCodeRegex = RegExp(`^(${currentSelectedCountry.dialCode})`)
+  const codeToBeReplaced = number.match(dialCodeRegex)
   const newNumber = number.replace(dialCodeRegex, nextSelectedCountry.dialCode)
+
+  if (codeToBeReplaced === null && newNumber === number) {
+    return nextSelectedCountry.dialCode + number
+  }
   return newNumber
 }

<|original_code|>
export default function replaceCountryCode(
  currentSelectedCountry,
  nextSelectedCountry,
  number,
) {
  const dialCodeRegex = RegExp(`^(${currentSelectedCountry.dialCode})`)
  const newNumber = number.replace(dialCodeRegex, nextSelectedCountry.dialCode)
  return newNumber
}

<|edits_diff|>
--- src/replace_country_code.js
+++ src/replace_country_code.js
@@ -4,6 +4,7 @@
   number,
 ) {
   const dialCodeRegex = RegExp(`^(${currentSelectedCountry.dialCode})`)
+  const codeToBeReplaced = number.match(dialCodeRegex)
   const newNumber = number.replace(dialCodeRegex, nextSelectedCountry.dialCode)
   return newNumber
 }
<|current_version|>
export default function replaceCountryCode(
  currentSelectedCountry,
  nextSelectedCountry,
  number,
) {
  const dialCodeRegex = RegExp(`^(${currentSelectedCountry.dialCode})`)
  const codeToBeReplaced = number.match(dialCodeRegex)
  const newNumber = number.replace(dialCodeRegex, nextSelectedCountry.dialCode)
  return newNumber
}

<|next_version|>
export default function replaceCountryCode(
  currentSelectedCountry,
  nextSelectedCountry,
  number,
) {
  const dialCodeRegex = RegExp(`^(${currentSelectedCountry.dialCode})`)
  const codeToBeReplaced = number.match(dialCodeRegex)
  const newNumber = number.replace(dialCodeRegex, nextSelectedCountry.dialCode)

  if (codeToBeReplaced === null && newNumber === number) {
    return nextSelectedCountry.dialCode + number
  }
  return newNumber
}


Allow Browser Sync port to be specified

Allow Browser Sync port to be specified

Defaults to the default Browser Sync port: 3000.

--- site/gulpfile.js
+++ site/gulpfile.js
@@ -7,10 +7,12 @@

 elixir(function(mix) {
     var env = argv.e || argv.env || 'local';
+    var port = argv.p || argv.port || 3000;

     mix.sass('main.scss')
         .exec('jigsaw build ' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*'])
         .browserSync({
+            port: port,
             server: { baseDir: 'build_' + env },
             proxy: null,
             files: [ 'build_' + env + '/**/*' ]

<|original_code|>
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var argv = require('yargs').argv;

elixir.config.assetsPath = 'source/_assets';
elixir.config.publicPath = 'source';

elixir(function(mix) {
    var env = argv.e || argv.env || 'local';

    mix.sass('main.scss')
        .exec('jigsaw build ' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*'])
        .browserSync({
            server: { baseDir: 'build_' + env },
            proxy: null,
            files: [ 'build_' + env + '/**/*' ]
        });
});

<|edits_diff|>
--- site/gulpfile.js
+++ site/gulpfile.js
@@ -7,6 +7,7 @@

 elixir(function(mix) {
     var env = argv.e || argv.env || 'local';
+    var port = argv.p || argv.port || 3000;

     mix.sass('main.scss')
         .exec('jigsaw build ' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*'])
<|current_version|>
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var argv = require('yargs').argv;

elixir.config.assetsPath = 'source/_assets';
elixir.config.publicPath = 'source';

elixir(function(mix) {
    var env = argv.e || argv.env || 'local';
    var port = argv.p || argv.port || 3000;

    mix.sass('main.scss')
        .exec('jigsaw build ' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*'])
        .browserSync({
            server: { baseDir: 'build_' + env },
            proxy: null,
            files: [ 'build_' + env + '/**/*' ]
        });
});

<|next_version|>
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var argv = require('yargs').argv;

elixir.config.assetsPath = 'source/_assets';
elixir.config.publicPath = 'source';

elixir(function(mix) {
    var env = argv.e || argv.env || 'local';
    var port = argv.p || argv.port || 3000;

    mix.sass('main.scss')
        .exec('jigsaw build ' + env, ['./source/*', './source/**/*', '!./source/_assets/**/*'])
        .browserSync({
            port: port,
            server: { baseDir: 'build_' + env },
            proxy: null,
            files: [ 'build_' + env + '/**/*' ]
        });
});


Add exports of reducer and hydrateStore

Add exports of reducer and hydrateStore

--- src/orb/index.js
+++ src/orb/index.js
@@ -3,6 +3,8 @@
 import Grid from './components/Grid';
 import WrappedGrid from './WrappedGrid';
 import Chart from './components/Chart/Chart';
+import reducer from './reducers';
+import hydrateStore from './hydrateStore';

 import './index.css';

@@ -11,3 +13,5 @@
 export { Grid };
 export { WrappedGrid };
 export { Chart };
+export { reducer };
+export { hydrateStore };

<|original_code|>
import GridConfiguration from './components/GridConfiguration';
import ChartConfiguration from './components/ChartConfiguration';
import Grid from './components/Grid';
import WrappedGrid from './WrappedGrid';
import Chart from './components/Chart/Chart';

import './index.css';

export { GridConfiguration };
export { ChartConfiguration };
export { Grid };
export { WrappedGrid };
export { Chart };

<|edits_diff|>
--- src/orb/index.js
+++ src/orb/index.js
@@ -3,6 +3,8 @@
 import Grid from './components/Grid';
 import WrappedGrid from './WrappedGrid';
 import Chart from './components/Chart/Chart';
+import reducer from './reducers';
+import hydrateStore from './hydrateStore';

 import './index.css';

<|current_version|>
import GridConfiguration from './components/GridConfiguration';
import ChartConfiguration from './components/ChartConfiguration';
import Grid from './components/Grid';
import WrappedGrid from './WrappedGrid';
import Chart from './components/Chart/Chart';
import reducer from './reducers';
import hydrateStore from './hydrateStore';

import './index.css';

export { GridConfiguration };
export { ChartConfiguration };
export { Grid };
export { WrappedGrid };
export { Chart };

<|next_version|>
import GridConfiguration from './components/GridConfiguration';
import ChartConfiguration from './components/ChartConfiguration';
import Grid from './components/Grid';
import WrappedGrid from './WrappedGrid';
import Chart from './components/Chart/Chart';
import reducer from './reducers';
import hydrateStore from './hydrateStore';

import './index.css';

export { GridConfiguration };
export { ChartConfiguration };
export { Grid };
export { WrappedGrid };
export { Chart };
export { reducer };
export { hydrateStore };


Use SwitchTextType package in ProseEditor.

--- packages/prose-editor/ProseEditorPackage.js
+++ packages/prose-editor/ProseEditorPackage.js
@@ -1,4 +1,5 @@
 import BasePackage from '../base/BasePackage'
+import SwitchTextTypePackage from '../switch-text-type/SwitchTextTypePackage'
 import ParagraphPackage from '../paragraph/ParagraphPackage'
 import HeadingPackage from '../heading/HeadingPackage'
 import CodeblockPackage from '../codeblock/CodeblockPackage'
@@ -21,6 +22,7 @@
     })
     // SwitchTextType, Undo/Redo etc.
     config.import(BasePackage)
+    config.import(SwitchTextTypePackage)
     config.import(ParagraphPackage)
     config.import(HeadingPackage)
     config.import(CodeblockPackage)

<|original_code|>
import BasePackage from '../base/BasePackage'
import ParagraphPackage from '../paragraph/ParagraphPackage'
import HeadingPackage from '../heading/HeadingPackage'
import CodeblockPackage from '../codeblock/CodeblockPackage'
import BlockquotePackage from '../blockquote/BlockquotePackage'
import LinkPackage from '../link/LinkPackage'
import EmphasisPackage from '../emphasis/EmphasisPackage'
import StrongPackage from '../strong/StrongPackage'
import CodePackage from '../code/CodePackage'
import SubscriptPackage from '../subscript/SubscriptPackage'
import SuperscriptPackage from '../superscript/SuperscriptPackage'
import ProseArticle from './ProseArticle'

export default {
  name: 'prose-editor',
  configure: function(config) {
    config.defineSchema({
      name: 'prose-article',
      ArticleClass: ProseArticle,
      defaultTextType: 'paragraph'
    })
    // SwitchTextType, Undo/Redo etc.
    config.import(BasePackage)
    config.import(ParagraphPackage)
    config.import(HeadingPackage)
    config.import(CodeblockPackage)
    config.import(BlockquotePackage)
    config.import(EmphasisPackage)
    config.import(StrongPackage)
    config.import(SubscriptPackage)
    config.import(SuperscriptPackage)
    config.import(CodePackage)
    config.import(LinkPackage)
  }
}

<|edits_diff|>
--- packages/prose-editor/ProseEditorPackage.js
+++ packages/prose-editor/ProseEditorPackage.js
@@ -1,4 +1,5 @@
 import BasePackage from '../base/BasePackage'
+import SwitchTextTypePackage from '../switch-text-type/SwitchTextTypePackage'
 import ParagraphPackage from '../paragraph/ParagraphPackage'
 import HeadingPackage from '../heading/HeadingPackage'
 import CodeblockPackage from '../codeblock/CodeblockPackage'
<|current_version|>
import BasePackage from '../base/BasePackage'
import SwitchTextTypePackage from '../switch-text-type/SwitchTextTypePackage'
import ParagraphPackage from '../paragraph/ParagraphPackage'
import HeadingPackage from '../heading/HeadingPackage'
import CodeblockPackage from '../codeblock/CodeblockPackage'
import BlockquotePackage from '../blockquote/BlockquotePackage'
import LinkPackage from '../link/LinkPackage'
import EmphasisPackage from '../emphasis/EmphasisPackage'
import StrongPackage from '../strong/StrongPackage'
import CodePackage from '../code/CodePackage'
import SubscriptPackage from '../subscript/SubscriptPackage'
import SuperscriptPackage from '../superscript/SuperscriptPackage'
import ProseArticle from './ProseArticle'

export default {
  name: 'prose-editor',
  configure: function(config) {
    config.defineSchema({
      name: 'prose-article',
      ArticleClass: ProseArticle,
      defaultTextType: 'paragraph'
    })
    // SwitchTextType, Undo/Redo etc.
    config.import(BasePackage)
    config.import(ParagraphPackage)
    config.import(HeadingPackage)
    config.import(CodeblockPackage)
    config.import(BlockquotePackage)
    config.import(EmphasisPackage)
    config.import(StrongPackage)
    config.import(SubscriptPackage)
    config.import(SuperscriptPackage)
    config.import(CodePackage)
    config.import(LinkPackage)
  }
}

<|next_version|>
import BasePackage from '../base/BasePackage'
import SwitchTextTypePackage from '../switch-text-type/SwitchTextTypePackage'
import ParagraphPackage from '../paragraph/ParagraphPackage'
import HeadingPackage from '../heading/HeadingPackage'
import CodeblockPackage from '../codeblock/CodeblockPackage'
import BlockquotePackage from '../blockquote/BlockquotePackage'
import LinkPackage from '../link/LinkPackage'
import EmphasisPackage from '../emphasis/EmphasisPackage'
import StrongPackage from '../strong/StrongPackage'
import CodePackage from '../code/CodePackage'
import SubscriptPackage from '../subscript/SubscriptPackage'
import SuperscriptPackage from '../superscript/SuperscriptPackage'
import ProseArticle from './ProseArticle'

export default {
  name: 'prose-editor',
  configure: function(config) {
    config.defineSchema({
      name: 'prose-article',
      ArticleClass: ProseArticle,
      defaultTextType: 'paragraph'
    })
    // SwitchTextType, Undo/Redo etc.
    config.import(BasePackage)
    config.import(SwitchTextTypePackage)
    config.import(ParagraphPackage)
    config.import(HeadingPackage)
    config.import(CodeblockPackage)
    config.import(BlockquotePackage)
    config.import(EmphasisPackage)
    config.import(StrongPackage)
    config.import(SubscriptPackage)
    config.import(SuperscriptPackage)
    config.import(CodePackage)
    config.import(LinkPackage)
  }
}


Test exampleReducer when action type is EXAMPLE_ACTION

--- test/reducers/example-reducer.test.js
+++ test/reducers/example-reducer.test.js
@@ -1,7 +1,13 @@
+import * as actionTypes from "../../src/actions/types";
 import exampleReducer from "../../src/reducers/example-reducer";

 describe("exampleReducer", () => {
   test("initial state", () => {
     expect(exampleReducer(undefined, {})).toEqual({example: ""});
   });
+
+  test ("when action type is EXAMPLE_ACTION", () => {
+    expect(exampleReducer(undefined, {type: actionTypes.EXAMPLE_ACTION, text: "Testing"}))
+      .toEqual({example: "Testing"});
+  });
 });

<|original_code|>
import exampleReducer from "../../src/reducers/example-reducer";

describe("exampleReducer", () => {
  test("initial state", () => {
    expect(exampleReducer(undefined, {})).toEqual({example: ""});
  });
});

<|edits_diff|>
--- test/reducers/example-reducer.test.js
+++ test/reducers/example-reducer.test.js
@@ -1,3 +1,4 @@
+import * as actionTypes from "../../src/actions/types";
 import exampleReducer from "../../src/reducers/example-reducer";

 describe("exampleReducer", () => {
<|current_version|>
import * as actionTypes from "../../src/actions/types";
import exampleReducer from "../../src/reducers/example-reducer";

describe("exampleReducer", () => {
  test("initial state", () => {
    expect(exampleReducer(undefined, {})).toEqual({example: ""});
  });
});

<|next_version|>
import * as actionTypes from "../../src/actions/types";
import exampleReducer from "../../src/reducers/example-reducer";

describe("exampleReducer", () => {
  test("initial state", () => {
    expect(exampleReducer(undefined, {})).toEqual({example: ""});
  });

  test ("when action type is EXAMPLE_ACTION", () => {
    expect(exampleReducer(undefined, {type: actionTypes.EXAMPLE_ACTION, text: "Testing"}))
      .toEqual({example: "Testing"});
  });
});


Add FormReducer to redux reducers

Add FormReducer to redux reducers

--- src/reducers/index.js
+++ src/reducers/index.js
@@ -6,6 +6,7 @@
 import { UserReducer } from './UserReducer';
 import { PrescriptionReducer } from './PrescriptionReducer';
 import { PatientReducer } from './PatientReducer';
+import { FormReducer } from './FormReducer';

 export default combineReducers({
   user: UserReducer,
@@ -15,4 +16,5 @@
   modules: ModulesReducer,
   prescription: PrescriptionReducer,
   patient: PatientReducer,
+  form: FormReducer,
 });

<|original_code|>
import { combineReducers } from 'redux';
import NavigationReducer from './NavigationReducer';
import SyncReducer from './SyncReducer';
import { PagesReducer } from './PagesReducer';
import { ModulesReducer } from './ModulesReducer';
import { UserReducer } from './UserReducer';
import { PrescriptionReducer } from './PrescriptionReducer';
import { PatientReducer } from './PatientReducer';

export default combineReducers({
  user: UserReducer,
  nav: NavigationReducer,
  sync: SyncReducer,
  pages: PagesReducer,
  modules: ModulesReducer,
  prescription: PrescriptionReducer,
  patient: PatientReducer,
});

<|edits_diff|>
--- src/reducers/index.js
+++ src/reducers/index.js
@@ -6,6 +6,7 @@
 import { UserReducer } from './UserReducer';
 import { PrescriptionReducer } from './PrescriptionReducer';
 import { PatientReducer } from './PatientReducer';
+import { FormReducer } from './FormReducer';

 export default combineReducers({
   user: UserReducer,
<|current_version|>
import { combineReducers } from 'redux';
import NavigationReducer from './NavigationReducer';
import SyncReducer from './SyncReducer';
import { PagesReducer } from './PagesReducer';
import { ModulesReducer } from './ModulesReducer';
import { UserReducer } from './UserReducer';
import { PrescriptionReducer } from './PrescriptionReducer';
import { PatientReducer } from './PatientReducer';
import { FormReducer } from './FormReducer';

export default combineReducers({
  user: UserReducer,
  nav: NavigationReducer,
  sync: SyncReducer,
  pages: PagesReducer,
  modules: ModulesReducer,
  prescription: PrescriptionReducer,
  patient: PatientReducer,
});

<|next_version|>
import { combineReducers } from 'redux';
import NavigationReducer from './NavigationReducer';
import SyncReducer from './SyncReducer';
import { PagesReducer } from './PagesReducer';
import { ModulesReducer } from './ModulesReducer';
import { UserReducer } from './UserReducer';
import { PrescriptionReducer } from './PrescriptionReducer';
import { PatientReducer } from './PatientReducer';
import { FormReducer } from './FormReducer';

export default combineReducers({
  user: UserReducer,
  nav: NavigationReducer,
  sync: SyncReducer,
  pages: PagesReducer,
  modules: ModulesReducer,
  prescription: PrescriptionReducer,
  patient: PatientReducer,
  form: FormReducer,
});