<commit_before>/**
 * Collection of test assertions helpers
 *
 * It mixes in the native node.js `assert` module. So you can just use this module as a
 * drop-in replacement.
 *
 * @module
 * @alias test/assert
 * @mixes nodejs/assert
 * @example
 *   var assert = require('yeoman-generator').assert;
 */
'use strict';

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

// Extend the native assert module
var assert = module.exports = require('assert');

/**
 * Assert that a file exists
 * @param  {String}       file     - path to a file
 * @example
 * assert.file('templates/user.hbs');
 *
 * @also
 *
 * Assert that each of an array of files exists
 * @param {Array}         pairs    - an array of paths to files
 * @example
 * assert.file(['templates/user.hbs', 'templates/user/edit.hbs']);
 *
 * @also
 *
 * Assert that a file's content matches a regex
 * @deprecated
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.file('models/user.js', /App\.User = DS\.Model\.extend/);
 */

assert.file = function () {
  var args = _.toArray(arguments);
  if (_.last(args) instanceof RegExp) {  // DEPRECATED CASE
    var depMsg = 'assert.file(String, RegExp) DEPRECATED; use ';
    depMsg += 'assert.fileContent(String, RegExp) instead.';
    console.log(depMsg);
    assert.fileContent(args[0], args[1]);
  } else {
    args = _.isString(args[0]) ? args : args[0];
    args.forEach(function (file) {
      var here = fs.existsSync(file);
      assert.ok(here, file + ', no such file or directory');
    });
  }
};

/**
 * Assert that a file doesn't exist
 * @param  {String}       file     - path to a file
 * @example
 * assert.noFile('templates/user.hbs');
 *
 * @also
 *
 * Assert that each of an array of files doesn't exist
 * @param {Array}         pairs    - an array of paths to files
 * @example
 * assert.noFile(['templates/user.hbs', 'templates/user/edit.hbs']);
 */

assert.noFile = function () {
  var args = _.toArray(arguments);
  args = _.isString(args[0]) ? args : args[0];
  args.forEach(function (file) {
    var here = fs.existsSync(file);
    assert.ok(!here, file + ' exists');
  });
};

/**
 * Assert that each of an array of files exists. If an item is an array with
 * the first element a filepath and the second element a regex, check to see
 * that the file content matches the regex
 * @deprecated
 * @param {Array} pairs - an array of paths to files or file/regex subarrays
 * @example
 * file(['templates/user.hbs', 'templates/user/edit.hbs']);
 * @example
 * files(['foo.js', 'bar.js', ['baz.js', /function baz/]]);
 */

assert.files = function (files) {
  var depMsg = 'assert.files deprecated. Use ';
  depMsg += 'assert.file([String, String, ...]) or ';
  depMsg += 'assert.file([[String, RegExp], [String, RegExp]...]) instead.';
  console.log(depMsg);
  files.forEach(function (item) {
    var file = item;
    var rx;
    if (item instanceof Array) {
      file = item[0];
      rx = item[1];
      assert.fileContent(file, rx);
    } else {
      assert.file(file);
    }
  });
};

/**
 * Assert that a file's content matches a regex
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.fileContent('models/user.js', /App\.User = DS\.Model\.extend/);
 *
 * @also
 *
 * Assert that each file in an array of file-regex pairs matches its corresponding regex
 * @param {Array}         pairs    - an array of arrays, where each subarray is a [String, RegExp] pair
 * @example
 * var arg = [
 *   [ 'models/user.js', /App\.User \ DS\.Model\.extend/ ],
 *   [ 'controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/ ]
 * ]
 * assert.fileContent(arg);
 */

assert.fileContent = function () {
  var args = _.toArray(arguments);
  var pairs = _.isString(args[0]) ? [args] : args[0];
  pairs.forEach(function (pair) {
    var file = pair[0];
    var regex = pair[1];
    assert.file(file);
    var body = fs.readFileSync(file, 'utf8');
    assert.ok(regex.test(body), file + ' did not match \'' + regex + '\'.');
  });
};

/**
 * Assert that a file's content does not match a regex
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.noFileContent('models/user.js', /App\.User = DS\.Model\.extend/);
 *
 * @also
 *
 * Assert that each file in an array of file-regex pairs does not match its corresponding regex
 * @param {Array}         pairs    - an array of arrays, where each subarray is a [String, RegExp] pair
 * var arg = [
 *   [ 'models/user.js', /App\.User \ DS\.Model\.extend/ ],
 *   [ 'controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/ ]
 * ]
 * assert.noFileContent(arg);
 */

assert.noFileContent = function (file, reg) {
  var args = _.toArray(arguments);
  var pairs = _.isString(args[0]) ? [args] : args[0];
  pairs.forEach(function (pair) {
    var file = pair[0];
    var regex = pair[1];
    assert.file(file);
    var body = fs.readFileSync(file, 'utf8');
    assert.ok(!regex.test(body), file + ' did not match \'' + regex + '\'.');
  });
};

/**
 * Assert that two strings are equal after standardization of newlines
 * @param {String} value - a string
 * @param {String} expected - the expected value of the string
 * @example
 * assert.textEqual('I have a yellow cat', 'I have a yellow cat');
 */

assert.textEqual = function (value, expected) {
  function eol(str) {
    return str.replace(/\r\n/g, '\n');
  }

  assert.equal(eol(value), eol(expected));
};

/**
 * Assert an Object implements an interface
 * @param  {Object}       subject - subject implementing the façade
 * @param  {Object|Array} methods - a façace, hash or array of keys to be implemented
 */

assert.implement = function (subject, methods) {
  methods = _.isArray(methods) ? methods : Object.keys(methods).filter(function (method) {
    return _.isFunction(methods[method]);
  });

  var pass = methods.filter(function (method) {
    return !_.isFunction(subject[method]);
  });

  assert.ok(pass.length === 0, 'expected object to implement the complete interface');
};
<commit_msg>Improve jsdoc markup<commit_after>/**
 * Collection of test assertions helpers
 *
 * It mixes in the native node.js `assert` module. So you can just use this module as a
 * drop-in replacement.
 *
 * @module test/assert
 * @mixes nodejs/assert
 * @example
 *   var assert = require('yeoman-generator').assert;
 */
'use strict';

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

// Extend the native assert module
/** @alias module:test/assert */
var assert = module.exports = require('assert');

/**
 * Assert that a file exists
 * @param  {String}       file     - path to a file
 * @example
 * assert.file('templates/user.hbs');
 *
 * @also
 *
 * Assert that each of an array of files exists
 * @param {Array}         pairs    - an array of paths to files
 * @example
 * assert.file(['templates/user.hbs', 'templates/user/edit.hbs']);
 *
 * @also
 *
 * Assert that a file's content matches a regex
 * @deprecated
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.file('models/user.js', /App\.User = DS\.Model\.extend/);
 */

assert.file = function () {
  var args = _.toArray(arguments);
  if (_.last(args) instanceof RegExp) {  // DEPRECATED CASE
    var depMsg = 'assert.file(String, RegExp) DEPRECATED; use ';
    depMsg += 'assert.fileContent(String, RegExp) instead.';
    console.log(depMsg);
    assert.fileContent(args[0], args[1]);
  } else {
    args = _.isString(args[0]) ? args : args[0];
    args.forEach(function (file) {
      var here = fs.existsSync(file);
      assert.ok(here, file + ', no such file or directory');
    });
  }
};

/**
 * Assert that a file doesn't exist
 * @param  {String}       file     - path to a file
 * @example
 * assert.noFile('templates/user.hbs');
 *
 * @also
 *
 * Assert that each of an array of files doesn't exist
 * @param {Array}         pairs    - an array of paths to files
 * @example
 * assert.noFile(['templates/user.hbs', 'templates/user/edit.hbs']);
 */

assert.noFile = function () {
  var args = _.toArray(arguments);
  args = _.isString(args[0]) ? args : args[0];
  args.forEach(function (file) {
    var here = fs.existsSync(file);
    assert.ok(!here, file + ' exists');
  });
};

/**
 * Assert that each of an array of files exists. If an item is an array with
 * the first element a filepath and the second element a regex, check to see
 * that the file content matches the regex
 * @deprecated
 * @param {Array} pairs - an array of paths to files or file/regex subarrays
 * @example
 * file(['templates/user.hbs', 'templates/user/edit.hbs']);
 * @example
 * files(['foo.js', 'bar.js', ['baz.js', /function baz/]]);
 */

assert.files = function (files) {
  var depMsg = 'assert.files deprecated. Use ';
  depMsg += 'assert.file([String, String, ...]) or ';
  depMsg += 'assert.file([[String, RegExp], [String, RegExp]...]) instead.';
  console.log(depMsg);
  files.forEach(function (item) {
    var file = item;
    var rx;
    if (item instanceof Array) {
      file = item[0];
      rx = item[1];
      assert.fileContent(file, rx);
    } else {
      assert.file(file);
    }
  });
};

/**
 * Assert that a file's content matches a regex
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.fileContent('models/user.js', /App\.User = DS\.Model\.extend/);
 *
 * @also
 *
 * Assert that each file in an array of file-regex pairs matches its corresponding regex
 * @param {Array}         pairs    - an array of arrays, where each subarray is a [String, RegExp] pair
 * @example
 * var arg = [
 *   [ 'models/user.js', /App\.User \ DS\.Model\.extend/ ],
 *   [ 'controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/ ]
 * ]
 * assert.fileContent(arg);
 */

assert.fileContent = function () {
  var args = _.toArray(arguments);
  var pairs = _.isString(args[0]) ? [args] : args[0];
  pairs.forEach(function (pair) {
    var file = pair[0];
    var regex = pair[1];
    assert.file(file);
    var body = fs.readFileSync(file, 'utf8');
    assert.ok(regex.test(body), file + ' did not match \'' + regex + '\'.');
  });
};

/**
 * Assert that a file's content does not match a regex
 * @param  {String}       file     - path to a file
 * @param  {Regex}        reg      - regex that will be used to search the file
 * @example
 * assert.noFileContent('models/user.js', /App\.User = DS\.Model\.extend/);
 *
 * @also
 *
 * Assert that each file in an array of file-regex pairs does not match its corresponding regex
 * @param {Array}         pairs    - an array of arrays, where each subarray is a [String, RegExp] pair
 * var arg = [
 *   [ 'models/user.js', /App\.User \ DS\.Model\.extend/ ],
 *   [ 'controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/ ]
 * ]
 * assert.noFileContent(arg);
 */

assert.noFileContent = function (file, reg) {
  var args = _.toArray(arguments);
  var pairs = _.isString(args[0]) ? [args] : args[0];
  pairs.forEach(function (pair) {
    var file = pair[0];
    var regex = pair[1];
    assert.file(file);
    var body = fs.readFileSync(file, 'utf8');
    assert.ok(!regex.test(body), file + ' did not match \'' + regex + '\'.');
  });
};

/**
 * Assert that two strings are equal after standardization of newlines
 * @param {String} value - a string
 * @param {String} expected - the expected value of the string
 * @example
 * assert.textEqual('I have a yellow cat', 'I have a yellow cat');
 */

assert.textEqual = function (value, expected) {
  function eol(str) {
    return str.replace(/\r\n/g, '\n');
  }

  assert.equal(eol(value), eol(expected));
};

/**
 * Assert an Object implements an interface
 * @param  {Object}       subject - subject implementing the façade
 * @param  {Object|Array} methods - a façace, hash or array of keys to be implemented
 */

assert.implement = function (subject, methods) {
  methods = _.isArray(methods) ? methods : Object.keys(methods).filter(function (method) {
    return _.isFunction(methods[method]);
  });

  var pass = methods.filter(function (method) {
    return !_.isFunction(subject[method]);
  });

  assert.ok(pass.length === 0, 'expected object to implement the complete interface');
};
<|endoftext|>


<commit_before>import {loadRuntimeApi, run} from "../../src/redux/actionCreators";
import configureStore from "redux-mock-store";
import thunk from 'redux-thunk';

describe("The actionCreators'", () => {

  const middlewares = [thunk];
  const mockStore = configureStore(middlewares);

  describe("loadRuntimeApi function", () => {
    var resolve, reject, store;

    beforeEach(() => {
      var runtimeApiLoader = function() {
        return new Promise(function(_resolve, _reject) {
          resolve = _resolve;
          reject = _reject;
        });
      };
      store = mockStore({}); //initial state of the store
      store.dispatch(loadRuntimeApi(runtimeApiLoader));
    });

    it("dispatches a START_LOAD_RUNTIME action first", () => {
      expect(store.getActions()[0]).toEqual({type: "START_LOAD_RUNTIME"});
    });

    it("dispatches a FINISH_LOAD_RUNTIME after the runtime is loaded", (done) => {
      resolve("the runtime api");
      window.setTimeout(() => {
        expect(store.getActions()[1])
          .toEqual({type: "FINISH_LOAD_RUNTIME", payload: "the runtime api"});
        done();
      }, 0);
    });

    it("dispatches a FAIL_LOAD_RUNTIME after the promise is rejected", (done) => {
      reject("some error");
      window.setTimeout(() => {
        expect(store.getActions()[1])
          .toEqual({type: "FAIL_LOAD_RUNTIME", payload: "some error"});
        done();
      }, 0);
    });
  });

  describe("run function,", () => {

    var getState, parseResolve, parseReject, compileResolve, compileReject, executeResolve, executeReject, store;
    var src = "some source code";

    beforeEach(() => {
      getState = () => ({
        runtimeApi: {
          parse() {
            return new Promise((_resolve, _reject) => {
              parseResolve = _resolve;
              parseReject = _reject;
            });
          },
          compile() {
            return new Promise((_resolve, _reject) => {
              compileResolve = _resolve;
              compileReject = _reject;
            });
          },
          execute() {
            return new Promise((_resolve, _reject) => {
              executeResolve = _resolve;
              executeReject = _reject;
            });
          }
        }
      });
      store = mockStore(getState());
      store.dispatch(run(src));
    });

    it("dispatches a START_PARSE action first", () => {
      expect(store.getActions()[0]).toEqual({type: "START_PARSE", stage: 'parsing'});
    });

    describe("after calling the parse function,", () => {

      it("dispatches a FINISH_PARSE action once the source code is parsed", (done) => {
        parseResolve("the ast");
        window.setTimeout(() => {
          expect(store.getActions()[1])
            .toEqual({type: "FINISH_PARSE", payload: "the ast"});
          done();
        }, 0);
      });

      it("dispatches a START_COMPILE action once the source code is parsed", (done) => {
        parseResolve("the src");
        window.setTimeout(() => {
          expect(store.getActions()[2])
            .toEqual({type: "START_COMPILE", stage: 'compiling'});
          done();
        }, 0);
      });

      it("dispatches a FAIL_PARSE action once the first promise is rejected", (done) => {
        parseReject("some error");
        window.setTimeout(() => {
          expect(store.getActions()[1])
            .toEqual({type: "FAIL_PARSE", payload: "some error"});
          done();
        }, 0);
      });

      describe("and the compile function,", () => {

        beforeEach((done) => {
          parseResolve("the ast");
          window.setTimeout(done, 0);
        });

        it("dispatches a FINISH_COMPILE action once the ast is compiled", (done) => {
          compileResolve("the byte code");
          window.setTimeout(() => {
            expect(store.getActions()[3])
              .toEqual({type: "FINISH_COMPILE", payload: 'the byte code'});
            done();
          }, 0);
        });

        it("dispatches a START_EXECUTE action once the ast is compiled", (done) => {
          compileResolve("the bytecode");
          window.setTimeout(() => {
            expect(store.getActions()[4])
              .toEqual({type: "START_EXECUTE", stage: 'executing'});
            done();
          }, 0);
        });

        it("dispatches a FAIL_COMPILE action once the second promise is rejected", (done) => {
          compileReject("some error");
          window.setTimeout(() => {
            expect(store.getActions()[3])
              .toEqual({type: "FAIL_COMPILE", payload: "some error"});
            done();
          }, 0);
        });

        describe("and the execute function,", () => {

          beforeEach((done) => {
            compileResolve("the bytecode");
            window.setTimeout(done, 0);
          });

          it("dispatches a FINISH_EXECUTE action once the bytecode is executed", (done) => {
            executeResolve("some result");
            window.setTimeout(() => {
              expect(store.getActions()[5])
                .toEqual({type: "FINISH_EXECUTE", payload: "some result"});
              done();
            }, 0);
          });

          it("dispatches a FAIL_EXECUTE action once the third promise is rejected", (done) => {
            executeReject("some error");
            window.setTimeout(() => {
              expect(store.getActions()[5])
                .toEqual({type: "FAIL_EXECUTE", payload: "some error"});
              done();
            }, 0);
          });
        });
      });
    });
  });
});
<commit_msg>lint fixes<commit_after>import {loadRuntimeApi, run} from "../../src/redux/actionCreators";
import configureStore from "redux-mock-store";
import thunk from 'redux-thunk';

describe("The actionCreators'", () => {

  const middlewares = [thunk];
  const mockStore = configureStore(middlewares);

  describe("loadRuntimeApi function", () => {
    var resolve, reject, store;

    beforeEach(() => {
      var runtimeApiLoader = function() {
        return new Promise(function(_resolve, _reject) {
          resolve = _resolve;
          reject = _reject;
        });
      };
      store = mockStore({}); //initial state of the store
      store.dispatch(loadRuntimeApi(runtimeApiLoader));
    });

    it("dispatches a START_LOAD_RUNTIME action first", () => {
      expect(store.getActions()[0]).toEqual({type: "START_LOAD_RUNTIME"});
    });

    it("dispatches a FINISH_LOAD_RUNTIME after the runtime is loaded", (done) => {
      resolve("the runtime api");
      window.setTimeout(() => {
        expect(store.getActions()[1])
          .toEqual({type: "FINISH_LOAD_RUNTIME", payload: "the runtime api"});
        done();
      }, 0);
    });

    it("dispatches a FAIL_LOAD_RUNTIME after the promise is rejected", (done) => {
      reject("some error");
      window.setTimeout(() => {
        expect(store.getActions()[1])
          .toEqual({type: "FAIL_LOAD_RUNTIME", payload: "some error"});
        done();
      }, 0);
    });
  });

  describe("run function,", () => {

    var getState, parseResolve, parseReject, compileResolve, compileReject;
    var executeResolve, executeReject, store;
    var src = "some source code";

    beforeEach(() => {
      getState = () => ({
        runtimeApi: {
          parse() {
            return new Promise((_resolve, _reject) => {
              parseResolve = _resolve;
              parseReject = _reject;
            });
          },
          compile() {
            return new Promise((_resolve, _reject) => {
              compileResolve = _resolve;
              compileReject = _reject;
            });
          },
          execute() {
            return new Promise((_resolve, _reject) => {
              executeResolve = _resolve;
              executeReject = _reject;
            });
          }
        }
      });
      store = mockStore(getState());
      store.dispatch(run(src));
    });

    it("dispatches a START_PARSE action first", () => {
      expect(store.getActions()[0]).toEqual({type: "START_PARSE", stage: 'parsing'});
    });

    describe("after calling the parse function,", () => {

      it("dispatches a FINISH_PARSE action once the source code is parsed", (done) => {
        parseResolve("the ast");
        window.setTimeout(() => {
          expect(store.getActions()[1])
            .toEqual({type: "FINISH_PARSE", payload: "the ast"});
          done();
        }, 0);
      });

      it("dispatches a START_COMPILE action once the source code is parsed", (done) => {
        parseResolve("the src");
        window.setTimeout(() => {
          expect(store.getActions()[2])
            .toEqual({type: "START_COMPILE", stage: 'compiling'});
          done();
        }, 0);
      });

      it("dispatches a FAIL_PARSE action once the first promise is rejected", (done) => {
        parseReject("some error");
        window.setTimeout(() => {
          expect(store.getActions()[1])
            .toEqual({type: "FAIL_PARSE", payload: "some error"});
          done();
        }, 0);
      });

      describe("and the compile function,", () => {

        beforeEach((done) => {
          parseResolve("the ast");
          window.setTimeout(done, 0);
        });

        it("dispatches a FINISH_COMPILE action once the ast is compiled", (done) => {
          compileResolve("the byte code");
          window.setTimeout(() => {
            expect(store.getActions()[3])
              .toEqual({type: "FINISH_COMPILE", payload: 'the byte code'});
            done();
          }, 0);
        });

        it("dispatches a START_EXECUTE action once the ast is compiled", (done) => {
          compileResolve("the bytecode");
          window.setTimeout(() => {
            expect(store.getActions()[4])
              .toEqual({type: "START_EXECUTE", stage: 'executing'});
            done();
          }, 0);
        });

        it("dispatches a FAIL_COMPILE action once the second promise is rejected",
           (done) => {
             compileReject("some error");
             window.setTimeout(() => {
               expect(store.getActions()[3])
                 .toEqual({type: "FAIL_COMPILE", payload: "some error"});
               done();
             }, 0);
           });

        describe("and the execute function,", () => {

          beforeEach((done) => {
            compileResolve("the bytecode");
            window.setTimeout(done, 0);
          });

          it("dispatches a FINISH_EXECUTE action once the bytecode is executed",
             (done) => {
               executeResolve("some result");
               window.setTimeout(() => {
                 expect(store.getActions()[5])
                   .toEqual({type: "FINISH_EXECUTE", payload: "some result"});
                 done();
               }, 0);
             });

          it("dispatches a FAIL_EXECUTE action once the third promise is rejected",
             (done) => {
               executeReject("some error");
               window.setTimeout(() => {
                 expect(store.getActions()[5])
                   .toEqual({type: "FAIL_EXECUTE", payload: "some error"});
                 done();
               }, 0);
             });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>import { combine } from 'most'
import keycode from 'keycode'

import { streamDom } from '../stream-dom'
import * as actions from '../model/todo-actions'
import { TodoList } from './TodoList'

export function App({
  properties: {
    todos$: allTodos$,
    locationHash$,
    filter$,
    filterRoutes: {
      hashShowActive,
      hashShowCompleted,
      hashDefault
    }
  },
  eventStreams: {
    todoAction
  },
  createEventStream,
  attachEventStream
}) {
  const todos$ = combine(
    (allTodos, filter) => allTodos.filter(filter),
    allTodos$,
    filter$
  )

  const keyPressNewTodo$ = createEventStream()
  const newTodoEnter$ = keyPressNewTodo$.filter(e => e.keyCode === keycode('Enter'))
  attachEventStream(todoAction, newTodoEnter$
    .map(e => e.target.value.trim())
    .filter(text => text.length > 0)
    .map(text => actions.create(text))
  )
  newTodoEnter$.observe(e => e.target.value = '')

  const changeToggleAll$ = createEventStream()
  attachEventStream(todoAction, changeToggleAll$.map(e => actions.toggleAll(e.target.checked)))

  const activeCount$ = allTodos$.filter(todo => !todo.completed).map(todos => todos.length)
  const footerStyle$ = allTodos$.map(conditionalVisibility(allTodos => allTodos.length > 0))

  const clickClearCompleted$ = createEventStream()
  attachEventStream(todoAction, clickClearCompleted$.map(() => actions.destroyAllCompleted()))

  return (

todos

          <input class="new-todo" placeholder="What needs to be done?" autofocus
            e:keypress={keyPressNewTodo$}
            />

          <input id="toggle-all" class="toggle-all" type="checkbox" e:change={changeToggleAll$} />
          Mark all as complete
          <TodoList todos$={todos$} e:todoAction={todoAction} />

          {activeCount$} items left

              All

              Active

              Completed

          <button class="clear-completed" e:click={clickClearCompleted$}>Clear completed</button>

Double-click to edit a todo

Created by Brandon Payton

  )
}

function conditionalVisibility(predicate) {
  return x => predicate(x) ? '': 'display: none'
}

function selectedHash(hash) {
  return selectedHash => selectedHash === hash ? 'selected' : ''
}
<commit_msg>Fix items left count in todomvc example<commit_after>import { combine } from 'most'
import keycode from 'keycode'

import { streamDom } from '../stream-dom'
import * as actions from '../model/todo-actions'
import { TodoList } from './TodoList'

export function App({
  properties: {
    todos$: allTodos$,
    locationHash$,
    filter$,
    filterRoutes: {
      hashShowActive,
      hashShowCompleted,
      hashDefault
    }
  },
  eventStreams: {
    todoAction
  },
  createEventStream,
  attachEventStream
}) {
  const todos$ = combine(
    (allTodos, filter) => allTodos.filter(filter),
    allTodos$,
    filter$
  )

  const keyPressNewTodo$ = createEventStream()
  const newTodoEnter$ = keyPressNewTodo$.filter(e => e.keyCode === keycode('Enter'))
  attachEventStream(todoAction, newTodoEnter$
    .map(e => e.target.value.trim())
    .filter(text => text.length > 0)
    .map(text => actions.create(text))
  )
  newTodoEnter$.observe(e => e.target.value = '')

  const changeToggleAll$ = createEventStream()
  attachEventStream(todoAction, changeToggleAll$.map(e => actions.toggleAll(e.target.checked)))

  const activeCount$ = allTodos$.map(
    todos => todos.reduce((count, t) => count + (t.completed ? 0 : 1), 0)
  )
  const footerStyle$ = allTodos$.map(conditionalVisibility(allTodos => allTodos.length > 0))

  const clickClearCompleted$ = createEventStream()
  attachEventStream(todoAction, clickClearCompleted$.map(() => actions.destroyAllCompleted()))

  return (

todos

          <input class="new-todo" placeholder="What needs to be done?" autofocus
            e:keypress={keyPressNewTodo$}
            />

          <input id="toggle-all" class="toggle-all" type="checkbox" e:change={changeToggleAll$} />
          Mark all as complete
          <TodoList todos$={todos$} e:todoAction={todoAction} />

          {activeCount$} items left

              All

              Active

              Completed

          <button class="clear-completed" e:click={clickClearCompleted$}>Clear completed</button>

Double-click to edit a todo

Created by Brandon Payton

  )
}

function conditionalVisibility(predicate) {
  return x => predicate(x) ? '': 'display: none'
}

function selectedHash(hash) {
  return selectedHash => selectedHash === hash ? 'selected' : ''
}
<|endoftext|>


<commit_before>import site from '../app';

site.directive('score', ($timeout, $filter) => {
  return {
    restrict: 'E',
    templateUrl: 'score',
    scope: {
      value: '='
    },
    link: (scope, element, attrs) => {
      scope.editing = false;
      scope.editStuff = { value: scope.value }; // don't bind to primitives, they said
      scope.maxScore = 999;

      $timeout(() => {
        const bigScores = $('.duel-area').hasClass('big-scores');
        scope.maxScore = bigScores ? 999999999999 : 999;
      }, 0);

      scope.getValue = () => _.isNumber(scope.value) ? $filter('number')(scope.value, 0) : '-';

      scope.edit = () => {
        if(!attrs.canClick) return;
        scope.editing = true;
        $timeout(() => {
          $(element).find('.score-input').focus();
          $(element).find('.score-input').select();
        }, 0);
      };
      scope.unedit = () => scope.editing = false;

      scope.watchKeyPresses = (e) => {
        if(e.which !== 13) return;
        scope.unedit();
      };

      scope.value = scope.value || 0;

      scope.$watch('editStuff.value', (newVal) => scope.value = newVal);
    }
  };
});<commit_msg>feat(tournaments): scores are, by default, 0 now. this means each score does not need to be entered manually if the participant got no points, which will make larger matches much more workable<commit_after>import site from '../app';

site.directive('score', ($timeout, $filter) => {
  return {
    restrict: 'E',
    templateUrl: 'score',
    scope: {
      value: '='
    },
    link: (scope, element, attrs) => {
      scope.editing = false;
      scope.editStuff = { value: scope.value }; // don't bind to primitives, they said
      scope.maxScore = 999;

      $timeout(() => {
        const bigScores = $('.duel-area').hasClass('big-scores');
        scope.maxScore = bigScores ? 999999999999 : 999;
      }, 0);

      scope.getValue = () => _.isNumber(scope.value) ? $filter('number')(scope.value, 0) : '-';

      scope.edit = () => {
        if(!attrs.canClick) return;
        scope.editing = true;
        $timeout(() => {
          $(element).find('.score-input').focus();
          $(element).find('.score-input').select();
        }, 0);
      };
      scope.unedit = () => scope.editing = false;

      scope.watchKeyPresses = (e) => {
        if(e.which !== 13) return;
        scope.unedit();
      };

      scope.$watch('editStuff.value', (newVal) => scope.value = _.isNumber(newVal) ? newVal : 0);
    }
  };
});<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs-ext');
var lb = require('binary-search-bounds').ge;

// DirCache represents a cache of the directory listing at
// a specific path.
exports.DirCache = function DirCache(path) {
  this.path = path;
  // List is sorted by-modification-date (newest first).
  this.list = [];
  // Map is indexed by-name.
  this.map = {};
  // Array of callbacks to call if there is a rebuilding going on.
  this.rebuilding = null;
  // When was the last rebuild?
  this.rebuildTime = 0;
  // How long did it take?
  this.rebuildMs = 0;
}

// Encode the stat object for a file as a json record to be
// returned from our public API.
function encodeStat(name, statObj) {
  var modestr = '';
  if (statObj.isDirectory()) {
    modestr += 'd';
  }
  if (statObj.mode & 00400) {
    modestr += 'r';
  }
  if (statObj.mode & 00200) {
    modestr += 'w';
  }
  if (statObj.mode & 00100) {
    modestr += 'x';
  }
  var mtime = statObj.mtime.getTime();

  return {
    name: name,
    mode: modestr,
    size: statObj.size,
    mtime: mtime
  };
}

// Predicate to sort by modification-time.  If two entries have
// the same mtime, they are sorted alphabetically.
function byMtime(a, b) {
  if (a.mtime < b.mtime) {
    return -1
  }
  if (a.mtime > b.mtime) {
    return 1
  }
  if (a.name < b.name) {
    return -1;
  }
  if (a.name > b.name) {
    return 1;
  }
  return 0;
}

exports.DirCache.prototype = {
  // Synchronous initialization.  To be used once, at the beginning.
  initSync: function() {
    var names = fs.readdirSync(this.path);
    var list = [];
    var map = {};
    for (var j = 0; j < names.length; ++j) {
      // Skip over names starting with .
      if (names[i][0] == '.') {
        continue;
      }
      var itempath = path.join(this.path, names[i]);
      try {
        var obj = encodeStat(names[i], fs.statSync(itempath));
        list.push(obj);
        map[names[i]] = obj;
      } catch (e) {
        // Ignore races, where a file disappears between dir and stat.
        continue;
      }
    }
    list.sort(byMtime);
    this.list = list;
    this.map = map;
  },

  // Async rebuild.  Does the work, then refreshes atomically at the
  // end, then calls the callback.
  rebuild: function(callback) {
    var batch = 32;             // Do work in 32 parallel async tasks.
    var timeLimit = 60 * 1000;  // Timeout after 60 seconds.

    // If requested a rebuild while a rebuild is in progress, just
    // queue up with the rebuild-in-progress.
    if (this.rebuilding) {
      if (callback) { this.rebuilding.push(callback); }
      return;
    }

    // We're the first: queue up our callback and note the start time.
    var self = this;
    var notify = self.rebuilding = [];
    if (callback) { notify.push(callback); }
    var startTime = (new Date).getTime();

    // Set up an abort (signalled by timeout === true) after 60 seconds.
    var timeout = setTimeout(function() {
      timeout = true;
      notifyAll(false);
    }, timeLimit);

    // Kick off an async readdir.
    fs.readdir(self.path, function(err, names) {
      // On error, we notify false and finish up.
      if (err) {
        clearTimeout(timeout);
        notifyAll(false);
        return;
      }

      // Set up data structures to receive work in progress.
      var list = [];
      var map = {};
      var next = 0;
      var inprogress = 0;
      var finished = false;

      // Kick off parallel work tasks.
      while (inprogress < batch && next < names.length) {
        loopTask();
      }
      function loopTask() {
        if (timeout === true) {
          // When aborted, tasks stop looping.
          return;
        } else if (next < names.length) {
          // If there is still more work, tasks loop via doWork.
          doWork(names[next++], loopTask);
        } else if (inprogress == 0) {
          // If there is no more work, and nothing in progress, we complete.
          completeWork();
        }
      }

      // An individual item of work is to stat a single file.
      function doWork(name, next) {
        inprogress += 1;
        var itempath = path.join(self.path, name);
        fs.stat(itempath, function(err, statobj) {
          // Errors are treated as non-existent files.
          if (!err) {
            // Accumulate the results of the stat into list and map.
            var result = encodeStat(name, statobj);
            list.push(result);
            map[name] = result;
          }
          inprogress -= 1;
          next();
        });
      }

      // When work is done, save it and notify callbacks.
      function completeWork() {
        if (!finished) {
          finished = true;
          clearTimeout(timeout);
          list.sort(byMtime);
          self.list = list;
          self.map = map;
          self.rebuildTime = (new Date).getTime();
          self.rebuildMs = self.rebuildTime - startTime;
          notifyAll(true);
        }
      }
    });

    function notifyAll(ok) {
      if (notify && notify === self.rebuilding) {
        self.rebuilding = null;
        while (notify.length) {
          notify.pop().call(null, ok);
        }
      }
    }
  },

  // Get the time since the last rebuildTime.
  age: function() {
    return (new Date).getTime() - this.rebuildTime;
  },

  // Synchronous update of a specific name.
  updateSync: function(name) {
    var itempath = path.join(this.path, name);
    var obj = null;
    try {
      encodeStat(names[i], fs.statSync(itempath));
    } catch (e) {
      // File is gone: let obj be null.
    }
    this.updateObject(name, obj);
  },

  // Async update of a specific name.
  update: function(name, callback) {
    var itempath = path.join(this.path, name);
    var obj = null;
    var self = this;
    fs.stat(itempath, function(err, statObj) {
      if (!err) {
        obj = encodeStat(name, statObj);
      }
      self.updateObject(name, obj);
      callback(true);
    });
  },

  // Updates the object for 'name' with obj (may be null)
  updateObject: function(name, obj) {
    var oldindex = -1;
    if (this.map.hasOwnProperty(name)) {
      var oldobj = this.map[name];
      // Already up to date: nothing to do!
      if (obj !== null && oldobj.mtime == obj.mtime) {
        return;
      }
      oldindex = lb(this.list, oldobj, byMtime);
      if (obj === null) {
        // Remove the item at its old position
        this.list.splice(oldindex, 1);
        delete this.map[name];
        return;
      }
    }
    if (obj == null) {
      // If the file doesn't exist, there is nothing to insert.
      return;
    }
    // Insert the item at its new position
    this.map[name] = obj;
    var index = lb(this.list, obj, byMtime);
    if (oldindex == -1) {
      // It's a new item: insert it.
      this.list.splice(index, 0, obj);
    } else {
      // It's moving in the list: shift the old items over, then set it.
      if (index < oldindex) {
        for (var j = oldindex; j > index; --j) {
          this.list[j] = this.list[j - 1];
        }
      } else if (index > oldindex) {
        for (var j = oldindex; j < index; ++j) {
          this.list[j] = this.list[j + 1];
        }
      }
      this.list[index] = obj;
    }
  },

  // Reads an array of at most "count" items that include an exact
  // matched name (if any) and the most recent prefix matches.
  readPrefix: function(prefix, count) {
    var result = [];
    // ex is 1 if we need to reserve space for an exact match.
    var ex = this.map.hasOwnProperty(prefix) ? 1 : 0;
    // fill result with all objects matching the requested prefix.
    for (var j = 0; result.length + ex < count && j < this.list.length; ++j) {
      var obj = this.list[j];
      var name = obj.name;
      if (name == prefix) {
        // If the exact match is included due to recency, set ex to zero.
        ex = 0;
        result.push(obj);
      } else if (name.length > prefix.length &&
          name.substr(0, prefix.length) == prefix) {
        // Include prefix matches by recency.
        result.push(obj);
      }
    }
    if (ex) {
      // If an exact match wasn't included due to recency, include it now.
      result.push(this.map[prefix]);
    }
    return result;
  }
};
<commit_msg>Fix an off-by-one error in updateObject.<commit_after>var path = require('path');
var fs = require('fs-ext');
var lb = require('binary-search-bounds').ge;

// DirCache represents a cache of the directory listing at
// a specific path.
exports.DirCache = function DirCache(path) {
  this.path = path;
  // List is sorted by-modification-date (newest first).
  this.list = [];
  // Map is indexed by-name.
  this.map = {};
  // Array of callbacks to call if there is a rebuilding going on.
  this.rebuilding = null;
  // When was the last rebuild?
  this.rebuildTime = 0;
  // How long did it take?
  this.rebuildMs = 0;
}

// Encode the stat object for a file as a json record to be
// returned from our public API.
function encodeStat(name, statObj) {
  var modestr = '';
  if (statObj.isDirectory()) {
    modestr += 'd';
  }
  if (statObj.mode & 00400) {
    modestr += 'r';
  }
  if (statObj.mode & 00200) {
    modestr += 'w';
  }
  if (statObj.mode & 00100) {
    modestr += 'x';
  }
  var mtime = statObj.mtime.getTime();

  return {
    name: name,
    mode: modestr,
    size: statObj.size,
    mtime: mtime
  };
}

// Predicate to sort by modification-time.  If two entries have
// the same mtime, they are sorted alphabetically.
function byMtime(a, b) {
  if (a.mtime < b.mtime) {
    return -1
  }
  if (a.mtime > b.mtime) {
    return 1
  }
  if (a.name < b.name) {
    return -1;
  }
  if (a.name > b.name) {
    return 1;
  }
  return 0;
}

exports.DirCache.prototype = {
  // Synchronous initialization.  To be used once, at the beginning.
  initSync: function() {
    var names = fs.readdirSync(this.path);
    var list = [];
    var map = {};
    for (var j = 0; j < names.length; ++j) {
      // Skip over names starting with .
      if (names[i][0] == '.') {
        continue;
      }
      var itempath = path.join(this.path, names[i]);
      try {
        var obj = encodeStat(names[i], fs.statSync(itempath));
        list.push(obj);
        map[names[i]] = obj;
      } catch (e) {
        // Ignore races, where a file disappears between dir and stat.
        continue;
      }
    }
    list.sort(byMtime);
    this.list = list;
    this.map = map;
  },

  // Async rebuild.  Does the work, then refreshes atomically at the
  // end, then calls the callback.
  rebuild: function(callback) {
    var batch = 32;             // Do work in 32 parallel async tasks.
    var timeLimit = 60 * 1000;  // Timeout after 60 seconds.

    // If requested a rebuild while a rebuild is in progress, just
    // queue up with the rebuild-in-progress.
    if (this.rebuilding) {
      if (callback) { this.rebuilding.push(callback); }
      return;
    }

    // We're the first: queue up our callback and note the start time.
    var self = this;
    var notify = self.rebuilding = [];
    if (callback) { notify.push(callback); }
    var startTime = (new Date).getTime();

    // Set up an abort (signalled by timeout === true) after 60 seconds.
    var timeout = setTimeout(function() {
      timeout = true;
      notifyAll(false);
    }, timeLimit);

    // Kick off an async readdir.
    fs.readdir(self.path, function(err, names) {
      // On error, we notify false and finish up.
      if (err) {
        clearTimeout(timeout);
        notifyAll(false);
        return;
      }

      // Set up data structures to receive work in progress.
      var list = [];
      var map = {};
      var next = 0;
      var inprogress = 0;
      var finished = false;

      // Kick off parallel work tasks.
      while (inprogress < batch && next < names.length) {
        loopTask();
      }
      function loopTask() {
        if (timeout === true) {
          // When aborted, tasks stop looping.
          return;
        } else if (next < names.length) {
          // If there is still more work, tasks loop via doWork.
          doWork(names[next++], loopTask);
        } else if (inprogress == 0) {
          // If there is no more work, and nothing in progress, we complete.
          completeWork();
        }
      }

      // An individual item of work is to stat a single file.
      function doWork(name, next) {
        inprogress += 1;
        var itempath = path.join(self.path, name);
        fs.stat(itempath, function(err, statobj) {
          // Errors are treated as non-existent files.
          if (!err) {
            // Accumulate the results of the stat into list and map.
            var result = encodeStat(name, statobj);
            list.push(result);
            map[name] = result;
          }
          inprogress -= 1;
          next();
        });
      }

      // When work is done, save it and notify callbacks.
      function completeWork() {
        if (!finished) {
          finished = true;
          clearTimeout(timeout);
          list.sort(byMtime);
          self.list = list;
          self.map = map;
          self.rebuildTime = (new Date).getTime();
          self.rebuildMs = self.rebuildTime - startTime;
          notifyAll(true);
        }
      }
    });

    function notifyAll(ok) {
      if (notify && notify === self.rebuilding) {
        self.rebuilding = null;
        while (notify.length) {
          notify.pop().call(null, ok);
        }
      }
    }
  },

  // Get the time since the last rebuildTime.
  age: function() {
    return (new Date).getTime() - this.rebuildTime;
  },

  // Synchronous update of a specific name.
  updateSync: function(name) {
    var itempath = path.join(this.path, name);
    var obj = null;
    try {
      encodeStat(names[i], fs.statSync(itempath));
    } catch (e) {
      // File is gone: let obj be null.
    }
    this.updateObject(name, obj);
  },

  // Async update of a specific name.
  update: function(name, callback) {
    var itempath = path.join(this.path, name);
    var obj = null;
    var self = this;
    fs.stat(itempath, function(err, statObj) {
      if (!err) {
        obj = encodeStat(name, statObj);
      }
      self.updateObject(name, obj);
      callback(true);
    });
  },

  // Updates the object for 'name' with obj (may be null)
  updateObject: function(name, obj) {
    var oldindex = -1;
    if (this.map.hasOwnProperty(name)) {
      var oldobj = this.map[name];
      // Already up to date: nothing to do!
      if (obj !== null && oldobj.mtime == obj.mtime) {
        return;
      }
      oldindex = lb(this.list, oldobj, byMtime);
      if (obj === null) {
        // Remove the item at its old position
        this.list.splice(oldindex, 1);
        delete this.map[name];
        return;
      }
    }
    if (obj == null) {
      // If the file doesn't exist, there is nothing to insert.
      return;
    }
    // Insert the item at its new position
    this.map[name] = obj;
    var index = lb(this.list, obj, byMtime);
    if (oldindex == -1) {
      // It's a new item: insert it.
      this.list.splice(index, 0, obj);
    } else {
      // It's moving in the list: shift the old items over, then set it.
      if (index < oldindex) {
        for (var j = oldindex; j > index; --j) {
          this.list[j] = this.list[j - 1];
        }
      } else if (index > oldindex) {
        // If shifting right, our target index is off-by-one because
        // we ourselves are to the left of our destination index.
        index -= 1;
        for (var j = oldindex; j < index; ++j) {
          this.list[j] = this.list[j + 1];
        }
      }
      this.list[index] = obj;
    }
  },

  // Reads an array of at most "count" items that include an exact
  // matched name (if any) and the most recent prefix matches.
  readPrefix: function(prefix, count) {
    var result = [];
    // ex is 1 if we need to reserve space for an exact match.
    var ex = this.map.hasOwnProperty(prefix) ? 1 : 0;
    // fill result with all objects matching the requested prefix.
    for (var j = 0; result.length + ex < count && j < this.list.length; ++j) {
      var obj = this.list[j];
      var name = obj.name;
      if (name == prefix) {
        // If the exact match is included due to recency, set ex to zero.
        ex = 0;
        result.push(obj);
      } else if (name.length > prefix.length &&
          name.substr(0, prefix.length) == prefix) {
        // Include prefix matches by recency.
        result.push(obj);
      }
    }
    if (ex) {
      // If an exact match wasn't included due to recency, include it now.
      result.push(this.map[prefix]);
    }
    return result;
  }
};
<|endoftext|>


<commit_before>/*******************************************************************************
 * (C) Copyright 2016 Jerome Comte and Dorian Cransac
 *
 * This file is part of STEP
 *
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * STEP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
angular.module('functionsControllers',['dataTable','step'])

.controller('FunctionListCtrl', [ '$scope', '$compile', '$http', 'stateStorage', '$interval', '$modal', '$location','AuthService',
    function($scope, $compile, $http, $stateStorage, $interval, $modal, $location, AuthService) {
      $stateStorage.push($scope, 'functions', {});

      $scope.authService = AuthService;

      $scope.autorefresh = true;

      function openModal(function_) {
    	  var modalInstance = $modal.open({
            templateUrl: 'newFunctionModalContent.html',
            controller: 'newFunctionModalCtrl',
            resolve: {function_: function () {return function_;}}
          });

          modalInstance.result.then(function (functionParams) {
              $http.post("rest/functions",functionParams).success(function() {
              	if($scope.table) {
             		$scope.table.Datatable.ajax.reload(null, false);
          		}
              });

          }, function () {});
      }

      $scope.editFunction = function(id) {
      	$http.get("rest/functions/"+id).success(function(function_) {
      	  openModal(function_);
      	});
      }

      $scope.editFlow = function(id) {
        $scope.$apply(function() {
          $location.path('/root/artefacteditor/' + id)
        })
      }

      $scope.addFunction = function() {
    	openModal();
      }

      $scope.executeFunction = function(id, executeLocally) {
  	  var modalInstance = $modal.open({
            animation: $scope.animationsEnabled,
            templateUrl: 'executeFunctionModalContent.html',
            controller: 'executeFunctionModalCtrl',
            resolve: {
              functionId: function () {
                return id;
              },
              executeLocally: function () {
                return executeLocally;
              }
            }
          });

          modalInstance.result.then(function (argument) {}, function () {});
      }

      $scope.deleteFunction = function(id) {
    	  $http.delete("rest/functions/"+id).success(function() {
      		if($scope.table) {
      			$scope.table.Datatable.ajax.reload(null, false);
  			}
      });
      }

      $scope.table = {};

      $scope.tabledef = {}
      $scope.tabledef.columns = function(columns) {
        _.each(_.where(columns, { 'title' : 'ID' }), function(col) {
          col.visible = false
        });
        _.each(_.where(columns, { 'title' : 'Name' }), function(col) {
          col.render = function(data, type, row) {
            return data
          };
        });
        _.each(_.where(columns, { 'title' : 'Type' }), function(col) {
          col.render = function(data, type, row) {
        	var function_ = JSON.parse(row[row.length-1]);
        	if(data.indexOf('class:step.core.tokenhandlers.ArtefactMessageHandler')!=-1) {
        	  if(function_.handlerProperties) {
        	    if(AuthService.hasRight('kw-write')) {
        	      return 'Composite'
        	    } else {
        	      return 'Composite';
        	    }
        	  } else {
        		return 'Unknown';
        	  }
        	} else {
        	  return 'Handler'
        	}
          };
        });
        _.each(_.where(columns,{'title':'Actions'}),function(col){
            col.title="Actions";
            col.searchmode="none";
            col.width="160px";
            col.render = function ( data, type, row ) {
              var function_ = JSON.parse(row[row.length-1]);
              var isComposite = data.indexOf('class:step.core.tokenhandlers.ArtefactMessageHandler')!=-1;
            	var html = '

';

            	if(AuthService.hasRight('kw-write')) {
              	html+='<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().editFunction(\''+row[0]+'\')">' +
  	            	''+
              	  '</button> ';

              	if(isComposite) {
              	  html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().editFlow(\''+function_.handlerProperties['artefactid']+'\')">' +
                  ''+
                  '</button> ';
              	}
            	}

            	if(AuthService.hasRight('kw-execute')) {
              	html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().executeFunction(\''+row[0]+'\','+isComposite+')">' +
  	            	'' +
  	            	'</button> ';
            	}

            	if(AuthService.hasRight('kw-delete')) {
              	html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().deleteFunction(\''+row[0]+'\')">' +
  	            	'' +
  	            	'</button> ';
            	}

            	html+='

';

            	return html;
            }
           });
        return columns;
      };
    } ])

.controller('newFunctionModalCtrl', function ($scope, $modalInstance, $http, $location, function_) {

  var newFunction = function_==null;
  $scope.mode = newFunction?"add":"edit";

  $scope.getFunctionAttributes = function() {
  	return _.keys($scope.function_.attributes);
  }

  $scope.type = function(value) {
  	if(value) {
  	  $scope.function_.handlerChain = (value=="Composite")?"class:step.core.tokenhandlers.ArtefactMessageHandler":"";
  	}
  	return  ($scope.function_.handlerChain&&$scope.function_.handlerChain.indexOf("ArtefactMessageHandler")!=-1)?"Composite":"Handler";
  }

  if(newFunction) {
  	$scope.function_= {"attributes":{}};
  	$scope.type('Composite');
  	$http.get("rest/screens/functionTable").success(function(data){
  	  _.each(data,function(input) {
  	    eval('$scope.function_.'+input.id+"=''");
  	  })
  	});
  } else {
    $scope.function_=function_;
  }

  $scope.save = function (editAfterSave) {
	function close() {
	  $modalInstance.close($scope.function_);
	}

	if($scope.type()=='Composite') {
  	  function closeAndEdit() {
  		close();
  		if(editAfterSave) {
  		  $location.path('/root/artefacteditor/' + $scope.function_.handlerProperties['artefactid'])
  		}
  	  }

  	  if(newFunction || !($scope.function_.handlerProperties && $scope.function_.handlerProperties.artefactid)  ) {
  		var newArtefact = {"_class":"Sequence"};
  		$http.post("rest/controller/artefact",newArtefact).success(function(artefact){
			$scope.function_.handlerProperties = {"artefactid":artefact.id}
			closeAndEdit();
		})
  	  } else {
  		closeAndEdit();
	  }
	} else {
		close();
	}
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
})

.controller('executeFunctionModalCtrl', function ($scope, $modalInstance, $http, functionId, executeLocally) {

  $scope.argument = '';
	$scope.running = false;

	$scope.properties = [];

	$scope.addProperty = function() {
	  $scope.properties.push({key:"",value:""})
	}

  $scope.ok = function () {
    $scope.running=true;
    var properties = {};
    _.each($scope.properties,function(prop){properties[prop.key]=prop.value});
    $http.post("rest/functions/"+functionId+"/execute",{'executeLocally':executeLocally, 'properties':properties,'argument':$scope.argument}).success(function(data) {
		$scope.output = data;
		$scope.running=false;
		if(data) {
		  var output = data.output;
		  if(output.result) {
		    $scope.result = JSON.stringify(output.result)
		  }
		  $scope.attachments=data.attachments;
		  $scope.error = output.error
		}
	}).error(function(error) {
	  $scope.running=false;
	  $scope.error=error;
	});
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});<commit_msg>Changing default KW type selection on "new Keyword" screen<commit_after>/*******************************************************************************
 * (C) Copyright 2016 Jerome Comte and Dorian Cransac
 *
 * This file is part of STEP
 *
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * STEP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
angular.module('functionsControllers',['dataTable','step'])

.controller('FunctionListCtrl', [ '$scope', '$compile', '$http', 'stateStorage', '$interval', '$modal', '$location','AuthService',
    function($scope, $compile, $http, $stateStorage, $interval, $modal, $location, AuthService) {
      $stateStorage.push($scope, 'functions', {});

      $scope.authService = AuthService;

      $scope.autorefresh = true;

      function openModal(function_) {
    	  var modalInstance = $modal.open({
            templateUrl: 'newFunctionModalContent.html',
            controller: 'newFunctionModalCtrl',
            resolve: {function_: function () {return function_;}}
          });

          modalInstance.result.then(function (functionParams) {
              $http.post("rest/functions",functionParams).success(function() {
              	if($scope.table) {
             		$scope.table.Datatable.ajax.reload(null, false);
          		}
              });

          }, function () {});
      }

      $scope.editFunction = function(id) {
      	$http.get("rest/functions/"+id).success(function(function_) {
      	  openModal(function_);
      	});
      }

      $scope.editFlow = function(id) {
        $scope.$apply(function() {
          $location.path('/root/artefacteditor/' + id)
        })
      }

      $scope.addFunction = function() {
    	openModal();
      }

      $scope.executeFunction = function(id, executeLocally) {
  	  var modalInstance = $modal.open({
            animation: $scope.animationsEnabled,
            templateUrl: 'executeFunctionModalContent.html',
            controller: 'executeFunctionModalCtrl',
            resolve: {
              functionId: function () {
                return id;
              },
              executeLocally: function () {
                return executeLocally;
              }
            }
          });

          modalInstance.result.then(function (argument) {}, function () {});
      }

      $scope.deleteFunction = function(id) {
    	  $http.delete("rest/functions/"+id).success(function() {
      		if($scope.table) {
      			$scope.table.Datatable.ajax.reload(null, false);
  			}
      });
      }

      $scope.table = {};

      $scope.tabledef = {}
      $scope.tabledef.columns = function(columns) {
        _.each(_.where(columns, { 'title' : 'ID' }), function(col) {
          col.visible = false
        });
        _.each(_.where(columns, { 'title' : 'Name' }), function(col) {
          col.render = function(data, type, row) {
            return data
          };
        });
        _.each(_.where(columns, { 'title' : 'Type' }), function(col) {
          col.render = function(data, type, row) {
        	var function_ = JSON.parse(row[row.length-1]);
        	if(data.indexOf('class:step.core.tokenhandlers.ArtefactMessageHandler')!=-1) {
        	  if(function_.handlerProperties) {
        	    if(AuthService.hasRight('kw-write')) {
        	      return 'Composite'
        	    } else {
        	      return 'Composite';
        	    }
        	  } else {
        		return 'Unknown';
        	  }
        	} else {
        	  return 'Handler'
        	}
          };
        });
        _.each(_.where(columns,{'title':'Actions'}),function(col){
            col.title="Actions";
            col.searchmode="none";
            col.width="160px";
            col.render = function ( data, type, row ) {
              var function_ = JSON.parse(row[row.length-1]);
              var isComposite = data.indexOf('class:step.core.tokenhandlers.ArtefactMessageHandler')!=-1;
            	var html = '

';

            	if(AuthService.hasRight('kw-write')) {
              	html+='<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().editFunction(\''+row[0]+'\')">' +
  	            	''+
              	  '</button> ';

              	if(isComposite) {
              	  html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().editFlow(\''+function_.handlerProperties['artefactid']+'\')">' +
                  ''+
                  '</button> ';
              	}
            	}

            	if(AuthService.hasRight('kw-execute')) {
              	html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().executeFunction(\''+row[0]+'\','+isComposite+')">' +
  	            	'' +
  	            	'</button> ';
            	}

            	if(AuthService.hasRight('kw-delete')) {
              	html+= '<button type="button" class="btn btn-default" aria-label="Left Align" onclick="angular.element(\'#FunctionListCtrl\').scope().deleteFunction(\''+row[0]+'\')">' +
  	            	'' +
  	            	'</button> ';
            	}

            	html+='

';

            	return html;
            }
           });
        return columns;
      };
    } ])

.controller('newFunctionModalCtrl', function ($scope, $modalInstance, $http, $location, function_) {

  var newFunction = function_==null;
  $scope.mode = newFunction?"add":"edit";

  $scope.getFunctionAttributes = function() {
  	return _.keys($scope.function_.attributes);
  }

  $scope.type = function(value) {
  	if(value) {
  	  $scope.function_.handlerChain = (value=="Composite")?"class:step.core.tokenhandlers.ArtefactMessageHandler":"class:step.handlers.scripthandler.ScriptHandler";
  	}
  	return  ($scope.function_.handlerChain&&$scope.function_.handlerChain.indexOf("ArtefactMessageHandler")!=-1)?"Composite":"Handler";
  }

  if(newFunction) {
  	$scope.function_= {"attributes":{}};
  	$scope.type('Handler');
  	$http.get("rest/screens/functionTable").success(function(data){
  	  _.each(data,function(input) {
  	    eval('$scope.function_.'+input.id+"=''");
  	  })
  	});
  } else {
    $scope.function_=function_;
  }

  $scope.save = function (editAfterSave) {
	function close() {
	  $modalInstance.close($scope.function_);
	}

	if($scope.type()=='Composite') {
  	  function closeAndEdit() {
  		close();
  		if(editAfterSave) {
  		  $location.path('/root/artefacteditor/' + $scope.function_.handlerProperties['artefactid'])
  		}
  	  }

  	  if(newFunction || !($scope.function_.handlerProperties && $scope.function_.handlerProperties.artefactid)  ) {
  		var newArtefact = {"_class":"Sequence"};
  		$http.post("rest/controller/artefact",newArtefact).success(function(artefact){
			$scope.function_.handlerProperties = {"artefactid":artefact.id}
			closeAndEdit();
		})
  	  } else {
  		closeAndEdit();
	  }
	} else {
		close();
	}
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
})

.controller('executeFunctionModalCtrl', function ($scope, $modalInstance, $http, functionId, executeLocally) {

  $scope.argument = '';
	$scope.running = false;

	$scope.properties = [];

	$scope.addProperty = function() {
	  $scope.properties.push({key:"",value:""})
	}

  $scope.ok = function () {
    $scope.running=true;
    var properties = {};
    _.each($scope.properties,function(prop){properties[prop.key]=prop.value});
    $http.post("rest/functions/"+functionId+"/execute",{'executeLocally':executeLocally, 'properties':properties,'argument':$scope.argument}).success(function(data) {
		$scope.output = data;
		$scope.running=false;
		if(data) {
		  var output = data.output;
		  if(output.result) {
		    $scope.result = JSON.stringify(output.result)
		  }
		  $scope.attachments=data.attachments;
		  $scope.error = output.error
		}
	}).error(function(error) {
	  $scope.running=false;
	  $scope.error=error;
	});
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});<|endoftext|>


<commit_before>//@flow
import Project from '../Project';
import Workspace from '../Workspace';
import runWorkspaceTasks from './runWorkspaceTasks';

export default async function updatePackageVersions(versions: {[name: string]: string}, opts: { cwd?: string } = {}) {
  const cwd = opts.cwd || process.cwd();

  const updateWorkspacePackageVersion = (workspace: Workspace) => {
    const pkg = workspace.pkg;
    const promises = [];

    for(let depName of Object.keys(versions)) {
      const depType = pkg.getDependencyType(depName);
      if (!depType) continue;

      promises.push(pkg.updateDependencyVersionRange(depName, depType, versions[depName]));
    }

    return Promise.all(promises);
  }

  await runWorkspaceTasks(updateWorkspacePackageVersion, opts);
}
<commit_msg>Removes unneccessary updateWorkspacePackageVersion from updatePackageVersions<commit_after>//@flow
import Project from '../Project';
import Workspace from '../Workspace';
import runWorkspaceTasks from './runWorkspaceTasks';

export default async function updatePackageVersions(versions: {[name: string]: string}, opts: { cwd?: string } = {}) {
  const cwd = opts.cwd || process.cwd();
  const project = await Project.init(cwd);
  const workspaces = await project.getWorkspaces();

  for (let workspace of workspaces) {
    const pkg = workspace.pkg;
    const promises = [];

    for (let depName of Object.keys(versions)) {
      const depType = pkg.getDependencyType(depName);
      if (!depType) continue;

      promises.push(pkg.updateDependencyVersionRange(depName, depType, versions[depName]));
    }

    await Promise.all(promises);
  }
}
<|endoftext|>


<commit_before>import OptionsHelper from './options-helper';

describe('OptionsHelper', () => {
  it('alignBinary', () => {
    expect(OptionsHelper.alignBinary).toEqual([
      'left',
      'right'
    ]);
  });
  it('alignFull', () => {
    expect(OptionsHelper.alignFull).toEqual([
      'center',
      'left',
      'right'
    ]);
  });
  it('buttonColors', () => {
    expect(OptionsHelper.buttonColors).toEqual([
      'blue',
      'grey',
      'magenta',
      'magenta-dull',
      'red',
      'white'
    ]);
  });
  it('buttonIconPositions', () => {
    expect(OptionsHelper.buttonIconPositions).toEqual([
      'before',
      'after'
    ]);
  });
  it('colors', () => {
    expect(OptionsHelper.colors).toEqual([
      'default',
      'error',
      'help',
      'info',
      'maintenance',
      'new',
      'success',
      'warning'
    ]);
  });
  it('icons', () => {
    expect(OptionsHelper.icons).toEqual([
      'add',
      'alert',
      'analysis',
      'arrow_down',
      'arrow_left',
      'arrow_right',
      'arrow_up',
      'attach',
      'basket',
      'bin',
      'blocked',
      'blocked_square',
      'bulk_destroy',
      'business',
      'calendar',
      'call',
      'camera',
      'card_view',
      'caret_down',
      'cart',
      'chat',
      'chart_bar',
      'chart_line',
      'chart_pie',
      'chat_notes',
      'chevron_down',
      'chevron_left',
      'chevron_right',
      'chevron_up',
      'clock',
      'close',
      'collaborate',
      'copy',
      'connect',
      'credit_card',
      'credit_card_slash',
      'cross',
      'csv',
      'delete',
      'delivery',
      'disputed',
      'download',
      'drag',
      'drag_vertical',
      'draft',
      'dropdown',
      'duplicate',
      'edit',
      'edited',
      'email',
      'ellipsis_horizontal',
      'ellipsis_vertical',
      'error',
      'favourite',
      'favourite_lined',
      'fax',
      'feedback',
      'filter',
      'filter_new',
      'fit_height',
      'fit_width',
      'folder',
      'gift',
      'graph',
      'grid',
      'help',
      'home',
      'image',
      'in_progress',
      'in_transit',
      'info',
      'individual',
      'key',
      'link',
      'list_view',
      'locked',
      'location',
      'logout',
      'marker',
      'message',
      'messages',
      'minus',
      'mobile',
      'pdf',
      'people',
      'person',
      'phone',
      'play',
      'plus',
      'print',
      'progressed',
      'question',
      'refresh',
      'remove',
      'save',
      'search',
      'services',
      'settings',
      'share',
      'shop',
      'sort_down',
      'sort_up',
      'submitted',
      'sync',
      'tick',
      'unlocked',
      'upload',
      'uploaded',
      'video',
      'view',
      'warning',
      'white-tick'
    ]);
  });
  it('pageSizes', () => {
    expect(OptionsHelper.pageSizes).toEqual([
      10, 25, 50
    ]);
  });
  it('positions', () => {
    expect(OptionsHelper.positions).toEqual([
      'bottom',
      'left',
      'right',
      'top'
    ]);
  });
  it('sizesFull', () => {
    expect(OptionsHelper.sizesFull).toEqual([
      'extra-small',
      'small',
      'medium-small',
      'medium',
      'medium-large',
      'large',
      'extra-large'
    ]);
  });
  it('sizesPod', () => {
    expect(OptionsHelper.sizesPod).toEqual([
      'extra-small',
      'small',
      'medium',
      'large',
      'extra-large'
    ]);
  });
  it('sizesRestricted', () => {
    expect(OptionsHelper.sizesRestricted).toEqual([
      'small',
      'medium',
      'large'
    ]);
  });
  it('sizesBinary', () => {
    expect(OptionsHelper.sizesBinary).toEqual([
      'small',
      'large'
    ]);
  });
  it('themesBinary', () => {
    expect(OptionsHelper.themesBinary).toEqual([
      'primary',
      'secondary',
      'tertiary',
      'destructive',
      'darkBackground'
    ]);
  });
  it('themesFull', () => {
    expect(OptionsHelper.themesFull).toEqual([
      'primary',
      'secondary',
      'tertiary',
      'tile',
      'transparent'
    ]);
  });
});
<commit_msg>tests for new colour variations<commit_after>import OptionsHelper from './options-helper';

describe('OptionsHelper', () => {
  it('alignBinary', () => {
    expect(OptionsHelper.alignBinary).toEqual([
      'left',
      'right'
    ]);
  });
  it('alignFull', () => {
    expect(OptionsHelper.alignFull).toEqual([
      'center',
      'left',
      'right'
    ]);
  });
  it('buttonColors', () => {
    expect(OptionsHelper.buttonColors).toEqual([
      'blue',
      'grey',
      'magenta',
      'magenta-dull',
      'red',
      'white'
    ]);
  });
  it('buttonIconPositions', () => {
    expect(OptionsHelper.buttonIconPositions).toEqual([
      'before',
      'after'
    ]);
  });
  it('colors', () => {
    expect(OptionsHelper.colors).toEqual([
      'default',
      'disabled',
      'error',
      'help',
      'info',
      'maintenance',
      'new',
      'success',
      'warning'
    ]);
  });
  it('pillColours', () => {
    expect(OptionsHelper.pillColours).toEqual([
      'neutral',
      'negative',
      'positive'
    ]);
  });
  it('icons', () => {
    expect(OptionsHelper.icons).toEqual([
      'add',
      'alert',
      'analysis',
      'arrow_down',
      'arrow_left',
      'arrow_right',
      'arrow_up',
      'attach',
      'basket',
      'bin',
      'blocked',
      'blocked_square',
      'bulk_destroy',
      'business',
      'calendar',
      'call',
      'camera',
      'card_view',
      'caret_down',
      'cart',
      'chat',
      'chart_bar',
      'chart_line',
      'chart_pie',
      'chat_notes',
      'chevron_down',
      'chevron_left',
      'chevron_right',
      'chevron_up',
      'clock',
      'close',
      'collaborate',
      'copy',
      'connect',
      'credit_card',
      'credit_card_slash',
      'cross',
      'csv',
      'delete',
      'delivery',
      'disputed',
      'download',
      'drag',
      'drag_vertical',
      'draft',
      'dropdown',
      'duplicate',
      'edit',
      'edited',
      'email',
      'ellipsis_horizontal',
      'ellipsis_vertical',
      'error',
      'favourite',
      'favourite_lined',
      'fax',
      'feedback',
      'filter',
      'filter_new',
      'fit_height',
      'fit_width',
      'folder',
      'gift',
      'graph',
      'grid',
      'help',
      'home',
      'image',
      'in_progress',
      'in_transit',
      'info',
      'individual',
      'key',
      'link',
      'list_view',
      'locked',
      'location',
      'logout',
      'marker',
      'message',
      'messages',
      'minus',
      'mobile',
      'pdf',
      'people',
      'person',
      'phone',
      'play',
      'plus',
      'print',
      'progressed',
      'question',
      'refresh',
      'remove',
      'save',
      'search',
      'services',
      'settings',
      'share',
      'shop',
      'sort_down',
      'sort_up',
      'submitted',
      'sync',
      'tick',
      'unlocked',
      'upload',
      'uploaded',
      'video',
      'view',
      'warning',
      'white-tick'
    ]);
  });
  it('pageSizes', () => {
    expect(OptionsHelper.pageSizes).toEqual([
      10, 25, 50
    ]);
  });
  it('positions', () => {
    expect(OptionsHelper.positions).toEqual([
      'bottom',
      'left',
      'right',
      'top'
    ]);
  });
  it('sizesFull', () => {
    expect(OptionsHelper.sizesFull).toEqual([
      'extra-small',
      'small',
      'medium-small',
      'medium',
      'medium-large',
      'large',
      'extra-large'
    ]);
  });
  it('sizesPod', () => {
    expect(OptionsHelper.sizesPod).toEqual([
      'extra-small',
      'small',
      'medium',
      'large',
      'extra-large'
    ]);
  });
  it('sizesRestricted', () => {
    expect(OptionsHelper.sizesRestricted).toEqual([
      'small',
      'medium',
      'large'
    ]);
  });
  it('sizesBinary', () => {
    expect(OptionsHelper.sizesBinary).toEqual([
      'small',
      'large'
    ]);
  });
  it('themesBinary', () => {
    expect(OptionsHelper.themesBinary).toEqual([
      'primary',
      'secondary',
      'tertiary',
      'destructive',
      'darkBackground'
    ]);
  });
  it('themesFull', () => {
    expect(OptionsHelper.themesFull).toEqual([
      'primary',
      'secondary',
      'tertiary',
      'tile',
      'transparent'
    ]);
  });
});
<|endoftext|>


<commit_before>"use strict";

var utils = require("./utils")

/**
 * The `AssertionError` is defined in assert.
 * @extends Error
 * @example
 *  new assert.AssertionError({
 *    message: message,
 *    actual: actual,
 *    expected: expected
 *  })
 */
function AssertionError(options) {
  var assertionError = Object.create(AssertionError.prototype);

  if (utils.isString(options))
    options = { message: options };
  if ("actual" in options)
    assertionError.actual = options.actual;
  if ("expected" in options)
    assertionError.expected = options.expected;
  if ("operator" in options)
    assertionError.operator = options.operator;

  assertionError.message = options.message;
  assertionError.stack = new Error().stack;
  return assertionError;
}
AssertionError.prototype = Object.create(Error.prototype, {
  constructor: { value: AssertionError },
  name: { value: "AssertionError", enumerable: true },
  toString: { value: function toString() {
    var value;
    if (this.message) {
      value = this.name + " : " + this.message;
    }
    else {
      value = [
        this.name + " : ",
        utils.source(this.expected),
        this.operator,
        utils.source(this.actual)
      ].join(" ");
    }
    return value;
  }}
});
exports.AssertionError = AssertionError;

function Assert(logger) {
  return Object.create(Assert.prototype, { _log: { value: logger }});
}
Assert.prototype = {
  fail: function fail(e) {
    this._log.fail(e);
  },
  pass: function pass(message) {
    this._log.pass(message);
  },
  error: function error(e) {
    this._log.error(e);
  },
  ok: function ok(value, message) {
    if (!!!value) {
      this.fail({
        actual: value,
        expected: true,
        message: message,
        operator: "=="
      });
    }
    else {
      this.pass(message);
    }
  },

  /**
   * The equality assertion tests shallow, coercive equality with `==`.
   * @example
   *    assert.equal(1, 1, "one is one");
   */
  equal: function equal(actual, expected, message) {
    if (actual == expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "=="
      });
    }
  },

  /**
   * The non-equality assertion tests for whether two objects are not equal
   * with `!=`.
   * @example
   *    assert.notEqual(1, 2, "one is not two");
   */
  notEqual: function notEqual(actual, expected, message) {
    if (actual != expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "!=",
      });
    }
  },

  /**
   * The equivalence assertion tests a deep (with `===`) equality relation.
   * @example
   *    assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects")
   */
   deepEqual: function deepEqual(actual, expected, message) {
    if (isDeepEqual(actual, expected)) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "deepEqual"
      });
    }
  },

  /**
   * The non-equivalence assertion tests for any deep (with `===`) inequality.
   * @example
   *    assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
   *                        "object"s inherit from different prototypes");
   */
  notDeepEqual: function notDeepEqual(actual, expected, message) {
    if (!isDeepEqual(actual, expected)) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "notDeepEqual"
      });
    }
  },

  /**
   * The strict equality assertion tests strict equality, as determined by
   * `===`.
   * @example
   *    assert.strictEqual(null, null, "`null` is `null`")
   */
  strictEqual: function strictEqual(actual, expected, message) {
    if (actual === expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "==="
      });
    }
  },

  /**
   * The strict non-equality assertion tests for strict inequality, as
   * determined by `!==`.
   * @example
   *    assert.notStrictEqual(null, undefined, "`null` is not `undefined`");
   */
  notStrictEqual: function notStrictEqual(actual, expected, message) {
    if (actual !== expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "!=="
      })
    }
  },

  /**
   * The assertion whether or not given `block` throws an exception. If optional
   * `Error` argument is provided and it"s type of function thrown error is
   * asserted to be an instance of it, if type of `Error` is string then message
   * of throw exception is asserted to contain it.
   * @param {Function} block
   *    Function that is expected to throw.
   * @param {Error|RegExp} [Error]
   *    Error constructor that is expected to be thrown or a string that
   *    must be contained by a message of the thrown exception, or a RegExp
   *    matching a message of the thrown exception.
   * @param {String} message
   *    Description message
   *
   * @examples
   *
   *    assert.throws(function block() {
   *      doSomething(4)
   *    }, "Object is expected", "Incorrect argument is passed");
   *
   *    assert.throws(function block() {
   *      Object.create(5)
   *    }, TypeError, "TypeError is thrown");
   */
  throws: function throws(block, Error, message) {
    var threw = false;
    var exception = null;

    // If third argument is not provided and second argument is a string it
    // means that optional `Error` argument was not passed, so we shift
    // arguments.
    if (utils.isString(Error) && utils.isUndefined(message)) {
      message = Error;
      Error = undefined;
    }

    // Executing given `block`.
    try {
      block();
    }
    catch (e) {
      threw = true;
      exception = e;
    }

    // If exception was thrown and `Error` argument was not passed assert is
    // passed.
    if (threw && (utils.isUndefined(Error) ||
                 // If Error is thrown exception
                 (Error == exception) ||
                 // If passed `Error` is RegExp using it"s test method to
                 // assert thrown exception message.
                 (utils.isRegExp(Error) && Error.test(exception.message)) ||
                 // If passed `Error` is a constructor function testing if
                 // thrown exception is an instance of it.
                 (utils.isFunction(Error) && utils.instanceOf(exception, Error))))
    {
      this.pass(message);
    }

    // Otherwise we report assertion failure.
    else {
      var failure = {
        message: message,
        operator: "throws"
      };

      if (exception)
        failure.actual = exception;

      if (Error)
        failure.expected = Error;

      this.fail(failure);
    }
  }
};
exports.Assert = Assert;

function isDeepEqual(actual, expected) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;
  }

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  else if (utils.isDate(actual) && utils.isDate(expected)) {
    return actual.getTime() === expected.getTime();
  }

  // XXX specification bug: this should be specified
  else if (utils.isPrimitive(actual) || utils.isPrimitive(expected)) {
    return expected === actual;
  }

  // 7.3. Other pairs that do not both pass typeof value == "object",
  // equivalence is determined by ==.
  else if (!utils.isObject(actual) && !utils.isObject(expected)) {
    return actual == expected;
  }

  // 7.4. For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical "prototype" property. Note: this
  // accounts for both named and indexed properties on Arrays.
  else {
    return actual.prototype === expected.prototype &&
           isEquivalent(actual, expected);
  }
}

function isEquivalent(a, b, stack) {
  return isArrayEquivalent(Object.keys(a).sort(),
                           Object.keys(b).sort()) &&
          Object.keys(a).every(function(key) {
            return isDeepEqual(a[key], b[key], stack)
          });
}

function isArrayEquivalent(a, b, stack) {
  return utils.isArray(a) && utils.isArray(b) && a.length === b.length &&
         a.every(function(value, index) {
           return isDeepEqual(value, b[index]);
         });
}
<commit_msg>Fix asserts for error values.<commit_after>"use strict";

var utils = require("./utils")

/**
 * The `AssertionError` is defined in assert.
 * @extends Error
 * @example
 *  new assert.AssertionError({
 *    message: message,
 *    actual: actual,
 *    expected: expected
 *  })
 */
function AssertionError(options) {
  var assertionError = Object.create(AssertionError.prototype);

  if (utils.isString(options))
    options = { message: options };
  if ("actual" in options)
    assertionError.actual = options.actual;
  if ("expected" in options)
    assertionError.expected = options.expected;
  if ("operator" in options)
    assertionError.operator = options.operator;

  assertionError.message = options.message;
  assertionError.stack = new Error().stack;
  return assertionError;
}
AssertionError.prototype = Object.create(Error.prototype, {
  constructor: { value: AssertionError },
  name: { value: "AssertionError", enumerable: true },
  toString: { value: function toString() {
    var value;
    if (this.message) {
      value = this.name + " : " + this.message;
    }
    else {
      value = [
        this.name + " : ",
        utils.source(this.expected),
        this.operator,
        utils.source(this.actual)
      ].join(" ");
    }
    return value;
  }}
});
exports.AssertionError = AssertionError;

function Assert(logger) {
  return Object.create(Assert.prototype, { _log: { value: logger }});
}
Assert.prototype = {
  fail: function fail(e) {
    this._log.fail(e);
  },
  pass: function pass(message) {
    this._log.pass(message);
  },
  error: function error(e) {
    this._log.error(e);
  },
  ok: function ok(value, message) {
    if (!!!value) {
      this.fail({
        actual: value,
        expected: true,
        message: message,
        operator: "=="
      });
    }
    else {
      this.pass(message);
    }
  },

  /**
   * The equality assertion tests shallow, coercive equality with `==`.
   * @example
   *    assert.equal(1, 1, "one is one");
   */
  equal: function equal(actual, expected, message) {
    if (actual == expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "=="
      });
    }
  },

  /**
   * The non-equality assertion tests for whether two objects are not equal
   * with `!=`.
   * @example
   *    assert.notEqual(1, 2, "one is not two");
   */
  notEqual: function notEqual(actual, expected, message) {
    if (actual != expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "!=",
      });
    }
  },

  /**
   * The equivalence assertion tests a deep (with `===`) equality relation.
   * @example
   *    assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects")
   */
   deepEqual: function deepEqual(actual, expected, message) {
    if (isDeepEqual(actual, expected)) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "deepEqual"
      });
    }
  },

  /**
   * The non-equivalence assertion tests for any deep (with `===`) inequality.
   * @example
   *    assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
   *                        "object"s inherit from different prototypes");
   */
  notDeepEqual: function notDeepEqual(actual, expected, message) {
    if (!isDeepEqual(actual, expected)) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "notDeepEqual"
      });
    }
  },

  /**
   * The strict equality assertion tests strict equality, as determined by
   * `===`.
   * @example
   *    assert.strictEqual(null, null, "`null` is `null`")
   */
  strictEqual: function strictEqual(actual, expected, message) {
    if (actual === expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "==="
      });
    }
  },

  /**
   * The strict non-equality assertion tests for strict inequality, as
   * determined by `!==`.
   * @example
   *    assert.notStrictEqual(null, undefined, "`null` is not `undefined`");
   */
  notStrictEqual: function notStrictEqual(actual, expected, message) {
    if (actual !== expected) {
      this.pass(message);
    }
    else {
      this.fail({
        actual: actual,
        expected: expected,
        message: message,
        operator: "!=="
      })
    }
  },

  /**
   * The assertion whether or not given `block` throws an exception. If optional
   * `Error` argument is provided and it"s type of function thrown error is
   * asserted to be an instance of it, if type of `Error` is string then message
   * of throw exception is asserted to contain it.
   * @param {Function} block
   *    Function that is expected to throw.
   * @param {Error|RegExp} [Error]
   *    Error constructor that is expected to be thrown or a string that
   *    must be contained by a message of the thrown exception, or a RegExp
   *    matching a message of the thrown exception.
   * @param {String} message
   *    Description message
   *
   * @examples
   *
   *    assert.throws(function block() {
   *      doSomething(4)
   *    }, "Object is expected", "Incorrect argument is passed");
   *
   *    assert.throws(function block() {
   *      Object.create(5)
   *    }, TypeError, "TypeError is thrown");
   */
  throws: function throws(block, Error, message) {
    var threw = false;
    var exception = null;

    // If third argument is not provided and second argument is a string it
    // means that optional `Error` argument was not passed, so we shift
    // arguments.
    if (utils.isString(Error) && utils.isUndefined(message)) {
      message = Error;
      Error = undefined;
    }

    // Executing given `block`.
    try {
      block();
    }
    catch (e) {
      threw = true;
      exception = e;
    }

    // If exception was thrown and `Error` argument was not passed assert is
    // passed.
    if (threw && (utils.isUndefined(Error) ||
                 // If Error is thrown exception
                 (Error == exception) ||
                 // If passed `Error` is RegExp using it"s test method to
                 // assert thrown exception message.
                 (utils.isRegExp(Error) && Error.test(exception.message)) ||
                 // If passed `Error` is a constructor function testing if
                 // thrown exception is an instance of it.
                 (utils.isFunction(Error) && utils.instanceOf(exception, Error))))
    {
      this.pass(message);
    }

    // Otherwise we report assertion failure.
    else {
      var failure = {
        message: message,
        operator: "throws"
      };

      if (exception)
        failure.actual = exception;

      if (Error)
        failure.expected = Error;

      this.fail(failure);
    }
  }
};
exports.Assert = Assert;

function isDeepEqual(actual, expected) {
  // 7.1. All identical values are equivalent, as determined by ===.
  if (actual === expected) {
    return true;
  }

  // 7.2. If the expected value is a Date object, the actual value is
  // equivalent if it is also a Date object that refers to the same time.
  else if (utils.isDate(actual) && utils.isDate(expected)) {
    return actual.getTime() === expected.getTime();
  }

  // XXX specification bug: this should be specified
  else if (utils.isPrimitive(actual) || utils.isPrimitive(expected)) {
    return expected === actual;
  }

  else if (utils.instanceOf(actual, Error) ||
           utils.instanceOf(expected, Error)) {
    return actual.message === expected.message &&
           actual.type === expected.type &&
           actual.name === expected.name &&
           (actual.constructor && expected.constructor &&
            actual.constructor.name === expected.constructor.name)
  }

  // 7.3. Other pairs that do not both pass typeof value == "object",
  // equivalence is determined by ==.
  else if (!utils.isObject(actual) && !utils.isObject(expected)) {
    return actual == expected;
  }

  // 7.4. For all other Object pairs, including Array objects, equivalence is
  // determined by having the same number of owned properties (as verified
  // with Object.prototype.hasOwnProperty.call), the same set of keys
  // (although not necessarily the same order), equivalent values for every
  // corresponding key, and an identical "prototype" property. Note: this
  // accounts for both named and indexed properties on Arrays.
  else {
    return actual.prototype === expected.prototype &&
           isEquivalent(actual, expected);
  }
}

function isEquivalent(a, b, stack) {
  return isArrayEquivalent(Object.keys(a).sort(),
                           Object.keys(b).sort()) &&
          Object.keys(a).every(function(key) {
            return isDeepEqual(a[key], b[key], stack)
          });
}

function isArrayEquivalent(a, b, stack) {
  return utils.isArray(a) && utils.isArray(b) && a.length === b.length &&
         a.every(function(value, index) {
           return isDeepEqual(value, b[index]);
         });
}
<|endoftext|>