<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-3 09:04:47<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>import test from 'ava';
import semverRegex from './index.js';

const fixtures = [
	'0.0.0',
	'0.10.0',
	'v1.0.0',
	'0.0.0-foo',
	'1.2.3-4',
	'2.7.2+asdf',
	'1.2.3-a.b.c.10.d.5',
	'2.7.2-foo+bar',
	'1.2.3-alpha.10.beta',
	'1.2.3-alpha.10.beta+build.unicorn.rainbow',
	'foo 0.0.0 bar 0.0.0',
	'99999.99999.99999'
];

test('matches semver versions on test', t => {
	for (const fixture of fixtures) {
		t.regex(fixture, semverRegex());
	}

	t.notRegex('0.88', semverRegex());
	t.notRegex('1.0.08', semverRegex());
	t.notRegex('1.08.0', semverRegex());
	t.notRegex('01.8.0', semverRegex());
});

test('returns semver on match', t => {
	t.deepEqual('0.0.0'.match(semverRegex()), ['0.0.0']);
	t.deepEqual('foo 0.0.0 bar 0.1.1'.match(semverRegex()), ['0.0.0', '0.1.1']);
});

test('#7, does not return tag prefix', t => {
	t.deepEqual('v0.0.0'.match(semverRegex()), ['0.0.0']);
});

test('#14, does not match sub-strings of longer semver-similar strings, respect semver@2.0.0 clause 9', t => {
	// TODO: Some of these are disabled as we need to improve the regex.
	const invalidStrings = [
		'1',
		'1.2',
		// '1.2.3-0123',
		// '1.2.3-0123.0123',
		// '1.1.2+.123',
		'+invalid',
		'-invalid',
		'-invalid+invalid',
		'-invalid.01',
		'alpha',
		'alpha.beta',
		'alpha.beta.1',
		'alpha.1',
		'alpha+beta',
		'alpha_beta',
		'alpha.',
		'alpha..',
		'beta',
		// '1.0.0-alpha_beta',
		'-alpha.',
		// '1.0.0-alpha..',
		// '1.0.0-alpha..1',
		// '1.0.0-alpha...1',
		// '1.0.0-alpha....1',
		// '1.0.0-alpha.....1',
		// '1.0.0-alpha......1',
		// '1.0.0-alpha.......1',
		'01.1.1',
		'1.01.1',
		'1.1.01',
		'1.2',
		// '1.2.3.DEV',
		'1.2-SNAPSHOT',
		// '1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788',
		'1.2-RC-SNAPSHOT',
		'-1.0.3-gamma+b7718',
		'+justmeta'
		// '9.8.7+meta+meta',
		// '9.8.7-whatever+meta+meta',
		// '99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12'
	];

	for (const string of invalidStrings) {
		t.notRegex(string, semverRegex());
	}
});

test('#18, allow 0 as numeric identifier', t => {
	for (const string of [
		'0.2.3-alpha.10.beta+build.unicorn.rainbow',
		'1.0.3-alpha.10.beta+build.unicorn.rainbow',
		'1.2.0-alpha.10.beta+build.unicorn.rainbow',
		'1.2.3-0.10.beta+build.unicorn.rainbow',
		'1.2.3-alpha.0.beta+build.unicorn.rainbow',
		'1.2.3-alpha.10.0+build.unicorn.rainbow'
	]) {
		t.regex(string, semverRegex());
	}
});

// If tests take longer than a second, it's stuck on this and we have catatrophic backtracking.
test('invalid version does not cause catatrophic backtracking', t => {
	t.regex(
		'v1.1.3-0aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$',
		semverRegex()
	);

	const postfix = '.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.repeat(99999);
	t.regex(
		`v1.1.3-0aa${postfix}$`,
		semverRegex()
	);

	for (let index = 1; index <= 50000; index++) {
		const start = Date.now();
		const fixture = `0.0.0-0${'.-------'.repeat(index)}@`;
		semverRegex().test(fixture);
		const difference = Date.now() - start;
		t.true(difference < 10, `Execution time: ${difference}`);
	}

	for (let index = 1; index <= 20; index++) {
		const start = Date.now();
		const fixture = `0.0.1-${'-.--'.repeat(index)} `;
		semverRegex().test(fixture);
		const difference = Date.now() - start;
		t.true(difference < 10, `Execution time: ${difference}`);
	}
});
<commit_msg>Fix CI<commit_after>import test from 'ava';
import semverRegex from './index.js';

const fixtures = [
	'0.0.0',
	'0.10.0',
	'v1.0.0',
	'0.0.0-foo',
	'1.2.3-4',
	'2.7.2+asdf',
	'1.2.3-a.b.c.10.d.5',
	'2.7.2-foo+bar',
	'1.2.3-alpha.10.beta',
	'1.2.3-alpha.10.beta+build.unicorn.rainbow',
	'foo 0.0.0 bar 0.0.0',
	'99999.99999.99999'
];

test('matches semver versions on test', t => {
	for (const fixture of fixtures) {
		t.regex(fixture, semverRegex());
	}

	t.notRegex('0.88', semverRegex());
	t.notRegex('1.0.08', semverRegex());
	t.notRegex('1.08.0', semverRegex());
	t.notRegex('01.8.0', semverRegex());
});

test('returns semver on match', t => {
	t.deepEqual('0.0.0'.match(semverRegex()), ['0.0.0']);
	t.deepEqual('foo 0.0.0 bar 0.1.1'.match(semverRegex()), ['0.0.0', '0.1.1']);
});

test('#7, does not return tag prefix', t => {
	t.deepEqual('v0.0.0'.match(semverRegex()), ['0.0.0']);
});

test('#14, does not match sub-strings of longer semver-similar strings, respect semver@2.0.0 clause 9', t => {
	// TODO: Some of these are disabled as we need to improve the regex.
	const invalidStrings = [
		'1',
		'1.2',
		// '1.2.3-0123',
		// '1.2.3-0123.0123',
		// '1.1.2+.123',
		'+invalid',
		'-invalid',
		'-invalid+invalid',
		'-invalid.01',
		'alpha',
		'alpha.beta',
		'alpha.beta.1',
		'alpha.1',
		'alpha+beta',
		'alpha_beta',
		'alpha.',
		'alpha..',
		'beta',
		// '1.0.0-alpha_beta',
		'-alpha.',
		// '1.0.0-alpha..',
		// '1.0.0-alpha..1',
		// '1.0.0-alpha...1',
		// '1.0.0-alpha....1',
		// '1.0.0-alpha.....1',
		// '1.0.0-alpha......1',
		// '1.0.0-alpha.......1',
		'01.1.1',
		'1.01.1',
		'1.1.01',
		'1.2',
		// '1.2.3.DEV',
		'1.2-SNAPSHOT',
		// '1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788',
		'1.2-RC-SNAPSHOT',
		'-1.0.3-gamma+b7718',
		'+justmeta'
		// '9.8.7+meta+meta',
		// '9.8.7-whatever+meta+meta',
		// '99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12'
	];

	for (const string of invalidStrings) {
		t.notRegex(string, semverRegex());
	}
});

test('#18, allow 0 as numeric identifier', t => {
	for (const string of [
		'0.2.3-alpha.10.beta+build.unicorn.rainbow',
		'1.0.3-alpha.10.beta+build.unicorn.rainbow',
		'1.2.0-alpha.10.beta+build.unicorn.rainbow',
		'1.2.3-0.10.beta+build.unicorn.rainbow',
		'1.2.3-alpha.0.beta+build.unicorn.rainbow',
		'1.2.3-alpha.10.0+build.unicorn.rainbow'
	]) {
		t.regex(string, semverRegex());
	}
});

// If tests take longer than a second, it's stuck on this and we have catatrophic backtracking.
test('invalid version does not cause catatrophic backtracking', t => {
	t.regex(
		'v1.1.3-0aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$',
		semverRegex()
	);

	const postfix = '.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.repeat(99999);
	t.regex(
		`v1.1.3-0aa${postfix}$`,
		semverRegex()
	);

	for (let index = 1; index <= 50000; index++) {
		const start = Date.now();
		const fixture = `0.0.0-0${'.-------'.repeat(index)}@`;
		semverRegex().test(fixture);
		const difference = Date.now() - start;
		t.true(difference < 20, `Execution time: ${difference}`);
	}

	for (let index = 1; index <= 20; index++) {
		const start = Date.now();
		const fixture = `0.0.1-${'-.--'.repeat(index)} `;
		semverRegex().test(fixture);
		const difference = Date.now() - start;
		t.true(difference < 20, `Execution time: ${difference}`);
	}
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-20 10:01:51<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>/*!
 * kind-error <https://github.com/tunnckoCore/kind-error>
 *
 * Copyright (c) 2015 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
 * Released under the MIT license.
 */

/* jshint asi:true, newcap:false */

'use strict'

var test = require('assertit')
var KindError = require('./index')

test('kind-error:', function () {
  test('should be able to invoke without `new` keyword', function (done) {
    var err = KindError()

    test.equal(err.name, 'KindError')
    test.equal(err.message, '')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should composed error object be instanceof Error', function (done) {
    var err = new KindError()

    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper name and dont have stack by default', function (done) {
    var err = new KindError()

    test.equal(err.name, 'KindError')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper stack if `showStack: true`', function (done) {
    var err = new KindError({showStack: true})

    test.ok(err.stack)
    test.equal(err.name, 'KindError')
    test.equal(err.stack.length > 5, true)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should dont have stack if showStack given but not true', function (done) {
    var err = new KindError({name: 'HideError', showStack: 123})

    test.equal(err.name, 'HideError')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support custom message', function (done) {
    var err = new KindError('foo bar')

    test.equal(err.name, 'KindError')
    test.equal(err.message, 'foo bar')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support custom properties', function (done) {
    var err = new KindError('foo bar', {custom: 123})

    test.equal(err.name, 'KindError')
    test.equal(err.message, 'foo bar')
    test.equal(err instanceof Error, true)
    test.equal(err.custom, 123)
    done()
  })
  test('should support change of name from opts', function (done) {
    var err = new KindError('custom name', {name: 'MyErr'})

    test.equal(err.name, 'MyErr')
    test.equal(err.message, 'custom name')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should override message when given in opts', function (done) {
    var err = new KindError('custom name', {name: 'MyErr', message: 'my msg'})

    test.equal(err.name, 'MyErr')
    test.equal(err.message, 'my msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support to give only object to constructor', function (done) {
    var err = new KindError({custom: 123, message: 'custom msg'})

    test.equal(err.name, 'KindError')
    test.equal(err.custom, 123)
    test.equal(err.message, 'custom msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should change `actual` to `typeof actual` if given', function (done) {
    var err = new KindError({
      name: 'AssertError',
      actual: 123,
      expected: 'string',
      message: 'assertion'
    })

    test.equal(err.name, 'AssertError')
    test.equal(err.value, 123)
    test.equal(err.actual, 'number')
    test.equal(err.expected, 'string')
    test.equal(err.inspected, '123')
    test.equal(err.message, 'assertion')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper .toString()', function (done) {
    var err = new KindError('proper to string', {name: 'ProperError'})

    test.equal(err.toString(), 'ProperError: proper to string')
    test.equal(err.toString().length > 10, true)
    test.equal(typeof err.toString, 'function')
    test.equal(typeof err.toString(), 'string')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should create `message`, if only `actual` and `expected` given', function (done) {
    var err = new KindError({
      name: 'AssertError',
      actual: 123,
      expected: 'array',
      showStack: true
    })

    test.equal(err.name, 'AssertError')
    test.equal(err.value, 123)
    test.equal(err.actual, 'number')
    test.equal(err.expected, 'array')
    test.equal(err.inspected, '123')
    test.equal(err.message, 'expect `array`, but `number` given')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should be able to pass error object as `options`', function (done) {
    var error = new TypeError()
    var err = new KindError(error)

    test.equal(err.name, 'TypeError')
    test.equal(err.message, '')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should inherit name from given error object', function (done) {
    var error = new SyntaxError()
    var err = new KindError(error)

    test.equal(err.name, 'SyntaxError')
    test.equal(err.message, '')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should inherit message from given error object', function (done) {
    var error = new TypeError('msg')
    var err = new KindError(error)

    test.equal(err.name, 'TypeError')
    test.equal(err.message, 'msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should work with falsey value in `opts.actual`, see #3', function (done) {
    require('./test/actual-falsey-values')
    done()
  })
  test('should create custom AppError class', function (done) {
    require('./test/app-error')
    done()
  })
})
<commit_msg>add one more test for toString<commit_after>/*!
 * kind-error <https://github.com/tunnckoCore/kind-error>
 *
 * Copyright (c) 2015 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
 * Released under the MIT license.
 */

/* jshint asi:true, newcap:false */

'use strict'

var test = require('assertit')
var KindError = require('./index')

test('kind-error:', function () {
  test('should be able to invoke without `new` keyword', function (done) {
    var err = KindError()

    test.equal(err.name, 'KindError')
    test.equal(err.message, '')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should composed error object be instanceof Error', function (done) {
    var err = new KindError()

    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper name and dont have stack by default', function (done) {
    var err = new KindError()

    test.equal(err.name, 'KindError')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper stack if `showStack: true`', function (done) {
    var err = new KindError({showStack: true})

    test.ok(err.stack)
    test.equal(err.name, 'KindError')
    test.equal(err.stack.length > 5, true)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should dont have stack if showStack given but not true', function (done) {
    var err = new KindError({name: 'HideError', showStack: 123})

    test.equal(err.name, 'HideError')
    test.equal(err.stack, undefined)
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support custom message', function (done) {
    var err = new KindError('foo bar')

    test.equal(err.name, 'KindError')
    test.equal(err.message, 'foo bar')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support custom properties', function (done) {
    var err = new KindError('foo bar', {custom: 123})

    test.equal(err.name, 'KindError')
    test.equal(err.message, 'foo bar')
    test.equal(err instanceof Error, true)
    test.equal(err.custom, 123)
    done()
  })
  test('should support change of name from opts', function (done) {
    var err = new KindError('custom name', {name: 'MyErr'})

    test.equal(err.name, 'MyErr')
    test.equal(err.message, 'custom name')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should override message when given in opts', function (done) {
    var err = new KindError('custom name', {name: 'MyErr', message: 'my msg'})

    test.equal(err.name, 'MyErr')
    test.equal(err.message, 'my msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should support to give only object to constructor', function (done) {
    var err = new KindError({custom: 123, message: 'custom msg'})

    test.equal(err.name, 'KindError')
    test.equal(err.custom, 123)
    test.equal(err.message, 'custom msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should change `actual` to `typeof actual` if given', function (done) {
    var err = new KindError({
      name: 'AssertError',
      actual: 123,
      expected: 'string',
      message: 'assertion'
    })

    test.equal(err.name, 'AssertError')
    test.equal(err.value, 123)
    test.equal(err.actual, 'number')
    test.equal(err.expected, 'string')
    test.equal(err.inspected, '123')
    test.equal(err.message, 'assertion')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should have proper .toString()', function (done) {
    var err = new KindError('proper to string', {name: 'ProperError'})

    test.equal(err.toString(), 'ProperError: proper to string')
    test.equal(err.toString().length > 10, true)
    test.equal(typeof err.toString, 'function')
    test.equal(typeof err.toString(), 'string')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should have better .toString() when `actual` and `expected`', function (done) {
    var err = new KindError({
      name: 'BetterError',
      actual: {foo: 'bar'},
      expected: 'string'
    })
    var str = err.toString()

    test.ok(str.indexOf('actual: object') !== -1)
    test.ok(str.indexOf('expected: string') !== -1)
    test.ok(str.indexOf('BetterError: expect `string`, but `object` given') !== -1)
    test.equal(err.toString().length > 10, true)
    test.equal(typeof err.toString, 'function')
    test.equal(typeof err.toString(), 'string')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should create `message`, if only `actual` and `expected` given', function (done) {
    var err = new KindError({
      name: 'AssertError',
      actual: 123,
      expected: 'array',
      showStack: true
    })

    test.equal(err.name, 'AssertError')
    test.equal(err.value, 123)
    test.equal(err.actual, 'number')
    test.equal(err.expected, 'array')
    test.equal(err.inspected, '123')
    test.equal(err.message, 'expect `array`, but `number` given')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should be able to pass error object as `options`', function (done) {
    var error = new TypeError()
    var err = new KindError(error)

    test.equal(err.name, 'TypeError')
    test.equal(err.message, '')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should inherit name from given error object', function (done) {
    var error = new SyntaxError()
    var err = new KindError(error)

    test.equal(err.name, 'SyntaxError')
    test.equal(err.message, '')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should inherit message from given error object', function (done) {
    var error = new TypeError('msg')
    var err = new KindError(error)

    test.equal(err.name, 'TypeError')
    test.equal(err.message, 'msg')
    test.equal(err instanceof Error, true)
    done()
  })
  test('should work with falsey value in `opts.actual`, see #3', function (done) {
    require('./test/actual-falsey-values')
    done()
  })
  test('should create custom AppError class', function (done) {
    require('./test/app-error')
    done()
  })
})
<|endoftext|>


<commit_before>import expect from 'expect'
import React from 'react'
import { createMemoryHistory } from 'history'
import { createRoutes } from '../RouteUtils'
import matchRoutes from '../matchRoutes'
import Route from '../Route'
import IndexRoute from '../IndexRoute'
import shouldWarn from './shouldWarn'

describe('matchRoutes', function () {
  let routes
  let
    RootRoute, UsersRoute, UsersIndexRoute, UserRoute, PostRoute, FilesRoute,
    AboutRoute, TeamRoute, ProfileRoute, GreedyRoute, OptionalRoute,
    OptionalRouteChild, CatchAllRoute
  let createLocation = createMemoryHistory().createLocation

  beforeEach(function () {
    /*
    <Route>
      <Route path="users">
        <IndexRoute />
        <Route path=":userID">
          <Route path="/profile" />
        </Route>
        <Route path="/team" />
      </Route>
    </Route>
    <Route path="/about" />
    <Route path="/(optional)">
      <Route path="child" />
    </Route>
    <Route path="*" />
    */
    routes = [
      RootRoute = {
        childRoutes: [
          UsersRoute = {
            path: 'users',
            indexRoute: (UsersIndexRoute = {}),
            childRoutes: [
              UserRoute = {
                path: ':userID',
                childRoutes: [
                  ProfileRoute = {
                    path: '/profile'
                  },
                  PostRoute = {
                    path: ':postID'
                  }
                ]
              },
              TeamRoute = {
                path: '/team'
              }
            ]
          }
        ]
      },
      FilesRoute = {
        path: '/files/*/*.jpg'
      },
      AboutRoute = {
        path: '/about'
      },
      GreedyRoute = {
        path: '/**/f'
      },
      OptionalRoute = {
        path: '/(optional)',
        childRoutes: [
          OptionalRouteChild = {
            path: 'child'
          }
        ]
      },
      CatchAllRoute = {
        path: '*'
      }
    ]
  })

  function describeRoutes() {
    describe('when the location matches an index route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/users'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UsersIndexRoute ])
          done()
        })
      })
    })

    describe('when the location matches a nested route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute ])
          expect(match.params).toEqual({ userID: '5' })
          done()
        })
      })
    })

    describe('when the location matches a deeply nested route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5/abc'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, PostRoute ])
          expect(match.params).toEqual({ userID: '5', postID: 'abc' })
          done()
        })
      })
    })

    describe('when the location matches a nested route with multiple splat params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/files/a/b/c.jpg'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ FilesRoute ])
          expect(match.params).toEqual({ splat: [ 'a', 'b/c' ] })
          done()
        })
      })
    })

    describe('when the location matches a nested route with a greedy splat param', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/foo/bar/f'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ GreedyRoute ])
          expect(match.params).toEqual({ splat: 'foo/bar' })
          done()
        })
      })
    })

    describe('when the location matches a route with hash', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/users#about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UsersIndexRoute ])
          done()
        })
      })
    })

    describe('when the location matches a deeply nested route with params and hash', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5/abc#about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, PostRoute ])
          expect(match.params).toEqual({ userID: '5', postID: 'abc' })
          done()
        })
      })
    })

    describe('when the location matches an absolute route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ AboutRoute ])
          done()
        })
      })
    })

    describe('when the location matches an optional route', function () {
      it('matches when the optional pattern is missing', function (done) {
        matchRoutes(routes, createLocation('/'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute ])
          done()
        })
      })

      it('matches when the optional pattern is present', function (done) {
        matchRoutes(routes, createLocation('/optional'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute ])
          done()
        })
      })
    })

    describe('when the location matches the child of an optional route', function () {
      it('matches when the optional pattern is missing', function (done) {
        matchRoutes(routes, createLocation('/child'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute, OptionalRouteChild ])
          done()
        })
      })

      it('matches when the optional pattern is present', function (done) {
        matchRoutes(routes, createLocation('/optional/child'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute, OptionalRouteChild ])
          done()
        })
      })
    })

    describe('when the location does not match any routes', function () {
      it('matches the "catch-all" route', function (done) {
        matchRoutes(routes, createLocation('/not-found'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })

      it('matches the "catch-all" route on a deep miss', function (done) {
        matchRoutes(routes, createLocation('/not-found/foo'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })

      it('matches the "catch-all" route on missing path separators', function (done) {
        matchRoutes(routes, createLocation('/optionalchild'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })
    })
  }

  describe('a synchronous route config', function () {
    describeRoutes()

    describe('when the location matches a nested absolute route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/team'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, TeamRoute ])
          done()
        })
      })
    })

    describe('when the location matches an absolute route nested under a route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/profile'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, ProfileRoute ])
          expect(match.params).toEqual({}) // no userID param
          done()
        })
      })
    })
  })

  describe('an asynchronous route config', function () {
    function makeAsyncRouteConfig(routes) {
      routes.forEach(function (route) {
        const { childRoutes, indexRoute } = route

        if (childRoutes) {
          delete route.childRoutes

          route.getChildRoutes = function (partialNextState, callback) {
            setTimeout(function () {
              callback(null, childRoutes)
            })
          }

          makeAsyncRouteConfig(childRoutes)
        }

        if (indexRoute) {
          delete route.indexRoute

          route.getIndexRoute = function (location, callback) {
            setTimeout(function () {
              callback(null, indexRoute)
            })
          }
        }
      })
    }

    beforeEach(function () {
      makeAsyncRouteConfig(routes)
    })

    describeRoutes()
  })

  describe('an asynchronous JSX route config', function () {
    let getChildRoutes, getIndexRoute, jsxRoutes

    beforeEach(function () {
      getChildRoutes = function (partialNextState, callback) {
        setTimeout(function () {
          callback(null, <Route path=":userID" />)
        })
      }

      getIndexRoute = function (location, callback) {
        setTimeout(function () {
          callback(null, <Route name="jsx" />)
        })
      }

      jsxRoutes = createRoutes([
        <Route name="users"
               path="users"
               getChildRoutes={getChildRoutes}
               getIndexRoute={getIndexRoute} />
      ])
    })

    it('when getChildRoutes callback returns reactElements', function (done) {
      matchRoutes(jsxRoutes, createLocation('/users/5'), function (error, match) {
        expect(match).toExist()
        expect(match.routes.map(r => r.path)).toEqual([ 'users', ':userID' ])
        expect(match.params).toEqual({ userID: '5' })
        done()
      })
    })

    it('when getIndexRoute callback returns reactElements', function (done) {
      matchRoutes(jsxRoutes, createLocation('/users'), function (error, match) {
        expect(match).toExist()
        expect(match.routes.map(r => r.name)).toEqual([ 'users', 'jsx' ])
        done()
      })
    })
  })

  describe('a nested route with a getChildRoutes callback', function () {
    let getChildRoutes, jsxRoutes

    beforeEach(function () {
      getChildRoutes = function (partialNextState, callback) {
        setTimeout(function () {
          callback(null, partialNextState)
        })
      }

      jsxRoutes = createRoutes([
        <Route name="users"
               path="users/:id">
          <Route name="topic"
                path=":topic"
                getChildRoutes={getChildRoutes} />
        </Route>
      ])
    })

    it('when getChildRoutes callback returns partialNextState', function (done) {
      matchRoutes(jsxRoutes, createLocation('/users/5/details'), function (error, partialNextState) {
        expect(partialNextState).toExist()
        expect(partialNextState.params).toEqual({ id: '5', topic: 'details' })
        done()
      })
    })
  })

  it('complains about invalid index route with path', function (done) {
    shouldWarn('path')

    const invalidRoutes = createRoutes(
      <Route path="/">
        <IndexRoute path="foo" />
      </Route>
    )

    matchRoutes(invalidRoutes, createLocation('/'), function (error, match) {
      expect(match).toExist()
      done()
    })
  })

  it('supports splat under pathless route at root', function (done) {
    const routes = createRoutes(
      <Route>
        <Route path="*" />
      </Route>
    )

    matchRoutes(routes, createLocation('/'), function (error, match) {
      expect(match).toExist()
      done()
    })
  })
})
<commit_msg>Update and consolidate tests<commit_after>import expect from 'expect'
import React from 'react'
import { createMemoryHistory } from 'history'
import { createRoutes } from '../RouteUtils'
import matchRoutes from '../matchRoutes'
import Route from '../Route'
import IndexRoute from '../IndexRoute'
import shouldWarn from './shouldWarn'

describe('matchRoutes', function () {
  let routes
  let
    RootRoute, UsersRoute, UsersIndexRoute, UserRoute, PostRoute, FilesRoute,
    AboutRoute, TeamRoute, ProfileRoute, GreedyRoute, OptionalRoute,
    OptionalRouteChild, CatchAllRoute
  let createLocation = createMemoryHistory().createLocation

  beforeEach(function () {
    /*
    <Route>
      <Route path="users">
        <IndexRoute />
        <Route path=":userID">
          <Route path="/profile" />
        </Route>
        <Route path="/team" />
      </Route>
    </Route>
    <Route path="/about" />
    <Route path="/(optional)">
      <Route path="child" />
    </Route>
    <Route path="*" />
    */
    routes = [
      RootRoute = {
        childRoutes: [
          UsersRoute = {
            path: 'users',
            indexRoute: (UsersIndexRoute = {}),
            childRoutes: [
              UserRoute = {
                path: ':userID',
                childRoutes: [
                  ProfileRoute = {
                    path: '/profile'
                  },
                  PostRoute = {
                    path: ':postID'
                  }
                ]
              },
              TeamRoute = {
                path: '/team'
              }
            ]
          }
        ]
      },
      FilesRoute = {
        path: '/files/*/*.jpg'
      },
      AboutRoute = {
        path: '/about'
      },
      GreedyRoute = {
        path: '/**/f'
      },
      OptionalRoute = {
        path: '/(optional)',
        childRoutes: [
          OptionalRouteChild = {
            path: 'child'
          }
        ]
      },
      CatchAllRoute = {
        path: '*'
      }
    ]
  })

  function describeRoutes() {
    describe('when the location matches an index route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/users'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UsersIndexRoute ])
          done()
        })
      })
    })

    describe('when the location matches a nested route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute ])
          expect(match.params).toEqual({ userID: '5' })
          done()
        })
      })
    })

    describe('when the location matches a deeply nested route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5/abc'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, PostRoute ])
          expect(match.params).toEqual({ userID: '5', postID: 'abc' })
          done()
        })
      })
    })

    describe('when the location matches a nested route with multiple splat params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/files/a/b/c.jpg'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ FilesRoute ])
          expect(match.params).toEqual({ splat: [ 'a', 'b/c' ] })
          done()
        })
      })
    })

    describe('when the location matches a nested route with a greedy splat param', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/foo/bar/f'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ GreedyRoute ])
          expect(match.params).toEqual({ splat: 'foo/bar' })
          done()
        })
      })
    })

    describe('when the location matches a route with hash', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/users#about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UsersIndexRoute ])
          done()
        })
      })
    })

    describe('when the location matches a deeply nested route with params and hash', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/users/5/abc#about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, PostRoute ])
          expect(match.params).toEqual({ userID: '5', postID: 'abc' })
          done()
        })
      })
    })

    describe('when the location matches an absolute route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/about'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ AboutRoute ])
          done()
        })
      })
    })

    describe('when the location matches an optional route', function () {
      it('matches when the optional pattern is missing', function (done) {
        matchRoutes(routes, createLocation('/'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute ])
          done()
        })
      })

      it('matches when the optional pattern is present', function (done) {
        matchRoutes(routes, createLocation('/optional'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute ])
          done()
        })
      })
    })

    describe('when the location matches the child of an optional route', function () {
      it('matches when the optional pattern is missing', function (done) {
        matchRoutes(routes, createLocation('/child'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute, OptionalRouteChild ])
          done()
        })
      })

      it('matches when the optional pattern is present', function (done) {
        matchRoutes(routes, createLocation('/optional/child'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ OptionalRoute, OptionalRouteChild ])
          done()
        })
      })
    })

    describe('when the location does not match any routes', function () {
      it('matches the "catch-all" route', function (done) {
        matchRoutes(routes, createLocation('/not-found'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })

      it('matches the "catch-all" route on a deep miss', function (done) {
        matchRoutes(routes, createLocation('/not-found/foo'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })

      it('matches the "catch-all" route on missing path separators', function (done) {
        matchRoutes(routes, createLocation('/optionalchild'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ CatchAllRoute ])
          done()
        })
      })
    })
  }

  describe('a synchronous route config', function () {
    describeRoutes()

    describe('when the location matches a nested absolute route', function () {
      it('matches the correct routes', function (done) {
        matchRoutes(routes, createLocation('/team'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, TeamRoute ])
          done()
        })
      })
    })

    describe('when the location matches an absolute route nested under a route with params', function () {
      it('matches the correct routes and params', function (done) {
        matchRoutes(routes, createLocation('/profile'), function (error, match) {
          expect(match).toExist()
          expect(match.routes).toEqual([ RootRoute, UsersRoute, UserRoute, ProfileRoute ])
          expect(match.params).toEqual({}) // no userID param
          done()
        })
      })
    })
  })

  describe('an asynchronous route config', function () {
    function makeAsyncRouteConfig(routes) {
      routes.forEach(function (route) {
        const { childRoutes, indexRoute } = route

        if (childRoutes) {
          delete route.childRoutes

          route.getChildRoutes = function (partialNextState, callback) {
            setTimeout(function () {
              callback(null, childRoutes)
            })
          }

          makeAsyncRouteConfig(childRoutes)
        }

        if (indexRoute) {
          delete route.indexRoute

          route.getIndexRoute = function (location, callback) {
            setTimeout(function () {
              callback(null, indexRoute)
            })
          }
        }
      })
    }

    beforeEach(function () {
      makeAsyncRouteConfig(routes)
    })

    describeRoutes()
  })

  describe('an asynchronous JSX route config', function () {
    let getChildRoutes, getIndexRoute, jsxRoutes, jsxNestedRoutes, state

    beforeEach(function () {
      getChildRoutes = function (partialNextState, callback) {
        state = partialNextState
        setTimeout(function () {
          callback(null, <Route path=":userID" />)
        })
      }

      getIndexRoute = function (location, callback) {
        setTimeout(function () {
          callback(null, <Route name="jsx" />)
        })
      }

      jsxRoutes = createRoutes([
        <Route name="users"
               path="users"
               getChildRoutes={getChildRoutes}
               getIndexRoute={getIndexRoute} />
      ])

      jsxNestedRoutes = createRoutes([
        <Route name="users"
              path="users/:id">
          <Route name="topic"
                path=":topic"
                getChildRoutes={getChildRoutes} />
        </Route>
      ])
    })

    it('when getChildRoutes callback returns reactElements', function (done) {
      matchRoutes(jsxRoutes, createLocation('/users/5'), function (error, match) {
        expect(match).toExist()
        expect(match.routes.map(r => r.path)).toEqual([ 'users', ':userID' ])
        expect(match.params).toEqual({ userID: '5' })
        done()
      })
    })

    it('when getIndexRoute callback returns reactElements', function (done) {
      matchRoutes(jsxRoutes, createLocation('/users'), function (error, match) {
        expect(match).toExist()
        expect(match.routes.map(r => r.name)).toEqual([ 'users', 'jsx' ])
        done()
      })
    })

    it('when getChildRoutes callback returns partialNextState', function (done) {
      matchRoutes(jsxNestedRoutes, createLocation('/users/5/details/others'), function () {
        expect(state).toExist()
        expect(state.params).toEqual({ id: '5', topic: 'details' })
        done()
      })
    })
  })

  it('complains about invalid index route with path', function (done) {
    shouldWarn('path')

    const invalidRoutes = createRoutes(
      <Route path="/">
        <IndexRoute path="foo" />
      </Route>
    )

    matchRoutes(invalidRoutes, createLocation('/'), function (error, match) {
      expect(match).toExist()
      done()
    })
  })

  it('supports splat under pathless route at root', function (done) {
    const routes = createRoutes(
      <Route>
        <Route path="*" />
      </Route>
    )

    matchRoutes(routes, createLocation('/'), function (error, match) {
      expect(match).toExist()
      done()
    })
  })
})
<|endoftext|>


<commit_before>'use strict'

/* global require, describe, it */
var translate = require('./index')
var expect = require('expect.js')

describe('translate.js', function () {
  var translationsObject = {
    plain: 'I like this.',
    like: 'I like {thing}!',
    simpleCounter: 'The count is {n}.',
    hits: {
      0: 'No Hits',
      1: '{n} Hit',
      2: '{n} Hitse', // some slavic langs have multiple plural forms
      3: '{n} Hitses', // some slavic langs have multiple plural forms
      n: '{n} Hits' // default
    },
    icelandicSheep: {
      0: 'Engar kindur',
      s: '{n} kind', // some languages use singular for any number that ends with 1 (i.e. 101, 21, 31, 51)
      p: '{n} kindur',
      13: 'Baaahd luck!' // Aribtrary translation outside of pluralization rules
    },
    horses: {
      n: 'Pluralization keys are missing' // default fallback
    },
    date: {
      1: '{day}. January {year}',
      2: '{day}. February {year}',
      3: '{day}. March {year}',
      4: '{day}. April {year}',
      5: '{day}. May {year}',
      6: '{day}. June {year}',
      7: '{day}. July {year}',
      8: '{day}. August {year}',
      9: '{day}. September {year}',
      10: '{day}. October {year}',
      11: '{day}. November {year}',
      12: '{day}. December {year}'
    },

    'Prosa Key': 'This is prosa!',

    comboCounter: '{name} is {n} years old.',
    translationWithSubkeys: { 'foo': 'FOO' }
  }

  var t = translate(translationsObject)

  it('should return translationKey if no translation is found', function () {
    expect(t('nonexistentkey')).to.equal('nonexistentkey')
  })

  it('should return a translated string', function () {
    expect(t('plain')).to.equal('I like this.')
  })

  it('should return a translated string for prosa keys', function () {
    expect(t('Prosa Key')).to.equal('This is prosa!')
  })

  it('should return a translated string and replace a placeholder ', function () {
    expect(t('like', {thing: 'Sun'})).to.equal('I like Sun!')
  })

  it('should return a translated string and show missing placeholders', function () {
    expect(t('like')).to.equal('I like {thing}!')
  })

  it('should return a translated string and replace a count', function () {
    expect(t('simpleCounter', 25)).to.equal('The count is 25.')
  })

  it('should return a translated string according to a potential dynamic subkey', function () {
    var dynamicSubKey = 'foo';
    expect(t('translationWithSubkeys', dynamicSubKey)).to.equal('FOO')
  })

  it('should return a translated string with the correct plural form (0)', function () {
    expect(t('hits', 0)).to.equal('No Hits')
  })

  it('should return a translated string with the correct plural form (1)', function () {
    expect(t('hits', 1)).to.equal('1 Hit')
  })

  it('should return a translated string with the correct plural form (2)', function () {
    expect(t('hits', 2)).to.equal('2 Hitse')
  })

  it('should return a translated string with the correct plural form (3)', function () {
    expect(t('hits', 3)).to.equal('3 Hitses')
  })

  it('should return a translated string with the correct plural form (4)', function () {
    expect(t('hits', 4)).to.equal('4 Hits')
  })

  it('should return a translated string with the correct plural form and replaced placeholders: t(key, replacements, count)', function () {
    expect(t('date', {day: '13', year: 2014}, 2)).to.equal('13. February 2014')
  })

  it('should return a translated string with the correct plural form and replaced placeholders: t(key, count, replacements)', function () {
    expect(t('date', 2, {day: '13', year: 2014})).to.equal('13. February 2014')
  })

  var placeholders = { name: 'Alice' }
  it('should handle combination of count and named placeholders', function () {
    expect(t('comboCounter', 10, placeholders)).to.equal('Alice is 10 years old.')
    expect(t('comboCounter', placeholders, 10)).to.equal('Alice is 10 years old.')
  })
  it("shouldn't modify the placeholder object", function () {
    expect('n' in placeholders).to.equal(false)
  })

  var nonstringtranslations = {
    foo: 10,
    bar: [],
    baz: {},
    heh: null,
    ooh: true,
    happensToBeString: 'OK'
  }
  var t0 = translate(nonstringtranslations)
  it('should treat any non-string translations as missing', function () {
    expect(t0('foo')).to.equal('foo')
    expect(t0('bar')).to.equal('bar')
    expect(t0('baz')).to.equal('baz')
    expect(t0('heh')).to.equal('heh')
    expect(t0('ooh')).to.equal('ooh')
    expect(t0('happensToBeString')).to.equal('OK')
  })

  // custom isPlural function
  var pluralize_IS = function (n /*, tarlationKey*/) {
    // Icelandic rules: Numbers ending in 1 are singular - unless ending in 11.
    return (n % 10 !== 1 || n % 100 === 11) ? 'p' : 's'
  }
  var t3b = translate(translationsObject, { pluralize: pluralize_IS })
  it('should pluralize (0) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 0)).to.equal('Engar kindur')
  })
  it('should pluralize (1) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 1)).to.equal('1 kind')
  })
  it('should pluralize (2) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 2)).to.equal('2 kindur')
  })
  it('should pluralize (11) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 11)).to.equal('11 kindur')
  })
  it('should pluralize (21) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 21)).to.equal('21 kind')
  })
  it('should pluralize (29) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 29)).to.equal('29 kindur')
  })
  it('should automatically return correct pluralization for negative counts', function () {
    expect(t3b('icelandicSheep', -21)).to.equal('-21 kind')
    expect(t3b('icelandicSheep', -29)).to.equal('-29 kindur')
  })
  it('should return explicit pluralization property regardless of pluralization function', function () {
    expect(t3b('icelandicSheep', 13)).to.equal('Baaahd luck!')
  })
  it('should not match negative count with its explicitly defined positive counterpart', function () {
    expect(t3b('icelandicSheep', -13)).to.equal('-13 kindur')
  })
  it('should default to the `n` key if some/all pluralization keys are missing', function () {
    expect(t3b('horses', 7)).to.equal('Pluralization keys are missing')
  })

  it('should ignore count/subkey if translation is a plain string', function () {
    expect(t3b('plain', 666)).to.equal('I like this.')
    expect(t3b('plain', 'nonexistentsubkey')).to.equal('I like this.')
  })
  it('should ignore replacements object if translation is a plain string', function () {
    expect(t3b('plain', {nonexistentreplacement: 'foo'})).to.equal('I like this.')
  })

  // wrong arguments
  var t4 = translate(translationsObject, 'asd')
  it('should return a translated string with the correct plural form and replaced placeholders: t(key, count, replacements) [wrong optio arg]', function () {
    expect(t4('date', 2, {day: '13', year: 2014})).to.equal('13. February 2014')
  })

  // debug enabled
  var t5 = translate(translationsObject, {debug: true})
  it('should return @@translationKey@@/@@translationKey.subKey@@ if no translation is found and debug is true', function () {
    expect(t5('nonexistentkey')).to.equal('@@nonexistentkey@@')
    expect(t5('translationWithSubkeys', 'not there')).to.equal('@@translationWithSubkeys.not there@@')
    expect(t5('translationWithSubkeys', 42)).to.equal('@@translationWithSubkeys.42@@')
    expect(t5('nonexistentkey', 42)).to.equal('@@nonexistentkey.42@@')
  })

  var t6Keys = {
    fruit: '{0} apples, {1} oranges, {2} kiwis',
    bread: '{0} buns, {n} scones',
    items: {
      1: '{0} item ({n})',
      n: '{0} items ({n})'
    }
  }
  var t6 = translate(t6Keys)
  it('should accept placeholder values in arrays', function () {
    expect(t6('fruit', ['shiny', 'round'])).to.equal('shiny apples, round oranges, {2} kiwis')
  })
  it('should mix count and array placeholders', function () {
    expect(t6('bread', 7, [10])).to.equal('10 buns, 7 scones')
    expect(t6('bread', [7], 10)).to.equal('7 buns, 10 scones')
  })
  it('should mix array placeholders and pluralization', function () {
    expect(t6('items', 1, ['Happy'])).to.equal('Happy item (1)')
    expect(t6('items', 7, ['Funny'])).to.equal('Funny items (7)')
  })

  var tXKeys = {
    name: 'English',
    x: {
      13: 'Thirteen',
      99: 'Ninety-nine',
      n: 'Default'
    }
  }
  var tX

  it('should gracefully handle no parameters', function () {
    tX = translate()
    expect(tX('name')).to.equal('name')
    expect(tX('x', 1)).to.equal('x')
  })

  it('should gracefully handle nully (not falsey) parameters', function () {
    tX = translate(undefined, null)
    expect(tX('name')).to.equal('name')
    expect(tX('x', 1)).to.equal('x')
  })

  it('should expose .keys and .opts properties', function () {
    expect(tX.keys).to.be.an('object')
    expect(tX.opts).to.be.an('object')
    expect(tX.keys).to.eql({})
  })

  it('should allow late binding of translation keys', function () {
    tX.keys.foo = 'bar'
    expect(tX('foo')).to.equal('bar')
  })

  it('should allow late binding of translation keys', function () {
    tX.keys = tXKeys
    expect(tX('foo')).to.equal('foo')
    expect(tX('name')).to.equal('English')
    expect(tX('x', 1)).to.equal('Default')
  })

  it('should allow late binding of pluralization', function () {
    tX.opts.pluralize = function (n) { return 99 }
    expect(tX('x', 1)).to.equal('Ninety-nine')
  })

  it('should gracefully handle completely overloading the opts', function () {
    tX.opts = {pluralize: function (n) { return 13 }}
    expect(tX('x', 1)).to.equal('Thirteen')
  })

  it('should gracefully handle accidental removal of opts', function () {
    delete tX.opts // Oops!
    expect(tX('x', 1)).to.equal('Default') // no pluralization found
  })

  it('should handle adjacent placeholders', function () {
    var t = translate({ test: '{foo}{bar}' })
    expect(t('test', {foo: 'Hello', bar: 'World'})).to.equal('HelloWorld')
  })

  it('should handle the placeholder tokens used internally by `replacePlaceholders()`', function () {
    var t = translate({ test: '{x}' })
    expect(t('test', { x: 'HelloWorld' })).to.equal('HelloWorld')
  })
})

describe('Return array option', function () {
  it('should return replacement-token translations as Arrays, when t.arr() is called', function () {
    var t = translate({
      test: 'abc {xyz} def'
    })
    expect(t.arr('test', { xyz: { foo: 'bar' } })).to.eql(['abc ', { foo: 'bar' }, ' def'])
  })
  it('should return replacement-token translations as Arrays, when `array` option is supplied', function () {
    var t = translate({
      test: 'abc {xyz} def'
    }, { array:true })
    expect(t('test', { xyz: { foo: 'bar' } })).to.eql(['abc ', { foo: 'bar' }, ' def'])
  })
})<commit_msg>Add tests for current behaviour of t.arr()<commit_after>'use strict'

/* global require, describe, it */
var translate = require('./index')
var expect = require('expect.js')

describe('translate.js', function () {
  var translationsObject = {
    plain: 'I like this.',
    like: 'I like {thing}!',
    simpleCounter: 'The count is {n}.',
    hits: {
      0: 'No Hits',
      1: '{n} Hit',
      2: '{n} Hitse', // some slavic langs have multiple plural forms
      3: '{n} Hitses', // some slavic langs have multiple plural forms
      n: '{n} Hits' // default
    },
    icelandicSheep: {
      0: 'Engar kindur',
      s: '{n} kind', // some languages use singular for any number that ends with 1 (i.e. 101, 21, 31, 51)
      p: '{n} kindur',
      13: 'Baaahd luck!' // Aribtrary translation outside of pluralization rules
    },
    horses: {
      n: 'Pluralization keys are missing' // default fallback
    },
    date: {
      1: '{day}. January {year}',
      2: '{day}. February {year}',
      3: '{day}. March {year}',
      4: '{day}. April {year}',
      5: '{day}. May {year}',
      6: '{day}. June {year}',
      7: '{day}. July {year}',
      8: '{day}. August {year}',
      9: '{day}. September {year}',
      10: '{day}. October {year}',
      11: '{day}. November {year}',
      12: '{day}. December {year}'
    },

    'Prosa Key': 'This is prosa!',

    comboCounter: '{name} is {n} years old.',
    translationWithSubkeys: { 'foo': 'FOO' }
  }

  var t = translate(translationsObject)

  it('should return translationKey if no translation is found', function () {
    expect(t('nonexistentkey')).to.equal('nonexistentkey')
  })

  it('should return a translated string', function () {
    expect(t('plain')).to.equal('I like this.')
  })

  it('should return a translated string for prosa keys', function () {
    expect(t('Prosa Key')).to.equal('This is prosa!')
  })

  it('should return a translated string and replace a placeholder ', function () {
    expect(t('like', {thing: 'Sun'})).to.equal('I like Sun!')
  })

  it('should return a translated string and show missing placeholders', function () {
    expect(t('like')).to.equal('I like {thing}!')
  })

  it('should return a translated string and replace a count', function () {
    expect(t('simpleCounter', 25)).to.equal('The count is 25.')
  })

  it('should return a translated string according to a potential dynamic subkey', function () {
    var dynamicSubKey = 'foo';
    expect(t('translationWithSubkeys', dynamicSubKey)).to.equal('FOO')
  })

  it('should return a translated string with the correct plural form (0)', function () {
    expect(t('hits', 0)).to.equal('No Hits')
  })

  it('should return a translated string with the correct plural form (1)', function () {
    expect(t('hits', 1)).to.equal('1 Hit')
  })

  it('should return a translated string with the correct plural form (2)', function () {
    expect(t('hits', 2)).to.equal('2 Hitse')
  })

  it('should return a translated string with the correct plural form (3)', function () {
    expect(t('hits', 3)).to.equal('3 Hitses')
  })

  it('should return a translated string with the correct plural form (4)', function () {
    expect(t('hits', 4)).to.equal('4 Hits')
  })

  it('should return a translated string with the correct plural form and replaced placeholders: t(key, replacements, count)', function () {
    expect(t('date', {day: '13', year: 2014}, 2)).to.equal('13. February 2014')
  })

  it('should return a translated string with the correct plural form and replaced placeholders: t(key, count, replacements)', function () {
    expect(t('date', 2, {day: '13', year: 2014})).to.equal('13. February 2014')
  })

  var placeholders = { name: 'Alice' }
  it('should handle combination of count and named placeholders', function () {
    expect(t('comboCounter', 10, placeholders)).to.equal('Alice is 10 years old.')
    expect(t('comboCounter', placeholders, 10)).to.equal('Alice is 10 years old.')
  })
  it("shouldn't modify the placeholder object", function () {
    expect('n' in placeholders).to.equal(false)
  })

  var nonstringtranslations = {
    foo: 10,
    bar: [],
    baz: {},
    heh: null,
    ooh: true,
    happensToBeString: 'OK'
  }
  var t0 = translate(nonstringtranslations)
  it('should treat any non-string translations as missing', function () {
    expect(t0('foo')).to.equal('foo')
    expect(t0('bar')).to.equal('bar')
    expect(t0('baz')).to.equal('baz')
    expect(t0('heh')).to.equal('heh')
    expect(t0('ooh')).to.equal('ooh')
    expect(t0('happensToBeString')).to.equal('OK')
  })

  // custom isPlural function
  var pluralize_IS = function (n /*, tarlationKey*/) {
    // Icelandic rules: Numbers ending in 1 are singular - unless ending in 11.
    return (n % 10 !== 1 || n % 100 === 11) ? 'p' : 's'
  }
  var t3b = translate(translationsObject, { pluralize: pluralize_IS })
  it('should pluralize (0) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 0)).to.equal('Engar kindur')
  })
  it('should pluralize (1) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 1)).to.equal('1 kind')
  })
  it('should pluralize (2) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 2)).to.equal('2 kindur')
  })
  it('should pluralize (11) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 11)).to.equal('11 kindur')
  })
  it('should pluralize (21) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 21)).to.equal('21 kind')
  })
  it('should pluralize (29) correctly in Icelandic', function () {
    expect(t3b('icelandicSheep', 29)).to.equal('29 kindur')
  })
  it('should automatically return correct pluralization for negative counts', function () {
    expect(t3b('icelandicSheep', -21)).to.equal('-21 kind')
    expect(t3b('icelandicSheep', -29)).to.equal('-29 kindur')
  })
  it('should return explicit pluralization property regardless of pluralization function', function () {
    expect(t3b('icelandicSheep', 13)).to.equal('Baaahd luck!')
  })
  it('should not match negative count with its explicitly defined positive counterpart', function () {
    expect(t3b('icelandicSheep', -13)).to.equal('-13 kindur')
  })
  it('should default to the `n` key if some/all pluralization keys are missing', function () {
    expect(t3b('horses', 7)).to.equal('Pluralization keys are missing')
  })

  it('should ignore count/subkey if translation is a plain string', function () {
    expect(t3b('plain', 666)).to.equal('I like this.')
    expect(t3b('plain', 'nonexistentsubkey')).to.equal('I like this.')
  })
  it('should ignore replacements object if translation is a plain string', function () {
    expect(t3b('plain', {nonexistentreplacement: 'foo'})).to.equal('I like this.')
  })

  // wrong arguments
  var t4 = translate(translationsObject, 'asd')
  it('should return a translated string with the correct plural form and replaced placeholders: t(key, count, replacements) [wrong optio arg]', function () {
    expect(t4('date', 2, {day: '13', year: 2014})).to.equal('13. February 2014')
  })

  // debug enabled
  var t5 = translate(translationsObject, {debug: true})
  it('should return @@translationKey@@/@@translationKey.subKey@@ if no translation is found and debug is true', function () {
    expect(t5('nonexistentkey')).to.equal('@@nonexistentkey@@')
    expect(t5('translationWithSubkeys', 'not there')).to.equal('@@translationWithSubkeys.not there@@')
    expect(t5('translationWithSubkeys', 42)).to.equal('@@translationWithSubkeys.42@@')
    expect(t5('nonexistentkey', 42)).to.equal('@@nonexistentkey.42@@')
  })

  var t6Keys = {
    fruit: '{0} apples, {1} oranges, {2} kiwis',
    bread: '{0} buns, {n} scones',
    items: {
      1: '{0} item ({n})',
      n: '{0} items ({n})'
    }
  }
  var t6 = translate(t6Keys)
  it('should accept placeholder values in arrays', function () {
    expect(t6('fruit', ['shiny', 'round'])).to.equal('shiny apples, round oranges, {2} kiwis')
  })
  it('should mix count and array placeholders', function () {
    expect(t6('bread', 7, [10])).to.equal('10 buns, 7 scones')
    expect(t6('bread', [7], 10)).to.equal('7 buns, 10 scones')
  })
  it('should mix array placeholders and pluralization', function () {
    expect(t6('items', 1, ['Happy'])).to.equal('Happy item (1)')
    expect(t6('items', 7, ['Funny'])).to.equal('Funny items (7)')
  })

  var tXKeys = {
    name: 'English',
    x: {
      13: 'Thirteen',
      99: 'Ninety-nine',
      n: 'Default'
    }
  }
  var tX

  it('should gracefully handle no parameters', function () {
    tX = translate()
    expect(tX('name')).to.equal('name')
    expect(tX('x', 1)).to.equal('x')
  })

  it('should gracefully handle nully (not falsey) parameters', function () {
    tX = translate(undefined, null)
    expect(tX('name')).to.equal('name')
    expect(tX('x', 1)).to.equal('x')
  })

  it('should expose .keys and .opts properties', function () {
    expect(tX.keys).to.be.an('object')
    expect(tX.opts).to.be.an('object')
    expect(tX.keys).to.eql({})
  })

  it('should allow late binding of translation keys', function () {
    tX.keys.foo = 'bar'
    expect(tX('foo')).to.equal('bar')
  })

  it('should allow late binding of translation keys', function () {
    tX.keys = tXKeys
    expect(tX('foo')).to.equal('foo')
    expect(tX('name')).to.equal('English')
    expect(tX('x', 1)).to.equal('Default')
  })

  it('should allow late binding of pluralization', function () {
    tX.opts.pluralize = function (n) { return 99 }
    expect(tX('x', 1)).to.equal('Ninety-nine')
  })

  it('should gracefully handle completely overloading the opts', function () {
    tX.opts = {pluralize: function (n) { return 13 }}
    expect(tX('x', 1)).to.equal('Thirteen')
  })

  it('should gracefully handle accidental removal of opts', function () {
    delete tX.opts // Oops!
    expect(tX('x', 1)).to.equal('Default') // no pluralization found
  })

  it('should handle adjacent placeholders', function () {
    var t = translate({ test: '{foo}{bar}' })
    expect(t('test', {foo: 'Hello', bar: 'World'})).to.equal('HelloWorld')
  })

  it('should handle the placeholder tokens used internally by `replacePlaceholders()`', function () {
    var t = translate({ test: '{x}' })
    expect(t('test', { x: 'HelloWorld' })).to.equal('HelloWorld')
  })
})

describe('Return array option', function () {
  it('should return replacement-token translations as Arrays, when t.arr() is called', function () {
    var t = translate({
      test: 'abc {xyz} def'
    })
    expect(t.arr('test', { xyz: { foo: 'bar' } })).to.eql(['abc ', { foo: 'bar' }, ' def'])
  })
  it('should return replacement-token translations as Arrays, when `array` option is supplied', function () {
    var t = translate({
      test: 'abc {xyz} def'
    }, { array:true })
    expect(t('test', { xyz: { foo: 'bar' } })).to.eql(['abc ', { foo: 'bar' }, ' def'])
  })
  it('should return simple translations as strings, even when t.arr() is called', function () {
    var t = translate({
      test1: 'simple',
      test2: { 4:'simple' },
      test3: { subkey:'simple' },
    })
    expect(t.arr('test1')).to.eql('simple')
    expect(t.arr('test2', 4)).to.eql('simple')
    expect(t.arr('test3', 'subkey')).to.eql('simple')
  })
})<|endoftext|>


<commit_before>/*!
 * helper-reflinks <https://github.com/jonschlinkert/helper-reflinks>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT License
 */

'use strict';

var should = require('should');
var handlebars = require('handlebars');
var _ = require('lodash');
var reflinksHelper = require('./');

function test(str) {
  return /\[lookup-deps\]/.test(str);
}

describe('helper reflinks', function () {
  var links = reflinksHelper();
  it('should return a formatted reflinks statement:', function () {
    test(links).should.be.true;
  });

  it('should work as a lodash helper:', function () {
    test(_.template('<%= reflinks() %>', {}, {imports: {reflinks: reflinksHelper}})).should.be.true;
  });

  it('should work as a lodash mixin:', function () {
    _.mixin({reflinks: reflinksHelper});
    test(_.template('<%= _.reflinks() %>', {})).should.be.true;
  });

  it('should work as a handlebars helper:', function () {
    handlebars.registerHelper('reflinks', reflinksHelper);
    test(handlebars.compile('{{reflinks "*"}}')()).should.be.true;
  });
});
<commit_msg>update tests for lodash changes<commit_after>/*!
 * helper-reflinks <https://github.com/jonschlinkert/helper-reflinks>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT License
 */

'use strict';

var should = require('should');
var handlebars = require('handlebars');
var _ = require('lodash');
var reflinksHelper = require('./');

function test(str) {
  return /\[lookup-deps\]/.test(str);
}

describe('helper reflinks', function () {
  var links = reflinksHelper();
  it('should return a formatted reflinks statement:', function () {
    test(links).should.be.true;
  });

  it('should work as a lodash helper:', function () {
    test(_.template('<%= reflinks() %>', {imports: {reflinks: reflinksHelper}})({})).should.be.true;
  });

  it('should work as a lodash mixin:', function () {
    _.mixin({reflinks: reflinksHelper});
    test(_.template('<%= _.reflinks() %>')({})).should.be.true;
  });

  it('should work as a handlebars helper:', function () {
    handlebars.registerHelper('reflinks', reflinksHelper);
    test(handlebars.compile('{{reflinks "*"}}')()).should.be.true;
  });
});
<|endoftext|>


<commit_before>var assert = require('assert');

var time = require('./');

var d = new time.Date(Date.UTC(2011, 0, 1));

assert.equal(d.getUTCFullYear(), 2011);
assert.equal(d.getUTCMonth(), 0);
assert.equal(d.getUTCDate(), 1);
console.log(d+'');

d.setTimezone("UTC");
console.log(d+'');
console.log("UTC Hours: " + d.getHours());
assert.equal(d.getUTCDay(), d.getDay());
assert.equal(d.getUTCDate(), d.getDate());
assert.equal(d.getUTCFullYear(), d.getFullYear());
assert.equal(d.getUTCHours(), d.getHours());
assert.equal(d.getUTCMilliseconds(), d.getMilliseconds());
assert.equal(d.getUTCMinutes(), d.getMinutes());
assert.equal(d.getUTCMonth(), d.getMonth());
assert.equal(d.getUTCSeconds(), d.getSeconds());
assert.equal(d.getTimezoneOffset(), 0);

d.setTimezone("America/Los_Angeles");
console.log(d+'');
console.log("LA Hours: " + d.getHours());
assert.equal(d.getHours(), 16);
assert.equal(d.getTimezoneOffset(), 480);

d.setTimezone("America/New_York");
console.log(d+'');
console.log("NY Hours: " + d.getHours());
assert.equal(d.getHours(), 19);

d.setTimezone("US/Arizona");
console.log(d+'');
console.log("AZ Hours: " + d.getHours());
assert.equal(d.getHours(), 17);
assert.equal(d.getUTCHours(), 0);
d.setUTCHours(23);
assert.equal(d.getHours(), 16);
d.setHours(15);
assert.equal(d.getHours(), 15);
<commit_msg>Another test case in 'test.js'<commit_after>var assert = require('assert');

var initialTz = process.env.TZ;

var time = require('./');

var d = new time.Date(Date.UTC(2011, 0, 1));

assert.equal(d.getUTCFullYear(), 2011);
assert.equal(d.getUTCMonth(), 0);
assert.equal(d.getUTCDate(), 1);
console.log(d+'');

d.setTimezone("UTC");
console.log(d+'');
console.log("UTC Hours: " + d.getHours());
assert.equal(d.getUTCDay(), d.getDay());
assert.equal(d.getUTCDate(), d.getDate());
assert.equal(d.getUTCFullYear(), d.getFullYear());
assert.equal(d.getUTCHours(), d.getHours());
assert.equal(d.getUTCMilliseconds(), d.getMilliseconds());
assert.equal(d.getUTCMinutes(), d.getMinutes());
assert.equal(d.getUTCMonth(), d.getMonth());
assert.equal(d.getUTCSeconds(), d.getSeconds());
assert.equal(d.getTimezoneOffset(), 0);

d.setTimezone("America/Los_Angeles");
console.log(d+'');
console.log("LA Hours: " + d.getHours());
assert.equal(d.getHours(), 16);
assert.equal(d.getTimezoneOffset(), 480);

d.setTimezone("America/New_York");
console.log(d+'');
console.log("NY Hours: " + d.getHours());
assert.equal(d.getHours(), 19);

d.setTimezone("US/Arizona");
console.log(d+'');
console.log("AZ Hours: " + d.getHours());
assert.equal(d.getHours(), 17);
assert.equal(d.getUTCHours(), 0);
d.setUTCHours(23);
assert.equal(d.getHours(), 16);
d.setHours(15);
assert.equal(d.getHours(), 15);

// The 'Date' extension functions are meant to "clean up" after themselves
// by setting the TZ variable back to it's original value after doing it's thing.
assert.equal(process.env.TZ, initialTz);
<|endoftext|>


<commit_before>/*!
 * stringify-changelog <https://github.com/jonschlinkert/stringify-changelog>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

/* deps:mocha */
var assert = require('assert');
var should = require('should');
var moment = require('moment');
var changlog = require('./');

describe('changlog', function () {
  it('should generate a changelog from a yaml file:', function () {
    changlog('fixtures/a.yml').should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should generate a changelog from an object:', function () {
    var data = { 'v0.1.0': { date: '2016-12-26', changes: [ 'Got stuck in another chimney.' ] } };
    changlog(data).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should generate a changelog from an array:', function () {
    var data = [
      {date: '2016-12-26', version: 'v0.1.0', changes: [ 'Got stuck in another chimney.' ]
    }];

    changlog(data).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should allow a custom date function:', function () {
    var data = [
      {date: '2016-12-26', version: 'v0.1.0', changes: [ 'Got stuck in another chimney.' ]
    }];

    var opts = {};
    opts.dateFn = function (date) {
    // console.log(arguments)
      return ' * ' + moment(date).format('YYYY-MM-DD');
    };

    changlog(data, opts).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should throw an error:', function () {
    (function () {
      changlog();
    }).should.throw('helper-changelog cannot find data or a file to read.');
  });
});
<commit_msg>clean up<commit_after>/*!
 * stringify-changelog <https://github.com/jonschlinkert/stringify-changelog>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

/* deps:mocha */
var assert = require('assert');
var should = require('should');
var moment = require('moment');
var changelog = require('./');

describe('changelog', function () {
  it('should generate a changelog from a yaml file:', function () {
    changelog('fixtures/a.yml').should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should generate a changelog from an object:', function () {
    var data = { 'v0.1.0': { date: '2016-12-26', changes: [ 'Got stuck in another chimney.' ] } };
    changelog(data).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should generate a changelog from an array:', function () {
    var data = [
      {date: '2016-12-26', version: 'v0.1.0', changes: [ 'Got stuck in another chimney.' ]
    }];

    changelog(data).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should allow a custom date function:', function () {
    var data = [
      {date: '2016-12-26', version: 'v0.1.0', changes: [ 'Got stuck in another chimney.' ]
    }];

    var opts = {};
    opts.dateFn = function (date) {
      return ' * ' + moment(date).format('YYYY-MM-DD');
    };

    changelog(data, opts).should.equal([
      '**DATE**       **VERSION**   **CHANGES**                  ',
      '* 2016-12-26   v0.1.0        Got stuck in another chimney.',
    ].join('\n'));
  });

  it('should throw an error:', function () {
    (function () {
      changelog();
    }).should.throw('helper-changelog cannot find data or a file to read.');
  });
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-17 11:36:28<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-20 11:56:30<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>