<commit_before>import auth from '../lib/auth'
import lang from '../lib/lang'
import timezone from '../lib/timezone'
import init from '../lib/init'

import userStore from '../store/modules/user'
import taskTypeStore from '../store/modules/tasktypes'

import Asset from '../components/Asset'
import Assets from '../components/Assets'
import AssetTypes from '../components/AssetTypes'
import Breakdown from '../components/Breakdown'
import CustomActions from '../components/CustomActions'
import Login from '../components/Login'
import Main from '../components/Main'
import NotFound from '../components/NotFound'
import Notifications from '../components/Notifications'
import People from '../components/People'
import Person from '../components/Person'
import Productions from '../components/Productions'
import OpenProductions from '../components/OpenProductions'
import Playlist from '../components/Playlist'
import Profile from '../components/Profile'
import Task from '../components/Task'
import TaskTypes from '../components/TaskTypes'
import TaskStatus from '../components/TaskStatus'
import Todos from '../components/Todos'
import ServerDown from '../components/ServerDown'
import Sequences from '../components/Sequences'
import TaskType from '../components/TaskType'
import Episodes from '../components/Episodes'
import Shot from '../components/Shot'
import Shots from '../components/Shots'

export const routes = [

  {
    path: '',
    component: Main,

    beforeEnter: (to, from, next) => {
      auth.requireAuth(to, from, (nextPath) => {
        if (nextPath) {
          next(nextPath)
        } else {
          timezone.setTimezone()
          lang.setLocale()
          init((err) => {
            if (err) {
              next({name: 'server-down'})
            } else {
              if (userStore.getters.isCurrentUserManager(userStore.state)) {
                next({name: 'open-productions'})
              } else {
                next({name: 'todos'})
              }
            }
          })
        }
      })
    }
  },

  {
    path: '/',
    component: Main,

    beforeEnter: (to, from, next) => {
      auth.requireAuth(to, from, (nextPath) => {
        if (nextPath) {
          next(nextPath)
        } else {
          timezone.setTimezone()
          lang.setLocale()
          if (taskTypeStore.state.taskTypes.length === 0) {
            init(next)
          } else {
            next()
          }
        }
      })
    },

    children: [
      {
        path: '',
        name: 'home'
      },
      {
        path: '/open-productions',
        component: OpenProductions,
        name: 'open-productions'
      },
      {
        path: '/open-productions/new',
        component: OpenProductions,
        name: 'open-productions-new'
      },

      { path: '/people', component: People },
      { path: '/people/new', component: People },
      {
        path: '/people/edit/:person_id',
        component: People,
        name: 'edit-person'
      },
      {
        name: 'delete-person',
        path: '/people/delete/:person_id',
        component: People
      },
      {
        path: '/people/import',
        component: People,
        name: 'people'
      },
      {
        path: '/people/:person_id',
        component: Person,
        name: 'person'
      },

      {
        path: '/productions',
        component: Productions,
        name: 'productions'
      },
      {
        path: '/productions/new',
        component: Productions,
        name: 'productions-new'
      },
      {
        path: '/productions/edit/:production_id',
        component: Productions,
        name: 'edit-production'
      },
      {
        path: '/productions/delete/:production_id',
        component: Productions,
        name: 'delete-production'
      },

      {
        path: '/productions/:production_id/breakdown',
        component: Breakdown,
        name: 'breakdown'
      },
      {
        path: '/productions/:production_id/breakdown/shots/:shot_id',
        component: Breakdown,
        name: 'breakdown-shot'
      },

      {
        path: '/productions/:production_id/assets',
        component: Assets,
        name: 'assets'
      },
      {
        path: '/productions/:production_id/assets/new',
        component: Assets,
        name: 'new-asset'
      },
      {
        path:
        '/productions/:production_id/assets/:asset_id',
        component: Asset,
        name: 'asset'
      },
      {
        path:
        '/productions/:production_id/assets/edit/:asset_id',
        component: Assets,
        name: 'edit-asset'
      },
      {
        path: '/productions/:production_id/assets/delete/:asset_id',
        component: Assets,
        name: 'delete-asset'
      },
      {
        path: '/productions/:production_id/assets/restore/:asset_id',
        component: Assets,
        name: 'restore-asset'
      },
      {
        path: '/productions/:production_id/assets/import',
        component: Assets,
        name: 'import-assets'
      },
      {
        path: '/productions/:production_id/assets/create-tasks',
        component: Assets,
        name: 'create-asset-tasks'
      },

      {
        path: '/productions/:production_id/shots',
        component: Shots,
        name: 'shots'
      },
      {
        path: '/productions/:production_id/shots/manage',
        component: Shots,
        name: 'manage-shots'
      },
      {
        path: '/productions/:production_id/shots/import',
        component: Shots,
        name: 'import-shots'
      },
      {
        path: '/productions/:production_id/shots/create-tasks',
        component: Shots,
        name: 'create-shot-tasks'
      },
      {
        path: '/productions/:production_id/shots/edit/:shot_id',
        component: Shots,
        name: 'edit-shots'
      },
      {
        path: '/productions/:production_id/shots/delete/:shot_id',
        component: Shots,
        name: 'delete-shots'
      },
      {
        path: '/productions/:production_id/shots/restore/:shot_id',
        component: Shots,
        name: 'restore-shots'
      },
      {
        path: '/productions/:production_id/shots/:shot_id',
        component: Shot,
        name: 'shot'
      },

      {
        path: '/productions/:production_id/sequences',
        component: Sequences,
        name: 'sequences'
      },
      {
        path: '/productions/:production_id/sequences/edit/:sequence_id',
        component: Sequences,
        name: 'edit-sequence'
      },
      {
        path: '/productions/:production_id/sequences/delete/:sequence_id',
        component: Sequences,
        name: 'delete-sequence'
      },

      {
        path: '/productions/:production_id/episodes',
        component: Episodes,
        name: 'episodes'
      },
      {
        path: '/productions/:production_id/episodes/edit/:episode_id',
        component: Episodes,
        name: 'edit-episode'
      },
      {
        path: '/productions/:production_id/episodes/delete/:episode_id',
        component: Episodes,
        name: 'delete-episode'
      },

      {
        path: '/productions/:production_id/task-types/:task_type_id',
        component: TaskType,
        name: 'task-type'
      },

      {
        name: 'task',
        path: '/tasks/:task_id',
        component: Task
      },
      {
        name: 'task-delete',
        path: '/tasks/:task_id/delete',
        component: Task
      },
      {
        name: 'task-add-preview',
        path: '/tasks/:task_id/comments/:comment_id/add-preview',
        component: Task
      },
      {
        name: 'task-change-preview',
        path: '/tasks/:task_id/comments/:comment_id/change-preview',
        component: Task
      },
      {
        name: 'task-preview',
        path: '/tasks/:task_id/previews/:preview_id',
        component: Task
      },
      {
        name: 'comment-edit',
        path: '/tasks/:task_id/comments/:comment_id/edit',
        component: Task
      },
      {
        name: 'comment-delete',
        path: '/tasks/:task_id/comments/:comment_id/delete',
        component: Task
      },

      { path: '/asset-types', component: AssetTypes },
      { path: '/asset-types/new', component: AssetTypes },
      {
        name: 'edit-asset-type',
        path: '/asset-types/edit/:asset_type_id',
        component: AssetTypes
      },
      {
        name: 'delete-asset-type',
        path: '/asset-types/delete/:asset_type_id',
        component: AssetTypes
      },

      { path: '/task-types', component: TaskTypes },
      { path: '/task-types/new', component: TaskTypes },
      {
        name: 'edit-task-type',
        path: '/task-types/edit/:task_type_id',
        component: TaskTypes
      },
      {
        name: 'delete-task-type',
        path: '/task-types/delete/:task_type_id',
        component: TaskTypes
      },

      {
        name: 'task-status',
        path: '/task-status',
        component: TaskStatus
      },
      {
        name: 'new-task-status',
        path: '/task-status/new',
        component: TaskStatus
      },
      {
        name: 'edit-task-status',
        path: '/task-status/edit/:task_status_id',
        component: TaskStatus
      },
      {
        name: 'delete-task-status',
        path: '/task-status/delete/:task_status_id',
        component: TaskStatus
      },
      {
        name: 'task-types',
        path: '/task-types',
        component: TaskTypes
      },

      {
        name: 'custom-actions',
        path: '/custom-actions',
        component: CustomActions
      },
      {
        name: 'custom-actions-new',
        path: '/custom-actions/new',
        component: CustomActions
      },
      {
        name: 'edit-custom-action',
        path: '/custom-actions/edit/:custom_action_id',
        component: CustomActions
      },
      {
        name: 'delete-custom-action',
        path: '/custom-actions/delete/:custom_action_id',
        component: CustomActions
      },

      { path: '/todos', component: Todos, name: 'todos' },
      { path: '/profile', component: Profile, name: 'profile' },
      {
        path: '/profile/change-avatar',
        component: Profile,
        name: 'change-avatar'
      },

      {
        name: 'playlists',
        path: '/productions/:production_id/playlists',
        component: Playlist
      },
      {
        name: 'playlist',
        path: '/productions/:production_id/playlists/:playlist_id',
        component: Playlist
      },
      {
        name: 'delete-playlist',
        path: '/productions/:production_id/playlists/:playlist_id/delete',
        component: Playlist
      },
      {
        name: 'edit-playlist',
        path: '/productions/:production_id/playlists/:playlist_id/edit',
        component: Playlist
      },

      {
        name: 'notifications',
        path: '/notifications',
        component: Notifications
      }
    ]
  },
  {
    path: '/login',
    component: Login,
    name: 'login'
  },
  {
    path: '/server-down',
    component: ServerDown,
    name: 'server-down'
  },
  {
    path: '/*',
    component: NotFound,
    name: 'not-found'
  }
]
<commit_msg>Do not reload all open productions<commit_after>import auth from '../lib/auth'
import lang from '../lib/lang'
import timezone from '../lib/timezone'
import init from '../lib/init'

import userStore from '../store/modules/user'
import taskTypeStore from '../store/modules/tasktypes'
import store from '../store/'

import Asset from '../components/Asset'
import Assets from '../components/Assets'
import AssetTypes from '../components/AssetTypes'
import Breakdown from '../components/Breakdown'
import CustomActions from '../components/CustomActions'
import Login from '../components/Login'
import Main from '../components/Main'
import NotFound from '../components/NotFound'
import Notifications from '../components/Notifications'
import People from '../components/People'
import Person from '../components/Person'
import Productions from '../components/Productions'
import OpenProductions from '../components/OpenProductions'
import Playlist from '../components/Playlist'
import Profile from '../components/Profile'
import Task from '../components/Task'
import TaskTypes from '../components/TaskTypes'
import TaskStatus from '../components/TaskStatus'
import Todos from '../components/Todos'
import ServerDown from '../components/ServerDown'
import Sequences from '../components/Sequences'
import TaskType from '../components/TaskType'
import Episodes from '../components/Episodes'
import Shot from '../components/Shot'
import Shots from '../components/Shots'

export const routes = [

  {
    path: '',
    component: Main,

    beforeEnter: (to, from, next) => {
      auth.requireAuth(to, from, (nextPath) => {
        if (nextPath) {
          next(nextPath)
        } else {
          timezone.setTimezone()
          lang.setLocale()
          if (store.state.productions.openProductions.length === 0) {
            init((err) => {
              if (err) {
                next({name: 'server-down'})
              } else {
                if (userStore.getters.isCurrentUserManager(userStore.state)) {
                  next({name: 'open-productions'})
                } else {
                  next({name: 'todos'})
                }
              }
            })
          } else {
            if (userStore.getters.isCurrentUserManager(userStore.state)) {
              next({name: 'open-productions'})
            } else {
              next({name: 'todos'})
            }
          }
        }
      })
    }
  },

  {
    path: '/',
    component: Main,

    beforeEnter: (to, from, next) => {
      auth.requireAuth(to, from, (nextPath) => {
        if (nextPath) {
          next(nextPath)
        } else {
          timezone.setTimezone()
          lang.setLocale()
          if (taskTypeStore.state.taskTypes.length === 0) {
            init(next)
          } else {
            next()
          }
        }
      })
    },

    children: [
      {
        path: '',
        name: 'home'
      },
      {
        path: '/open-productions',
        component: OpenProductions,
        name: 'open-productions'
      },
      {
        path: '/open-productions/new',
        component: OpenProductions,
        name: 'open-productions-new'
      },

      { path: '/people', component: People },
      { path: '/people/new', component: People },
      {
        path: '/people/edit/:person_id',
        component: People,
        name: 'edit-person'
      },
      {
        name: 'delete-person',
        path: '/people/delete/:person_id',
        component: People
      },
      {
        path: '/people/import',
        component: People,
        name: 'people'
      },
      {
        path: '/people/:person_id',
        component: Person,
        name: 'person'
      },

      {
        path: '/productions',
        component: Productions,
        name: 'productions'
      },
      {
        path: '/productions/new',
        component: Productions,
        name: 'productions-new'
      },
      {
        path: '/productions/edit/:production_id',
        component: Productions,
        name: 'edit-production'
      },
      {
        path: '/productions/delete/:production_id',
        component: Productions,
        name: 'delete-production'
      },

      {
        path: '/productions/:production_id/breakdown',
        component: Breakdown,
        name: 'breakdown'
      },
      {
        path: '/productions/:production_id/breakdown/shots/:shot_id',
        component: Breakdown,
        name: 'breakdown-shot'
      },

      {
        path: '/productions/:production_id/assets',
        component: Assets,
        name: 'assets'
      },
      {
        path: '/productions/:production_id/assets/new',
        component: Assets,
        name: 'new-asset'
      },
      {
        path:
        '/productions/:production_id/assets/:asset_id',
        component: Asset,
        name: 'asset'
      },
      {
        path:
        '/productions/:production_id/assets/edit/:asset_id',
        component: Assets,
        name: 'edit-asset'
      },
      {
        path: '/productions/:production_id/assets/delete/:asset_id',
        component: Assets,
        name: 'delete-asset'
      },
      {
        path: '/productions/:production_id/assets/restore/:asset_id',
        component: Assets,
        name: 'restore-asset'
      },
      {
        path: '/productions/:production_id/assets/import',
        component: Assets,
        name: 'import-assets'
      },
      {
        path: '/productions/:production_id/assets/create-tasks',
        component: Assets,
        name: 'create-asset-tasks'
      },

      {
        path: '/productions/:production_id/shots',
        component: Shots,
        name: 'shots'
      },
      {
        path: '/productions/:production_id/shots/manage',
        component: Shots,
        name: 'manage-shots'
      },
      {
        path: '/productions/:production_id/shots/import',
        component: Shots,
        name: 'import-shots'
      },
      {
        path: '/productions/:production_id/shots/create-tasks',
        component: Shots,
        name: 'create-shot-tasks'
      },
      {
        path: '/productions/:production_id/shots/edit/:shot_id',
        component: Shots,
        name: 'edit-shots'
      },
      {
        path: '/productions/:production_id/shots/delete/:shot_id',
        component: Shots,
        name: 'delete-shots'
      },
      {
        path: '/productions/:production_id/shots/restore/:shot_id',
        component: Shots,
        name: 'restore-shots'
      },
      {
        path: '/productions/:production_id/shots/:shot_id',
        component: Shot,
        name: 'shot'
      },

      {
        path: '/productions/:production_id/sequences',
        component: Sequences,
        name: 'sequences'
      },
      {
        path: '/productions/:production_id/sequences/edit/:sequence_id',
        component: Sequences,
        name: 'edit-sequence'
      },
      {
        path: '/productions/:production_id/sequences/delete/:sequence_id',
        component: Sequences,
        name: 'delete-sequence'
      },

      {
        path: '/productions/:production_id/episodes',
        component: Episodes,
        name: 'episodes'
      },
      {
        path: '/productions/:production_id/episodes/edit/:episode_id',
        component: Episodes,
        name: 'edit-episode'
      },
      {
        path: '/productions/:production_id/episodes/delete/:episode_id',
        component: Episodes,
        name: 'delete-episode'
      },

      {
        path: '/productions/:production_id/task-types/:task_type_id',
        component: TaskType,
        name: 'task-type'
      },

      {
        name: 'task',
        path: '/tasks/:task_id',
        component: Task
      },
      {
        name: 'task-delete',
        path: '/tasks/:task_id/delete',
        component: Task
      },
      {
        name: 'task-add-preview',
        path: '/tasks/:task_id/comments/:comment_id/add-preview',
        component: Task
      },
      {
        name: 'task-change-preview',
        path: '/tasks/:task_id/comments/:comment_id/change-preview',
        component: Task
      },
      {
        name: 'task-preview',
        path: '/tasks/:task_id/previews/:preview_id',
        component: Task
      },
      {
        name: 'comment-edit',
        path: '/tasks/:task_id/comments/:comment_id/edit',
        component: Task
      },
      {
        name: 'comment-delete',
        path: '/tasks/:task_id/comments/:comment_id/delete',
        component: Task
      },

      { path: '/asset-types', component: AssetTypes },
      { path: '/asset-types/new', component: AssetTypes },
      {
        name: 'edit-asset-type',
        path: '/asset-types/edit/:asset_type_id',
        component: AssetTypes
      },
      {
        name: 'delete-asset-type',
        path: '/asset-types/delete/:asset_type_id',
        component: AssetTypes
      },

      { path: '/task-types', component: TaskTypes },
      { path: '/task-types/new', component: TaskTypes },
      {
        name: 'edit-task-type',
        path: '/task-types/edit/:task_type_id',
        component: TaskTypes
      },
      {
        name: 'delete-task-type',
        path: '/task-types/delete/:task_type_id',
        component: TaskTypes
      },

      {
        name: 'task-status',
        path: '/task-status',
        component: TaskStatus
      },
      {
        name: 'new-task-status',
        path: '/task-status/new',
        component: TaskStatus
      },
      {
        name: 'edit-task-status',
        path: '/task-status/edit/:task_status_id',
        component: TaskStatus
      },
      {
        name: 'delete-task-status',
        path: '/task-status/delete/:task_status_id',
        component: TaskStatus
      },
      {
        name: 'task-types',
        path: '/task-types',
        component: TaskTypes
      },

      {
        name: 'custom-actions',
        path: '/custom-actions',
        component: CustomActions
      },
      {
        name: 'custom-actions-new',
        path: '/custom-actions/new',
        component: CustomActions
      },
      {
        name: 'edit-custom-action',
        path: '/custom-actions/edit/:custom_action_id',
        component: CustomActions
      },
      {
        name: 'delete-custom-action',
        path: '/custom-actions/delete/:custom_action_id',
        component: CustomActions
      },

      { path: '/todos', component: Todos, name: 'todos' },
      { path: '/profile', component: Profile, name: 'profile' },
      {
        path: '/profile/change-avatar',
        component: Profile,
        name: 'change-avatar'
      },

      {
        name: 'playlists',
        path: '/productions/:production_id/playlists',
        component: Playlist
      },
      {
        name: 'playlist',
        path: '/productions/:production_id/playlists/:playlist_id',
        component: Playlist
      },
      {
        name: 'delete-playlist',
        path: '/productions/:production_id/playlists/:playlist_id/delete',
        component: Playlist
      },
      {
        name: 'edit-playlist',
        path: '/productions/:production_id/playlists/:playlist_id/edit',
        component: Playlist
      },

      {
        name: 'notifications',
        path: '/notifications',
        component: Notifications
      }
    ]
  },
  {
    path: '/login',
    component: Login,
    name: 'login'
  },
  {
    path: '/server-down',
    component: ServerDown,
    name: 'server-down'
  },
  {
    path: '/*',
    component: NotFound,
    name: 'not-found'
  }
]
<|endoftext|>


<commit_before>1. 'use strict';
2.
3. let http = require('http');
4.
5. http.createServer((request, response) => {
6. request.on('end', () => {
7. console.log('Request method: ' + request.method);
8. console.log('Request url: ' + request.url);
9. });
10.
11. // 傳送 HTTP header
12. // HTTP Status: 200 : OK
13. // Content Type: text/plain
14. response.writeHead(200, {
15. 'Content-Type': 'text/plain'
16. });
17.
18. // 傳送回應內容。
19. response.end('Hello World!\n');
20. }).listen(8088);
21.
22. // log message to Console
23. console.log('Server running at http://127.0.0.1:8088/');
<commit_msg>11/3 123<commit_after>'use strict';

let http = require('http');

http.createServer((request, response) => {
request.on('end', () => {
console.log('Request method: ' + request.method);
console.log('Request url: ' + request.url);
});

// 傳送 HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {
'Content-Type': 'text/plain'
});

// 傳送回應內容。
response.end('Hello World!\n');
}).listen(8088);

// log message to Console
console.log('Server running at http://127.0.0.1:8088/');
<|endoftext|>


<commit_before>var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');

var app = express();
var appSSL = express();

app.use(express.static(__dirname + '/dist'));
appSSL.use(express.static(__dirname + '/dist'));

app.set('port', process.env.PORT || 3000);
appSSL.set('port', process.env.PORT || 8000);

var options = {

	key: fs.readFileSync('https/hacksparrow-key.pem'),
	cert: fs.readFileSync('https/hacksparrow-cert.pem')
};

var server = http.createServer(app);
var serverSSL = https.createServer(options, appSSL);

serverSSL.listen(appSSL.get('port'), function () {
	console.log('HTTPS Server start on:' + appSSL.get('port'));
});

server.listen(app.get('port'), function () {
	console.log('Server start on:' + app.get('port'));
});<commit_msg>Added SSL Server<commit_after>var express = require('express');
var https = require('https');
var fs = require('fs');

var app = express();

app.use(express.static(__dirname + '/dist'));

app.set('port', process.env.PORT || 8000);

var options = {

	key: fs.readFileSync('https/hacksparrow-key.pem'),
	cert: fs.readFileSync('https/hacksparrow-cert.pem')
};

var server = https.createServer(options, appSSL);

server.listen(app.get('port'), function () {
	console.log('HTTPS Server start on:' + app.get('port'));
});<|endoftext|>


<commit_before>import { compose, setDisplayName, wrapDisplayName } from 'recompose';
import isObject from 'lodash.isobject';
import { branchUntoggled, DEFAULT_FLAG_PROP_KEY } from '@flopflip/react';
import injectFeatureToggle from './inject-feature-toggle';

export default ({ flag, variate }, UntoggledComponent) => WrappedComponent =>
  compose(
    injectFeatureToggle(flag),
    branchUntoggled(UntoggledComponent, DEFAULT_FLAG_PROP_KEY, variate),
    setDisplayName(wrapDisplayName(WrappedComponent, 'branchOnFeatureToggle'))
  )(WrappedComponent);
<commit_msg>fix(react-redux): to import branchOnFeatureToggle<commit_after>import { compose, setDisplayName, wrapDisplayName } from 'recompose';
import isObject from 'lodash.isobject';
import { branchOnFeatureToggle, DEFAULT_FLAG_PROP_KEY } from '@flopflip/react';
import injectFeatureToggle from './inject-feature-toggle';

export default ({ flag, variate }, UntoggledComponent) => WrappedComponent =>
  compose(
    injectFeatureToggle(flag),
    branchOnFeatureToggle(UntoggledComponent, DEFAULT_FLAG_PROP_KEY, variate),
    setDisplayName(wrapDisplayName(WrappedComponent, 'branchOnFeatureToggle'))
  )(WrappedComponent);
<|endoftext|>


<commit_before>const _ = require('lodash');

module.exports = {
  find: async function (params = {}) {
    let collectionName = this.collectionName;
    if (this.collectionName.split('_')) {
      collectionName = this.collectionName.split('_')[this.collectionName.split('_').length - 1];
    }

    const populate = this.associations
      .filter(ast => ast.autoPopulate)
      .reduce((acc, ast) => {
        const from = ast.plugin ? `${ast.plugin}_${ast.model}` : ast.collection ? ast.collection : ast.model;
        const as = ast.alias;
        const localField = !ast.dominant ? '_id' : ast.via === collectionName || ast.via === 'related' ? '_id' : ast.alias;
        const foreignField = ast.filter ? `${ast.via}.ref` :
          ast.dominant ?
            (ast.via === collectionName ? ast.via : '_id') :
            (ast.via === collectionName ? '_id' : ast.via);

        acc.push({
          $lookup: {
            from,
            localField,
            foreignField,
            as,
          }
        });

        if (ast.type === 'model') {
          acc.push({
            $unwind: {
              path: `$${ast.alias}`,
              preserveNullAndEmptyArrays: true
            }
          });
        }

        if (params.relations) {
          Object.keys(params.relations).forEach(
            (relationName) => {
              if (ast.alias === relationName) {
                const association = this.associations.find(a => a.alias === relationName);
                if (association) {
                  const relation = params.relations[relationName];

                  Object.keys(relation).forEach(
                    (filter) => {
                      acc.push({
                        $match: { [`${relationName}.${filter}`]: relation[filter] }
                      });
                    }
                  );
                }
              }
            }
          );
        }

        return acc;
      }, []);

    const result = this
      .aggregate([
        {
          $match: params.where ? params.where : {}
        },
        ...populate,
      ]);

    if (params.start) result.skip(params.start);
    if (params.limit) result.limit(params.limit);
    if (params.sort) result.sort(params.sort);

    return result;
  },

  count: async function (params = {}) {
    return Number(await this
      .count(params));
  },

  findOne: async function (params, populate) {
    const primaryKey = params[this.primaryKey] || params.id;

    if (primaryKey) {
      params = {
        [this.primaryKey]: primaryKey
      };
    }

    return this
      .findOne(params)
      .populate(populate || this.associations.map(x => x.alias).join(' '))
      .lean();
  },

  create: async function (params) {
    return this.create(Object.keys(params).reduce((acc, current) => {
      if (_.get(this._attributes, [current, 'type']) || _.get(this._attributes, [current, 'model'])) {
        acc[current] = params[current];
      }

      return acc;
    }, {}))
      .catch((err) => {
        if (err.message.indexOf('index:') !== -1) {
          const message = err.message.split('index:');
          const field = _.words(_.last(message).split('_')[0]);
          const error = { message: `This ${field} is already taken`, field };

          throw error;
        }

        throw err;
      });
  },

  update: async function (search, params = {}) {
    if (_.isEmpty(params)) {
      params = search;
    }

    const primaryKey = search[this.primaryKey] || search.id;

    if (primaryKey) {
      search = {
        [this.primaryKey]: primaryKey
      };
    }

    return this.update(search, params, {
      strict: false
    })
      .catch((error) => {
        const field = _.last(_.words(error.message.split('_')[0]));
        const err = { message: `This ${field} is already taken`, field };

        throw err;
      });
  },

  delete: async function (params) {
    // Delete entry.
    return this
      .remove({
        [this.primaryKey]: params[this.primaryKey] || params.id
      });
  },

  deleteMany: async function (params) {
    // Delete entry.
    return this
      .remove({
        [this.primaryKey]: {
          $in: params[this.primaryKey] || params.id
        }
      });
  },

  search: async function (params) {
    const re = new RegExp(params.id);

    return this
      .find({
        '$or': [
          { username: re },
          { email: re }
        ]
      });
  },

  addPermission: async function (params) {
    return this
      .create(params);
  },

  removePermission: async function (params) {
    return this
      .remove(params);
  }
};
<commit_msg>Take into account user model<commit_after>const _ = require('lodash');

const buildTempFieldPath = field => {
  return `__${field}`;
};

const restoreRealFieldPath = (field, prefix) => {
  return `${prefix}${field}`;
};

export const generateLookupStage = (
  strapiModel,
  { whitelistedPopulate = null, prefixPath = '' } = {}
) => {
  const result = strapiModel.associations
    .filter(ast => {
      if (whitelistedPopulate) {
        return _.includes(whitelistedPopulate, ast.alias);
      }
      return ast.autoPopulate;
    })
    .reduce((acc, ast) => {
      const model = ast.plugin
        ? strapi.plugins[ast.plugin].models[ast.collection || ast.model]
        : strapi.models[ast.collection || ast.model];

      const from = model.collectionName;
      const isDominantAssociation = ast.dominant || !!ast.model;

      const _localField = !isDominantAssociation
        ? '_id'
        : ast.via === strapiModel.collectionName || ast.via === 'related'
          ? '_id'
          : ast.alias;

      const localField = `${prefixPath}${_localField}`;

      const foreignField = ast.filter
        ? `${ast.via}.ref`
        : isDominantAssociation
          ? ast.via === strapiModel.collectionName
            ? ast.via
            : '_id'
          : ast.via === strapiModel.collectionName
            ? '_id'
            : ast.via;

      // Add the juncture like the `.populate()` function
      const asTempPath = buildTempFieldPath(ast.alias, prefixPath);
      const asRealPath = restoreRealFieldPath(ast.alias, prefixPath);
      acc.push({
        $lookup: {
          from,
          localField,
          foreignField,
          as: asTempPath,
        },
      });

      // Unwind the relation's result if only one is expected
      if (ast.type === 'model') {
        acc.push({
          $unwind: {
            path: `$${asTempPath}`,
            preserveNullAndEmptyArrays: true,
          },
        });
      }

      // Preserve relation field if it is empty
      acc.push({
        $addFields: {
          [asRealPath]: {
            $ifNull: [`$${asTempPath}`, null],
          },
        },
      });

      // Remove temp field
      acc.push({
        $project: {
          [asTempPath]: 0,
        },
      });

      return acc;
    }, []);

  return result;
};

export const generateMatchStage = (
  strapiModel,
  filters,
  { prefixPath = '' } = {}
) => {
  const result = _.chain(filters)
    .get('relations')
    .reduce((acc, relationFilters, relationName) => {
      const association = strapiModel.associations.find(
        a => a.alias === relationName
      );

      // Ignore association if it's not been found
      if (!association) {
        return acc;
      }

      const model = association.plugin
        ? strapi.plugins[association.plugin].models[
            association.collection || association.model
          ]
        : strapi.models[association.collection || association.model];

      _.forEach(relationFilters, (value, key) => {
        if (key !== 'relations') {
          acc.push({
            $match: { [`${prefixPath}${relationName}.${key}`]: value },
          });
        } else {
          const nextPrefixedPath = `${prefixPath}${relationName}.`;
          acc.push(
            ...generateLookupStage(model, {
              whitelistedPopulate: _.keys(value),
              prefixPath: nextPrefixedPath,
            }),
            ...generateMatchStage(model, relationFilters, {
              prefixPath: nextPrefixedPath,
            })
          );
        }
      });
      return acc;
    }, [])
    .value();

  return result;
};

module.exports = {
  find: async function (filters = {}, populate) {
    // Generate stages.
    const populateStage = generateLookupStage(this, { whitelistedPopulate: populate });
    const matchStage = generateMatchStage(this, filters);

    const result = this.aggregate([
      {
        $match: filters.where || {}, // Direct relation filter
      },
      ...populateStage, // Nested-Population
      ...matchStage, // Nested relation filter
    ]);

    if (_.has(filters, 'start')) result.skip(filters.start);
    if (_.has(filters, 'limit')) result.limit(filters.limit);
    if (_.has(filters, 'sort')) result.sort(filters.sort);

    return result;
  },

  count: async function (params = {}) {
    return Number(await this
      .count(params));
  },

  findOne: async function (params, populate) {
    const primaryKey = params[this.primaryKey] || params.id;

    if (primaryKey) {
      params = {
        [this.primaryKey]: primaryKey
      };
    }

    return this
      .findOne(params)
      .populate(populate || this.associations.map(x => x.alias).join(' '))
      .lean();
  },

  create: async function (params) {
    return this.create(Object.keys(params).reduce((acc, current) => {
      if (_.get(this._attributes, [current, 'type']) || _.get(this._attributes, [current, 'model'])) {
        acc[current] = params[current];
      }

      return acc;
    }, {}))
      .catch((err) => {
        if (err.message.indexOf('index:') !== -1) {
          const message = err.message.split('index:');
          const field = _.words(_.last(message).split('_')[0]);
          const error = { message: `This ${field} is already taken`, field };

          throw error;
        }

        throw err;
      });
  },

  update: async function (search, params = {}) {
    if (_.isEmpty(params)) {
      params = search;
    }

    const primaryKey = search[this.primaryKey] || search.id;

    if (primaryKey) {
      search = {
        [this.primaryKey]: primaryKey
      };
    }

    return this.update(search, params, {
      strict: false
    })
      .catch((error) => {
        const field = _.last(_.words(error.message.split('_')[0]));
        const err = { message: `This ${field} is already taken`, field };

        throw err;
      });
  },

  delete: async function (params) {
    // Delete entry.
    return this
      .remove({
        [this.primaryKey]: params[this.primaryKey] || params.id
      });
  },

  deleteMany: async function (params) {
    // Delete entry.
    return this
      .remove({
        [this.primaryKey]: {
          $in: params[this.primaryKey] || params.id
        }
      });
  },

  search: async function (params) {
    const re = new RegExp(params.id);

    return this
      .find({
        '$or': [
          { username: re },
          { email: re }
        ]
      });
  },

  addPermission: async function (params) {
    return this
      .create(params);
  },

  removePermission: async function (params) {
    return this
      .remove(params);
  }
};
<|endoftext|>


<commit_before>describe("Sites", function() {
	describe("should find the favicon in the", function() {
		var path, error, server;

		beforeEach(function() {
			path = '';
			error = false;

			done = false;

			server = sinon.fakeServer.create();
		});

		afterEach(function() {
			server.restore();
		});

		describe("root directory", function() {
			it("with no folders", function() {
				server.respondWith("GET", "/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchRoot("/", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/favicon.ico");
				});
			});

			it("with folders", function() {
				server.respondWith("GET", "/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchRoot("/kitty/is/here", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/favicon.ico");
				});
			});

			it("with failures", function() {
				runs(function() {
					faviconSearchRoot("/", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(true);
					expect(path).toMatch("");
				});
			});
		});

		describe("current directory", function() {
			it("as is", function() {
				server.respondWith("GET", "/kitty/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchCurrent("/kitty", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/kitty/favicon.ico");
				});
			});

			it("with failures", function() {
				runs(function() {
					faviconSearchCurrent("/kitty", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(true);
					expect(path).toMatch("");
				});
			});
		});

		describe("page", function() {
			describe("as a link", function() {
				it("with a relative URL locator", function() {
					server.respondWith("GET", "/index.html", [200, { "Content-Type": "text/html"},
						"<link rel=\"icon\" href=\"//www.kitty.com/meow/favicon.ico\"></body"]);
					server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

					runs(function() {
						faviconSearchForDeclared("/index.html", function(favicon_path) {
							path = favicon_path;
							error = false;

							done = true;
						}, function() {
							error = true;

							done = true;
						});

						server.respond();
					});

					waitsFor(function() {
						return done;
					}, "The favicon path should be found.", 500);

					runs(function() {
						expect(done).toBe(true);
						expect(error).toBe(false);
						expect(path).toMatch("http://www.kitty.com/meow/favicon.ico");
					});
				});

				describe("with a relative path", function() {
					describe("prefixed by a '/'", function() {
						it("in a URL with a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index.html", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"/meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index.html", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://kitty.com/meow/favicon.ico");
							});
						});

						it("in a URL without a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"/meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://kitty.com/meow/favicon.ico");
							});
						});
					});

					describe("not prefixed by a '/'", function() {
						it("in a URL with a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index.html", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index.html", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://kitty.com/meow/favicon.ico");
							});
						});
					});
				});
			});
		});
	});
});<commit_msg>Test to match includes 'www'.<commit_after>describe("Sites", function() {
	describe("should find the favicon in the", function() {
		var path, error, server;

		beforeEach(function() {
			path = '';
			error = false;

			done = false;

			server = sinon.fakeServer.create();
		});

		afterEach(function() {
			server.restore();
		});

		describe("root directory", function() {
			it("with no folders", function() {
				server.respondWith("GET", "/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchRoot("/", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/favicon.ico");
				});
			});

			it("with folders", function() {
				server.respondWith("GET", "/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchRoot("/kitty/is/here", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/favicon.ico");
				});
			});

			it("with failures", function() {
				runs(function() {
					faviconSearchRoot("/", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(true);
					expect(path).toMatch("");
				});
			});
		});

		describe("current directory", function() {
			it("as is", function() {
				server.respondWith("GET", "/kitty/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

				runs(function() {
					faviconSearchCurrent("/kitty", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(false);
					expect(path).toMatch("/kitty/favicon.ico");
				});
			});

			it("with failures", function() {
				runs(function() {
					faviconSearchCurrent("/kitty", function(favicon_path) {
						path = favicon_path;
						error = false;

						done = true;
					}, function() {
						error = true;

						done = true;
					});

					server.respond();
				});

				waitsFor(function() {
					return done;
				}, "The favicon path should be found.", 500);

				runs(function() {
					expect(done).toBe(true);
					expect(error).toBe(true);
					expect(path).toMatch("");
				});
			});
		});

		describe("page", function() {
			describe("as a link", function() {
				it("with a relative URL locator", function() {
					server.respondWith("GET", "/index.html", [200, { "Content-Type": "text/html"},
						"<link rel=\"icon\" href=\"//www.kitty.com/meow/favicon.ico\"></body"]);
					server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

					runs(function() {
						faviconSearchForDeclared("/index.html", function(favicon_path) {
							path = favicon_path;
							error = false;

							done = true;
						}, function() {
							error = true;

							done = true;
						});

						server.respond();
					});

					waitsFor(function() {
						return done;
					}, "The favicon path should be found.", 500);

					runs(function() {
						expect(done).toBe(true);
						expect(error).toBe(false);
						expect(path).toMatch("http://www.kitty.com/meow/favicon.ico");
					});
				});

				describe("with a relative path", function() {
					describe("prefixed by a '/'", function() {
						it("in a URL with a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index.html", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"/meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index.html", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://kitty.com/meow/favicon.ico");
							});
						});

						it("in a URL without a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"/meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://kitty.com/meow/favicon.ico");
							});
						});
					});

					describe("not prefixed by a '/'", function() {
						it("in a URL with a page", function() {
							server.respondWith("GET", "http://www.kitty.com/index.html", [200, { "Content-Type": "text/html"},
								"<link rel=\"icon\" href=\"meow/favicon.ico\"></body"]);
							server.respondWith("GET", "http://www.kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);
							server.respondWith("GET", "http://kitty.com/meow/favicon.ico", [200, { "Content-Type": "image/png"}, ""]);

							runs(function() {
								faviconSearchForDeclared("http://www.kitty.com/index.html", function(favicon_path) {
									path = favicon_path;
									error = false;

									done = true;
								}, function() {
									error = true;

									done = true;
								});

								server.respond();
							});

							waitsFor(function() {
								return done;
							}, "The favicon path should be found.", 500);

							runs(function() {
								expect(done).toBe(true);
								expect(error).toBe(false);
								expect(path).toMatch("http://www.kitty.com/meow/favicon.ico");
							});
						});
					});
				});
			});
		});
	});
});<|endoftext|>


<commit_before>var Lab = require('lab')
var Code = require('code')
var lab = exports.lab = Lab.script()

var experiment = lab.experiment
var test = lab.test
var beforeEach = lab.beforeEach
var afterEach = lab.afterEach
var expect = Code.expect

var multiaddr = require('multiaddr')
var Id = require('ipfs-peer-id')
var Peer = require('ipfs-peer')
var Swarm = require('../src/')
var Identify = require('../src/identify')

var swarmA
var swarmB
var peerA
var peerB

beforeEach(function (done) {
  swarmA = new Swarm()
  swarmB = new Swarm()
  var c = new Counter(2, done)

  swarmA.listen(8100, function () {
    peerA = new Peer(Id.create(), [multiaddr('/ip4/127.0.0.1/tcp/' + swarmA.port)])
    c.hit()
  })

  swarmB.listen(8101, function () {
    peerB = new Peer(Id.create(), [multiaddr('/ip4/127.0.0.1/tcp/' + swarmB.port)])
    c.hit()
  })

})

afterEach(function (done) {
  swarmA.closeListener()
  swarmB.closeListener()
  done()
})

experiment('BASE', function () {
  test('Open a stream', function (done) {
    var protocol = '/sparkles/3.3.3'
    var c = new Counter(2, done)

    swarmB.registerHandler(protocol, function (stream) {
      c.hit()
    })

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
      c.hit()
    })
  })

  test('Reuse connection (from dialer)', function (done) {
    var protocol = '/sparkles/3.3.3'

    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)

      swarmA.openStream(peerB, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
        expect(swarmA.connections.length === 1)
        done()
      })
    })
  })
  test('Check for lastSeen', function (done) {
    var protocol = '/sparkles/3.3.3'

    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
      expect(peerB.lastSeen).to.be.instanceof(Date)
      done()
    })
  })

})

experiment('IDENTIFY', function () {
  test('Attach Identify, open a stream, see a peer update', function (done) {
    swarmA.on('error', function (err) {
      console.log('A - ', err)
    })

    swarmB.on('error', function (err) {
      console.log('B - ', err)
    })

    var protocol = '/sparkles/3.3.3'

    var identifyA = new Identify(swarmA, peerA)
    var identifyB = new Identify(swarmB, peerB)
    setTimeout(function () {
      swarmB.registerHandler(protocol, function (stream) {})

      swarmA.openStream(peerB, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
      })

      identifyB.on('peer-update', function (answer) {
        done()
      })
      identifyA.on('peer-update', function (answer) {})
    }, 500)
  })

  test('Attach Identify, open a stream, reuse stream', function (done) {
    console.log('\n\n\n')

    var protocol = '/sparkles/3.3.3'

    var identifyA = new Identify(swarmA, peerA)
    var identifyB = new Identify(swarmB, peerB)

    swarmA.registerHandler(protocol, function (stream) {})
    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
    })

    identifyB.on('peer-update', function (answer) {
      expect(Object.keys(swarmB.connections).length).to.equal(1)
      swarmB.openStream(peerA, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
        expect(Object.keys(swarmB.connections).length).to.equal(1)
        done()
      })
    })
    identifyA.on('peer-update', function (answer) {})
  })

})

experiment('HARDNESS', function () {})

function Counter (target, callback) {
  var c = 0
  this.hit = count

  function count () {
    c += 1
    if (c === target) {
      callback()
    }
  }
}

// function checkErr (err) {
//   console.log('err')
//  expect(err).to.be.instanceof(Error)
//  }
<commit_msg>Start adding more swarm tests<commit_after>var Lab = require('lab')
var Code = require('code')
var lab = exports.lab = Lab.script()

var experiment = lab.experiment
var test = lab.test
var beforeEach = lab.beforeEach
var afterEach = lab.afterEach
var expect = Code.expect

var multiaddr = require('multiaddr')
var Id = require('ipfs-peer-id')
var Peer = require('ipfs-peer')
var Swarm = require('../src/')
var Identify = require('../src/identify')

var swarmA
var swarmB
var peerA
var peerB

beforeEach(function (done) {
  swarmA = new Swarm()
  swarmB = new Swarm()
  var c = new Counter(2, done)

  swarmA.listen(8100, function () {
    peerA = new Peer(Id.create(), [multiaddr('/ip4/127.0.0.1/tcp/' + swarmA.port)])
    c.hit()
  })

  swarmB.listen(8101, function () {
    peerB = new Peer(Id.create(), [multiaddr('/ip4/127.0.0.1/tcp/' + swarmB.port)])
    c.hit()
  })

})

afterEach(function (done) {
  swarmA.closeListener()
  swarmB.closeListener()
  done()
})

experiment('BASICS', function () {
  experiment('Swarm', function () {
    test('enforces instantiation with new', function (done) {
      expect(function () {
        Swarm()
      }).to.throw('Swarm must be called with new')
      done()
    })

    test('parses $IPFS_SWARM_PORT', function (done) {
      process.env.IPFS_SWARM_PORT = 1111
      var swarm = new Swarm()
      expect(swarm.port).to.be.equal(1111)
      process.env.IPFS_SWARM_PORT = undefined
      done()
    })
  })

  experiment('Swarm.listen', function (done) {
    test('handles missing port', function (done) {
      var swarm = new Swarm()
      swarm.listen(done)
    })

    test('handles passed in port', function (done) {
      var swarm = new Swarm()
      swarm.listen(1234)
      expect(swarm.port).to.be.equal(1234)
      done()
    })
  })
})

experiment('BASE', function () {
  test('Open a stream', function (done) {
    var protocol = '/sparkles/3.3.3'
    var c = new Counter(2, done)

    swarmB.registerHandler(protocol, function (stream) {
      c.hit()
    })

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
      c.hit()
    })
  })

  test('Reuse connection (from dialer)', function (done) {
    var protocol = '/sparkles/3.3.3'

    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)

      swarmA.openStream(peerB, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
        expect(swarmA.connections.length === 1)
        done()
      })
    })
  })
  test('Check for lastSeen', function (done) {
    var protocol = '/sparkles/3.3.3'

    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
      expect(peerB.lastSeen).to.be.instanceof(Date)
      done()
    })
  })

})

experiment('IDENTIFY', function () {
  test('Attach Identify, open a stream, see a peer update', function (done) {
    swarmA.on('error', function (err) {
      console.log('A - ', err)
    })

    swarmB.on('error', function (err) {
      console.log('B - ', err)
    })

    var protocol = '/sparkles/3.3.3'

    var identifyA = new Identify(swarmA, peerA)
    var identifyB = new Identify(swarmB, peerB)
    setTimeout(function () {
      swarmB.registerHandler(protocol, function (stream) {})

      swarmA.openStream(peerB, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
      })

      identifyB.on('peer-update', function (answer) {
        done()
      })
      identifyA.on('peer-update', function (answer) {})
    }, 500)
  })

  test('Attach Identify, open a stream, reuse stream', function (done) {
    console.log('\n\n\n')

    var protocol = '/sparkles/3.3.3'

    var identifyA = new Identify(swarmA, peerA)
    var identifyB = new Identify(swarmB, peerB)

    swarmA.registerHandler(protocol, function (stream) {})
    swarmB.registerHandler(protocol, function (stream) {})

    swarmA.openStream(peerB, protocol, function (err, stream) {
      expect(err).to.not.be.instanceof(Error)
    })

    identifyB.on('peer-update', function (answer) {
      expect(Object.keys(swarmB.connections).length).to.equal(1)
      swarmB.openStream(peerA, protocol, function (err, stream) {
        expect(err).to.not.be.instanceof(Error)
        expect(Object.keys(swarmB.connections).length).to.equal(1)
        done()
      })
    })
    identifyA.on('peer-update', function (answer) {})
  })

})

experiment('HARDNESS', function () {})

function Counter (target, callback) {
  var c = 0
  this.hit = count

  function count () {
    c += 1
    if (c === target) {
      callback()
    }
  }
}

// function checkErr (err) {
//   console.log('err')
//  expect(err).to.be.instanceof(Error)
//  }
<|endoftext|>


<commit_before>/*!
* Flocking - Creative audio synthesis for the Web!
* http://github.com/colinbdclark/flocking
*
* Copyright 2011, Colin Clark
* Dual licensed under the MIT or GPL Version 2 licenses.
*/

/*global module, test, expect, ok, equals, deepEqual, Float32Array*/
/*jslint white: true, vars: true, plusplus: true, undef: true, newcap: true, regexp: true, browser: true,
    forin: true, continue: true, nomen: true, bitwise: true, maxerr: 100, indent: 4 */

var flock = flock || {};

(function () {
    "use strict";

    module("Time Converters");

    var testTimeConversion = function (expected, args, converter, msg) {
        args = $.makeArray(args);
        equal(expected, converter.apply(null, args), msg);
    };

    test("flock.time.secToMs", function () {
        testTimeConversion(1500, 1.5, flock.time.secToMs,
            "1.5 seconds should convert to 1500 ms.");
        testTimeConversion(0, 0, flock.time.secToMs,
            "0 seconds should convert to 0 ms.");
    });

    test("flock.time.bpmToMs", function () {
        var bpm = 60,
            oneBeat = 1 / bpm,
            oneBeatMs = oneBeat * 1000,
            expected;

        expected = 4 * oneBeatMs;
        testTimeConversion(expected, [4, bpm], flock.time.bpmToMs,
            "4 beats at 60 bpm seconds should convert to " + expected + " ms.");
        testTimeConversion(0, [0, bpm], flock.time.bpmToMs,
            "0 beats at 60 bpm should convert to 0 ms.");
        testTimeConversion(0, [100, 0], flock.time.bpmToMs,
            "100 beats at 0 bpm should convert to 0 ms.");
    });

    module("Asynchronous Scheduler tests");

    var checkScheduledCallback = function (scheduledTime, sentAt, receivedAt) {
        equals(scheduledTime, 500,
            "The callback for once() should return the correct scheduled time.");
        ok(sentAt >= receivedAt - 3,
            "The callback should have been called at the scheduled time, within a tolerance of 3 ms.");
    };

    asyncTest("flock.scheduler.async.once()", function () {
        var runs = 10,
            numRuns = 0,
            sked = flock.scheduler.async({
                timeConverter: null
            });

        expect(21);

        var scheduledAction = function (scheduledTime, now) {
            numRuns++;
            checkScheduledCallback(scheduledTime, now, Date.now());
            if (numRuns < runs) {
                sked.once(500, scheduledAction);
            } else {
                equals(numRuns, runs,
                    "The scheduled callback should be invoked only once.");
                start();
            }
        };
        sked.once(500, scheduledAction);
    });

    asyncTest("flock.scheduler.async.repeat()", function () {
        var sked = flock.scheduler.async({
                timeConverter: null
            }),
            expectedInterval = 100,
            numRuns = 100,
            runs = 0,
            lastFired = 0,
            mistimingTolerance = 5,
            callback;

        expect(2 * numRuns);

        callback = function () {
            var now = Date.now(),
                actualInterval = now - lastFired;

            if (runs >= numRuns) {
                sked.clearRepeat(expectedInterval);
                start();
                return;
            }

            ok(actualInterval >= expectedInterval - mistimingTolerance,
                "The scheduled callback should be fired no earlier than " + mistimingTolerance + " ms.");
            ok(actualInterval <= expectedInterval + mistimingTolerance,
                "The scheduled callback should be fired no later than " + mistimingTolerance + " ms.");

            runs++;
            lastFired = Date.now();
        };

        sked.repeat(expectedInterval, callback);
        lastFired = Date.now();
    });

    asyncTest("flock.scheduler.async.repeat() multiple listeners", function () {
        var sked = flock.scheduler.async({
                timeConverter: null
            }),
            interval = 100,
            numRuns = 10,
            runs = 0,
            fired = {},
            both = true,
            makeRecordingListener,
            testingListenerImpl,
            listener1,
            listener2,
            testingListener;

        makeRecordingListener = function (record, prop) {
            return function () {
                record[prop] = true;
            };
        };

        testingListenerImpl = function () {
            if (runs >= numRuns) {
                if (both) {
                    sked.clear(listener1);
                    both = false;
                    runs = 0;
                } else {
                    sked.clear(listener2);
                    sked.clear(testingListener);
                    expect(numRuns * 2);
                    start();
                }
                flock.clear(fired);
                return;
            }

            if (both) {
                deepEqual(fired, {
                    listener1: true,
                    listener2: true
                }, "Both listeners should fire.");
            } else {
                deepEqual(fired, {
                    listener2: true
                }, "After the first listener has been removed, only the second should fire.");
            }
            flock.clear(fired);
            runs++;
        };

        listener1 = sked.repeat(100, makeRecordingListener(fired, "listener1"));
        listener2 = sked.repeat(100, makeRecordingListener(fired, "listener2"));
        testingListener = sked.repeat(100, testingListenerImpl);
    });

    var testClearScheduler = function (name, clearFnName) {
        asyncTest(name, function () {
            var sked = flock.scheduler.async({
                    timeConverter: null
                }),
                interval = 100,
                numRuns = 10,
                runs = 0,
                fired = {},
                runNextTestStage,
                makeRecordingListener,
                listener1,
                listener2,
                stages;

            runNextTestStage = function () {
                var stage = stages.shift();
                sked[clearFnName](interval);

                if (stage) {
                    runs = 0;
                    sked.repeat(interval, stage);
                } else {
                    start();
                    expect(stages.length * 2);
                }
            };

            makeRecordingListener = function (record, prop) {
                return function () {
                    record[prop] = true;

                    if (runs >= numRuns) {
                        flock.test.assertSoleProperty(record, prop);
                        flock.clear(record);
                        runNextTestStage();
                        return;
                    }

                    runs++;
                };
            };

            stages = [
                makeRecordingListener(fired, "listener1"),
                makeRecordingListener(fired, "listener2")
            ];

            runNextTestStage();
        });
    };

    testClearScheduler("flock.scheduler.async.clearRepeat()", "clearRepeat");
    testClearScheduler("flock.scheduler.async.clearAll()", "clearAll");

}());
<commit_msg>Increases tolerance for mistimed events in the Scheduler's unit tests. This is due to the fact that async scheduler's timing appears to be less solid in Firefox.<commit_after>/*!
* Flocking - Creative audio synthesis for the Web!
* http://github.com/colinbdclark/flocking
*
* Copyright 2011, Colin Clark
* Dual licensed under the MIT or GPL Version 2 licenses.
*/

/*global module, test, expect, ok, equals, deepEqual, Float32Array*/
/*jslint white: true, vars: true, plusplus: true, undef: true, newcap: true, regexp: true, browser: true,
    forin: true, continue: true, nomen: true, bitwise: true, maxerr: 100, indent: 4 */

var flock = flock || {};

(function () {
    "use strict";

    module("Time Converters");

    var testTimeConversion = function (expected, args, converter, msg) {
        args = $.makeArray(args);
        equal(expected, converter.apply(null, args), msg);
    };

    test("flock.time.secToMs", function () {
        testTimeConversion(1500, 1.5, flock.time.secToMs,
            "1.5 seconds should convert to 1500 ms.");
        testTimeConversion(0, 0, flock.time.secToMs,
            "0 seconds should convert to 0 ms.");
    });

    test("flock.time.bpmToMs", function () {
        var bpm = 60,
            oneBeat = 1 / bpm,
            oneBeatMs = oneBeat * 1000,
            expected;

        expected = 4 * oneBeatMs;
        testTimeConversion(expected, [4, bpm], flock.time.bpmToMs,
            "4 beats at 60 bpm seconds should convert to " + expected + " ms.");
        testTimeConversion(0, [0, bpm], flock.time.bpmToMs,
            "0 beats at 60 bpm should convert to 0 ms.");
        testTimeConversion(0, [100, 0], flock.time.bpmToMs,
            "100 beats at 0 bpm should convert to 0 ms.");
    });

    module("Asynchronous Scheduler tests");

    var checkScheduledCallback = function (scheduledTime, sentAt, receivedAt) {
        equals(scheduledTime, 500,
            "The callback for once() should return the correct scheduled time.");
        ok(sentAt >= receivedAt - 3,
            "The callback should have been called at the scheduled time, within a tolerance of 3 ms.");
    };

    asyncTest("flock.scheduler.async.once()", function () {
        var runs = 10,
            numRuns = 0,
            sked = flock.scheduler.async({
                timeConverter: null
            });

        expect(21);

        var scheduledAction = function (scheduledTime, now) {
            numRuns++;
            checkScheduledCallback(scheduledTime, now, Date.now());
            if (numRuns < runs) {
                sked.once(500, scheduledAction);
            } else {
                equals(numRuns, runs,
                    "The scheduled callback should be invoked only once.");
                start();
            }
        };
        sked.once(500, scheduledAction);
    });

    asyncTest("flock.scheduler.async.repeat()", function () {
        var sked = flock.scheduler.async({
                timeConverter: null
            }),
            expectedInterval = 100,
            numRuns = 100,
            runs = 0,
            lastFired = 0,
            mistimingTolerance = 25,
            callback;

        expect(2 * numRuns);

        callback = function () {
            var now = Date.now(),
                actualInterval = now - lastFired;

            if (runs >= numRuns) {
                sked.clearRepeat(expectedInterval);
                start();
                return;
            }

            ok(actualInterval >= expectedInterval - mistimingTolerance,
                "The scheduled callback should be fired no earlier than " + mistimingTolerance + " ms.");
            ok(actualInterval <= expectedInterval + mistimingTolerance,
                "The scheduled callback should be fired no later than " + mistimingTolerance + " ms.");

            runs++;
            lastFired = Date.now();
        };

        sked.repeat(expectedInterval, callback);
        lastFired = Date.now();
    });

    asyncTest("flock.scheduler.async.repeat() multiple listeners", function () {
        var sked = flock.scheduler.async({
                timeConverter: null
            }),
            interval = 100,
            numRuns = 10,
            runs = 0,
            fired = {},
            both = true,
            makeRecordingListener,
            testingListenerImpl,
            listener1,
            listener2,
            testingListener;

        makeRecordingListener = function (record, prop) {
            return function () {
                record[prop] = true;
            };
        };

        testingListenerImpl = function () {
            if (runs >= numRuns) {
                if (both) {
                    sked.clear(listener1);
                    both = false;
                    runs = 0;
                } else {
                    sked.clear(listener2);
                    sked.clear(testingListener);
                    expect(numRuns * 2);
                    start();
                }
                flock.clear(fired);
                return;
            }

            if (both) {
                deepEqual(fired, {
                    listener1: true,
                    listener2: true
                }, "Both listeners should fire.");
            } else {
                deepEqual(fired, {
                    listener2: true
                }, "After the first listener has been removed, only the second should fire.");
            }
            flock.clear(fired);
            runs++;
        };

        listener1 = sked.repeat(100, makeRecordingListener(fired, "listener1"));
        listener2 = sked.repeat(100, makeRecordingListener(fired, "listener2"));
        testingListener = sked.repeat(100, testingListenerImpl);
    });

    var testClearScheduler = function (name, clearFnName) {
        asyncTest(name, function () {
            var sked = flock.scheduler.async({
                    timeConverter: null
                }),
                interval = 100,
                numRuns = 10,
                runs = 0,
                fired = {},
                runNextTestStage,
                makeRecordingListener,
                listener1,
                listener2,
                stages;

            runNextTestStage = function () {
                var stage = stages.shift();
                sked[clearFnName](interval);

                if (stage) {
                    runs = 0;
                    sked.repeat(interval, stage);
                } else {
                    start();
                    expect(stages.length * 2);
                }
            };

            makeRecordingListener = function (record, prop) {
                return function () {
                    record[prop] = true;

                    if (runs >= numRuns) {
                        flock.test.assertSoleProperty(record, prop);
                        flock.clear(record);
                        runNextTestStage();
                        return;
                    }

                    runs++;
                };
            };

            stages = [
                makeRecordingListener(fired, "listener1"),
                makeRecordingListener(fired, "listener2")
            ];

            runNextTestStage();
        });
    };

    testClearScheduler("flock.scheduler.async.clearRepeat()", "clearRepeat");
    testClearScheduler("flock.scheduler.async.clearAll()", "clearAll");

}());
<|endoftext|>


<commit_before>"use strict";

var sortBy = function(f) {
  return function(x,y) {
    if (f(x) > f(y)) {
      return 1;
    } else if (f(x) < f(y)) {
      return -1;
    } else {
      return 0;
    }
  };
};

var Strategy = {
  BruteForce: function(possibleArgs) {
    return possibleArgs;
  },
  Beam: function(width, scoreFn) {
    return function() {
      var args = Array.prototype.slice.call(arguments,0);
      args.sort(sortBy(scoreFn));
      return args.slice(0,width);
    };
  }
};

var assert = require('assert');

var smush2 = function(a,b) {
  if (b.indexOf(a) === 0) {
    return b;
  } else {
    return a[0] + smush2(a.substr(1), b);
  }
};

var nextArguments = function(args) {
  var x = args[0];
  var y = args[1];

  var rest = [smush2(x,y)];
  for (var i=2;i<args.length;++i) {
    rest.push(args[i]);
  }

  return rest;
}

var smush = function() {
  var n = arguments.length;

  if (n == 0) {
    return "";
  } else if (n == 1) {
    return arguments[0];
  } else {
    var rest = nextArguments(arguments);
    return smush.apply(null,rest);
  }
};

var score = function() {
  var sum = 0;
  for (var i=0;i<arguments.length;++i) {
     sum += arguments[i].length;
  }
  return sum;
};

var selectMinimumAccordingToScoreFn = function(xs) {
  return xs.reduce(function(x,y) {
      return score(y) < score(x) ? y : x;
    },xs[0]);
};

var allFutureArguments = function(args) {
  var allPossibilities = [];
  var n = args.length;
  for (var i=0;i<n;++i) {
    for (var j=0;j<n;++j) {
      if (j == i) {
        continue;
      }
      var x = args[i];
      var y = args[j];

      var rest = [smush(x,y)];
      for (var k=0;k<n;++k) {
        if (k !== i && k !== j) {
          rest.push(args[k]);
        }
      }
      allPossibilities.push(rest);
    }
  }
  return allPossibilities;
};

var minimalSmush = function() {

  // Drop the first argument (which is a strategy)
  var n = arguments.length - 1;
  var selection = arguments[0];
  var args = [];
  for (var i=1;i<arguments.length;++i) {
    args.push(arguments[i]);
  }

  if (n == 0) {
    return ;
  } else if (n == 1) {
    return args[0];
  } else {

    var allPossibilities = selection(allFutureArguments(args));

    var everything = allPossibilities.map(function(args) {
      return smush.apply(null, args);
    });

    return everything.reduce(function(x,y) {
      return score(y) < score(x) ? y : x;
    },everything[0]);
  }
};

describe('word smushing', function() {

  describe('strategy', function() {
    it('is a brute force strategy', function() {
      var args = [['a','b'],['c','d']];
      var result = Strategy.BruteForce.apply(null,args);
      assert.equal(args.length, result.length);
    });

    it('is a beam search', function() {
      var args = ['abcdef','abcde', 'abcd','abc', 'ab', 'a'];

      var result = Strategy.Beam(2, score).apply(null, args);
      assert.equal(2, result.length);
    });

    it('beam search detects based on scoring function', function() {
      var args = ['abcdef','abcde', 'abcd','abc', 'ab', 'a'];
      var result = Strategy.Beam(2,score).apply(null, args);

      assert.equal('a', result[0]);
      assert.equal('ab', result[1]);
    });
  });

  describe('scoring function', function() {
    it('is just length of args summed', function() {
      assert.equal(10, score('fives', 'a','duck'));
    });
  });

  describe('two work smushing', function() {
    it('should smush two equal words', function() {
      var smushed = smush2('to','to');
      assert.equal('to', smushed);
    });

    it('should smush two letter words', function() {
      var smushed = smush2('it', 'to');
      assert.equal('ito', smushed);
    });

    it('should be conjunction  when doesn\'t smush', function() {
      var unsmushed = smush2('be', 'at');
      assert.equal('beat', unsmushed);
    });
  });

  describe('three word smushing', function() {
    it('should work for minimal example', function() {
      var smushed = smush('minutes','testing', 'ginger');
      assert.equal('minutestinginger', smushed);
    });
  });

  describe('finds minimal smush', function() {
    it('uses the strategy', function() {
      var used = false;
      var strategy = function(x) {
        used = true;
        return x;
      };

      var smushed = minimalSmush(strategy,'to', 'it');
      assert(used);
    });

    it('works with simple example', function() {
      var smushed = minimalSmush(Strategy.BruteForce,'to', 'it');
      assert.equal('ito', smushed);
    });

    it('works with a longer example', function() {
      var smushed = minimalSmush(
        Strategy.BruteForce,
        'testing',
        'ginger',
        'german',
        'minutes'
        );

      assert.equal('minutestingingerman', smushed);
    });

    it('still works with a beam search', function() {
      var smushed = minimalSmush(
        Strategy.Beam(3,score),
        'testing',
        'ginger',
        'german',
        'minutes'
        );

      assert.equal('minutestingingerman', smushed);
    });
  });
});
<commit_msg>whats the assert statement doing there....<commit_after>"use strict";
var assert = require('assert');

var sortBy = function(f) {
  return function(x,y) {
    if (f(x) > f(y)) {
      return 1;
    } else if (f(x) < f(y)) {
      return -1;
    } else {
      return 0;
    }
  };
};

var Strategy = {
  BruteForce: function(possibleArgs) {
    return possibleArgs;
  },
  Beam: function(width, scoreFn) {
    return function() {
      var args = Array.prototype.slice.call(arguments,0);
      args.sort(sortBy(scoreFn));
      return args.slice(0,width);
    };
  }
};

var smush2 = function(a,b) {
  if (b.indexOf(a) === 0) {
    return b;
  } else {
    return a[0] + smush2(a.substr(1), b);
  }
};

var nextArguments = function(args) {
  var x = args[0];
  var y = args[1];

  var rest = [smush2(x,y)];
  for (var i=2;i<args.length;++i) {
    rest.push(args[i]);
  }

  return rest;
}

var smush = function() {
  var n = arguments.length;

  if (n == 0) {
    return "";
  } else if (n == 1) {
    return arguments[0];
  } else {
    var rest = nextArguments(arguments);
    return smush.apply(null,rest);
  }
};

var score = function() {
  var sum = 0;
  for (var i=0;i<arguments.length;++i) {
     sum += arguments[i].length;
  }
  return sum;
};

var selectMinimumAccordingToScoreFn = function(xs) {
  return xs.reduce(function(x,y) {
      return score(y) < score(x) ? y : x;
    },xs[0]);
};

var allFutureArguments = function(args) {
  var allPossibilities = [];
  var n = args.length;
  for (var i=0;i<n;++i) {
    for (var j=0;j<n;++j) {
      if (j == i) {
        continue;
      }
      var x = args[i];
      var y = args[j];

      var rest = [smush(x,y)];
      for (var k=0;k<n;++k) {
        if (k !== i && k !== j) {
          rest.push(args[k]);
        }
      }
      allPossibilities.push(rest);
    }
  }
  return allPossibilities;
};

var minimalSmush = function() {

  // Drop the first argument (which is a strategy)
  var n = arguments.length - 1;
  var selection = arguments[0];
  var args = [];
  for (var i=1;i<arguments.length;++i) {
    args.push(arguments[i]);
  }

  if (n == 0) {
    return ;
  } else if (n == 1) {
    return args[0];
  } else {

    var allPossibilities = selection(allFutureArguments(args));

    var everything = allPossibilities.map(function(args) {
      return smush.apply(null, args);
    });

    return everything.reduce(function(x,y) {
      return score(y) < score(x) ? y : x;
    },everything[0]);
  }
};

describe('word smushing', function() {

  describe('strategy', function() {
    it('is a brute force strategy', function() {
      var args = [['a','b'],['c','d']];
      var result = Strategy.BruteForce.apply(null,args);
      assert.equal(args.length, result.length);
    });

    it('is a beam search', function() {
      var args = ['abcdef','abcde', 'abcd','abc', 'ab', 'a'];

      var result = Strategy.Beam(2, score).apply(null, args);
      assert.equal(2, result.length);
    });

    it('beam search detects based on scoring function', function() {
      var args = ['abcdef','abcde', 'abcd','abc', 'ab', 'a'];
      var result = Strategy.Beam(2,score).apply(null, args);

      assert.equal('a', result[0]);
      assert.equal('ab', result[1]);
    });
  });

  describe('scoring function', function() {
    it('is just length of args summed', function() {
      assert.equal(10, score('fives', 'a','duck'));
    });
  });

  describe('two work smushing', function() {
    it('should smush two equal words', function() {
      var smushed = smush2('to','to');
      assert.equal('to', smushed);
    });

    it('should smush two letter words', function() {
      var smushed = smush2('it', 'to');
      assert.equal('ito', smushed);
    });

    it('should be conjunction  when doesn\'t smush', function() {
      var unsmushed = smush2('be', 'at');
      assert.equal('beat', unsmushed);
    });
  });

  describe('three word smushing', function() {
    it('should work for minimal example', function() {
      var smushed = smush('minutes','testing', 'ginger');
      assert.equal('minutestinginger', smushed);
    });
  });

  describe('finds minimal smush', function() {
    it('uses the strategy', function() {
      var used = false;
      var strategy = function(x) {
        used = true;
        return x;
      };

      var smushed = minimalSmush(strategy,'to', 'it');
      assert(used);
    });

    it('works with simple example', function() {
      var smushed = minimalSmush(Strategy.BruteForce,'to', 'it');
      assert.equal('ito', smushed);
    });

    it('works with a longer example', function() {
      var smushed = minimalSmush(
        Strategy.BruteForce,
        'testing',
        'ginger',
        'german',
        'minutes'
        );

      assert.equal('minutestingingerman', smushed);
    });

    it('still works with a beam search', function() {
      var smushed = minimalSmush(
        Strategy.Beam(3,score),
        'testing',
        'ginger',
        'german',
        'minutes'
        );

      assert.equal('minutestingingerman', smushed);
    });
  });
});
<|endoftext|>


<commit_before>// todo
<commit_msg>Upload code about Local Storage (Player's name and score saved in local storage)<commit_after>//Player's name and score saved in local storage

//var scoreObject = (function(){
//    'use strict';
//
//    var score = 0;
//
//    function initScore() {
//        score = 0;
//    }
//
//    function updateScore(points) {
//        score = points;
//    }
//
//    function writeScore() {
//
////prompt the user for name
//        var username = prompt('Please enter your name:');
//
//        var scores = JSON.parse(localStorage['scores']) || [];
//        scores.push({username: username, score: score});
//        localStorage['scores'] = JSON.stringify(scores);
//    }
//
//    function readScore() {
//        var scores = JSON.parse(localStorage['scores']) || [];
//        return scores;
//    }
//
//    return {
//        initScore: initScore,
//        updateScore: updateScore,
//        writeScore: writeScore,
//        readScore: readScore
//    }
//}());<|endoftext|>


<commit_before>import { bindable, customAttribute } from 'aurelia-templating';
import { bindingMode, ObserverLocator } from 'aurelia-binding';
import { inject } from 'aurelia-dependency-injection';
import * as LogManager from 'aurelia-logging';

@inject(Element, LogManager, ObserverLocator)
@customAttribute('md-select')
export class MdSelect {
  @bindable({
    defaultBindingMode: bindingMode.twoWay
  }) selected;
  constructor(element, logManager, observerLocator) {
    this.element = element;
    this.handleChangeFromAurelia = this.handleChangeFromAurelia.bind(this);
    this.handleChangeFromNativeSelect = this.handleChangeFromNativeSelect.bind(this);
    this.log = LogManager.getLogger('md-select');
    this.observerLocator = observerLocator;
    this.valueObserver = this.observerLocator.getObserver(this.element, 'value');
  }
  attached() {
    this.valueObserver.subscribe(this.handleChangeFromAurelia);
    $(this.element).material_select();
    $(this.element).on('change', this.handleChangeFromNativeSelect);
  }

  detached() {
    $(this.element).off('change', this.handleChangeFromNativeSelect);
    $(this.element).material_select('destroy');
    this.valueObserver.unsubscribe();
  }

  handleChangeFromNativeSelect() {
    this.log.debug('handleChangeFromNativeSelect', this.element.value, $(this.element).val());
    this.valueObserver.synchronizeValue();
    this.valueObserver.notify();
  }

  handleChangeFromAurelia(newValue) {
    // this.selected = this.element.value;
    // this.selected = $(this.element).val();
    this.log.debug('handleChangeFromAurelia', newValue);
    this.selected = newValue;
    $(this.element).material_select();
  }

  // arraysAreEqual(array1, array2) {
  //   let result = true;
  //   if (array1 && array2) {
  //     if (typeof array1 === 'string') {
  //       // single select
  //       result = false;
  //     } else {
  //       result = (array1.length === array2.length) && array1.every(function(element, index) {
  //         return element === array2[index];
  //       });
  //     }
  //   } else {
  //     result = false;
  //   }
  //
  //   return result;
  // }

  // selectedChanged() {
  //   this.element.value = this.selected;
  //   // if (!this.arraysAreEqual($(this.element).val(), this.selected)) {
  //   //   $(this.element).val(this.selected);
  //   //   $(this.element).material_select();
  //   // }
  // }
}
<commit_msg>fix(md-select): fixed multiple selection<commit_after>import { customAttribute } from 'aurelia-templating';
import { ObserverLocator } from 'aurelia-binding';
import { inject } from 'aurelia-dependency-injection';
import * as LogManager from 'aurelia-logging';

@inject(Element, LogManager, ObserverLocator)
@customAttribute('md-select')
export class MdSelect {
  _suspendUpdate = false;

  constructor(element, logManager, observerLocator) {
    this.element = element;
    this.handleChangeFromViewModel = this.handleChangeFromViewModel.bind(this);
    this.handleChangeFromNativeSelect = this.handleChangeFromNativeSelect.bind(this);
    this.log = LogManager.getLogger('md-select');
    this.observerLocator = observerLocator;
    this.valueObserver = this.observerLocator.getObserver(this.element, 'value');
  }
  attached() {
    this.valueObserver.subscribe(this.handleChangeFromViewModel);
    $(this.element).material_select();
    $(this.element).on('change', this.handleChangeFromNativeSelect);
  }

  detached() {
    $(this.element).off('change', this.handleChangeFromNativeSelect);
    $(this.element).material_select('destroy');
    this.valueObserver.unsubscribe();
  }

  handleChangeFromNativeSelect() {
    this.log.debug('handleChangeFromNativeSelect', this.element.value, $(this.element).val());
    // Aurelia's select observer doesn't get noticed when something changes the
    // select value directly (this.element.value = "something"). So we trigger
    // the change here.
    this.valueObserver.value = $(this.element).val();
    this.valueObserver.synchronizeValue();
    this.valueObserver.synchronizeOptions();
    this._suspendUpdate = true;
    this.valueObserver.notify();
    this._suspendUpdate = false;
  }

  handleChangeFromViewModel(newValue) {
    // this.selected = this.element.value;
    // this.selected = $(this.element).val();
    this.log.debug('handleChangeFromViewModel', newValue, $(this.element).val());
    if (!this._suspendUpdate) {
      $(this.element).material_select();
    }
  }

  // arraysAreEqual(array1, array2) {
  //   let result = true;
  //   if (array1 && array2) {
  //     if (typeof array1 === 'string') {
  //       // single select
  //       result = false;
  //     } else {
  //       result = (array1.length === array2.length) && array1.every(function(element, index) {
  //         return element === array2[index];
  //       });
  //     }
  //   } else {
  //     result = false;
  //   }
  //
  //   return result;
  // }

  // selectedChanged() {
  //   this.element.value = this.selected;
  //   // if (!this.arraysAreEqual($(this.element).val(), this.selected)) {
  //   //   $(this.element).val(this.selected);
  //   //   $(this.element).material_select();
  //   // }
  // }
}
<|endoftext|>


<commit_before><commit_msg>static: make sure Gruntfile default task actually runs Jekyll<commit_after><|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var fs = require('fs');

module.exports = function (grunt) {
    require('time-grunt')(grunt);

    grunt.initConfig({
        // Configurable paths
        config: {
            lintFiles: [
                '**/*.js'
            ]
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                '<%= config.lintFiles %>'
            ]
        },
        jscs: {
            options: {
                config: '.jscsrc'
            },
            src: '<%= config.lintFiles %>'
        }
    });

    grunt.registerTask('lint', [
        'jshint',
        'jscs'
    ]);

    grunt.registerTask('test', [
        'lint'
    ]);
};
<commit_msg>remove unused node module imports<commit_after>'use strict';

module.exports = function (grunt) {
    require('time-grunt')(grunt);

    grunt.initConfig({
        // Configurable paths
        config: {
            lintFiles: [
                '**/*.js'
            ]
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                '<%= config.lintFiles %>'
            ]
        },
        jscs: {
            options: {
                config: '.jscsrc'
            },
            src: '<%= config.lintFiles %>'
        }
    });

    grunt.registerTask('lint', [
        'jshint',
        'jscs'
    ]);

    grunt.registerTask('test', [
        'lint'
    ]);
};
<|endoftext|>