<commit_before>import { Server as MockSocketServer } from 'mock-socket';
import Palindrom from '../../src/palindrom';
import chai, { expect, assert } from 'chai';
import sinonChai  from "sinon-chai";
import fetchMock from 'fetch-mock';
import sinon from 'sinon';
import { PalindromConnectionError } from '../../src/palindrom-errors';
import { sleep, getTestURL } from '../utils';

chai.use(sinonChai);

describe('Sockets - if `useWebSocket` flag is provided', () => {
    let mockSocketServer;
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it('should try to open WebSocket connection', async () => {
        mockSocketServer = new MockSocketServer(getTestURL('testURL', false, true));

        fetchMock.mock(getTestURL('testURL'), {
            status: 200,
            headers: { location: getTestURL('testURL') },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL'),
            useWebSocket: true
        });
        /* socket should be undefined before HTTP delay */
        assert(typeof palindrom.network._ws === 'undefined');

        await sleep();
        /* socket should NOT be undefined after HTTP delay */
        assert(typeof palindrom.network._ws !== 'undefined');
    });

    it('should calculate WebSocket URL correctly', async () => {
        mockSocketServer = new MockSocketServer(getTestURL('testURL', false, true));

        fetchMock.mock(getTestURL('testURL'), {
            status: 200,
            headers: { location: getTestURL('testURL') },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('testURL', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, with root slash /', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL'), {
            status: 200,
            headers: { location: '/default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, relatively', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL'), {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, with root slash and extra pathname', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL/koko'), {
            status: 200,
            headers: { location: '/default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL/koko'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, without root slash and extra pathname', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('testURL/default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL/koko'), {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL/koko'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('testURL/default/this_is_a_nice_url', false, true)
        );
    });
    it('should use wss for https remote URL', async () => {
        mockSocketServer = new MockSocketServer(
            'wss://localhost/testURL/default/this_is_a_nice_url'
        );

        fetchMock.mock('https://localhost/testURL/koko', {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: 'https://localhost/testURL/koko',
            useWebSocket: true
        });

        await sleep();
        assert(
            palindrom.network._ws.url ===
                'wss://localhost/testURL/default/this_is_a_nice_url'
        );
    });

    it('should use same host, port, username, and password as provided in remoteUrl', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('test/this_is_a_nice_url', false, true)
        );

        const remoteUrl = getTestURL('testURL/koko');

        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: getTestURL('test/this_is_a_nice_url') },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });

        await sleep();
        assert(
            palindrom.network._ws.url ===
                getTestURL('test/this_is_a_nice_url', false, true)
        );
    });
});
describe('Before HTTP connection is established', () => {
    const remoteUrl = getTestURL('testURL/koko');
    let mockSocketServer;
    beforeEach(() => {
        mockSocketServer = new MockSocketServer(getTestURL('testURL/koko', false, true));
        fetchMock.mock(remoteUrl, {
            status: 200,
            body: '{"hello": "world"}'
        });
    });
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it("shouldn't start a socket connection", async () => {
        let everConnected = false;

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onStateReset: () =>
                assert(everConnected === false, `shouldn't connect before HTTP`),
            onSocketOpened: () => (everConnected = true)
        });

        await sleep();

        assert.equal(everConnected, true, 'should connect after HTTP');
    });

    it("shouldn't send any change a patch using WebSocket", async () => {
        const messages = [];

        mockSocketServer.on('message', patch => {
            let patchParsed = JSON.parse(patch);
            messages.push(...patchParsed);
        });

        new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onStateReset: obj => (obj.firstName = 'Omar')
        });

        // Wait for HTTP to finish
        await sleep(15);

        assert(messages.length === 0);
    });
});
describe('Sockets events', () => {
    const remoteUrl = getTestURL('testURL/koko');
    let mockSocketServer, mockSocket, socketMessageSpy;
    beforeEach(function(){
        mockSocket = null;
        socketMessageSpy = sinon.spy();
        mockSocketServer = new MockSocketServer(getTestURL('testURL/koko', false, true));
        mockSocketServer.on('connection', socket => {
            mockSocket = socket;
            socket.on('message', socketMessageSpy);
        });

        fetchMock.mock(remoteUrl, {
            status: 200,
            body: '{"hello": "world"}'
        });
    });
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it('`onSocketOpened` callback should be called', async () => {
        var spy = sinon.spy();
        new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onSocketOpened: spy
        });

        assert.equal(
            spy.callCount,
            0,
            'socket should not be opened before HTTP delay'
        );

        await sleep();

        assert.equal(
            spy.callCount,
            1,
            'socket should be opened before HTTP delay'
        );
    });

    it('Should call onConnectionError even when a non-JSON message is sent', async () => {
        var spy = sinon.spy();
        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onConnectionError: spy
        });

        /* no issues so far */
        assert(spy.notCalled);

        await sleep();

        mockSocket.send(`[{"op": "replace", "path": "/hello", "value": "bye"}]`);

        assert.equal(palindrom.obj.hello, 'bye');

        /* no issues so far */
        assert(spy.notCalled);

        mockSocket.send(`Some error message from the server`);

        /* Now! */
        assert(spy.calledOnce);

        const error = spy.lastCall.args[0];

        assert(error instanceof PalindromConnectionError);
        assert.equal(
            error.message,
            'Server error\n\tSome error message from the server'
        );
    });

    context('After connection is established', () => {
        it('should send new changes over WebSocket', async () => {
            var palindrom = new Palindrom({
                remoteUrl,
                useWebSocket: true
            });

            /* wait for HTTP */
            await sleep();

            palindrom.obj.firstName = 'Omar';

            await sleep();

            expect(socketMessageSpy).to.have.been.calledOnceWithExactly(JSON.stringify([{
                op: 'add',
                path: '/firstName',
                value: 'Omar'
            }]));
        });

        it('should call onConnectionError event if there is no response after `pingIntervalS`', async () => {
            const connectionErrorSpy = sinon.spy();
            var palindrom = new Palindrom({
                remoteUrl,
                onConnectionError: connectionErrorSpy,
                pingIntervalS: 0.5,
                useWebSocket: true
            });

            /* wait for HTTP & heartbeat */

            await sleep(1200);

            /* onConnectionError should be called once now */
            expect(connectionErrorSpy).to.have.been.calledOnce;
            const argument = connectionErrorSpy.getCall(0).args[0];
            expect(argument).to.be.an.instanceof(PalindromConnectionError);
            expect(argument).to.have.property('message').that.match(/timeout/i);
            expect(argument).to.have.property('side', "Client");
        });

        it('should send a patch over HTTP before ws.readyState is OPENED, and over WebSocket after ws.readyState is OPENED', async () => {
            let tempObj;
            new Palindrom({
                remoteUrl,
                useWebSocket: true,
                onStateReset: obj => {
                    fetchMock.restore();

                    // prepare a response for the patch
                    fetchMock.mock(remoteUrl, {
                        status: 200,
                        headers: { contentType: 'application/json-patch+json' },
                        body: `[]`
                    });

                    /* here, socket connection isn't established yet, let's issue a change */
                    obj.name = 'Mark';

                    assert.equal(
                        '[{"op":"add","path":"/name","value":"Mark"}]',
                        fetchMock.lastOptions().body
                    );

                    tempObj = obj;
                }
            });

            /* make sure there is no socket messages */
            expect(socketMessageSpy).not.to.be.called;

            /* now socket is connected, let's issue a change */
            await sleep();

            tempObj.firstName = 'Omar';

            await sleep();

            expect(socketMessageSpy).to.have.been.calledOnceWithExactly('[{"op":"add","path":"/firstName","value":"Omar"}]');

            /* now socket is connected, let's issue another change */
            await sleep();
            tempObj.firstName = 'Hanan';
            // mock-socket is asynchronous, so let's wait for it to propagate event
            await sleep(10);

            expect(socketMessageSpy).to.have.been.calledTwice;
            expect(socketMessageSpy).to.have.been.calledWithExactly('[{"op":"replace","path":"/firstName","value":"Hanan"}]');
        });
    });
});
<commit_msg>Make WebSockets tests DRYier<commit_after>import { Server as MockSocketServer } from 'mock-socket';
import Palindrom from '../../src/palindrom';
import chai, { expect, assert } from 'chai';
import sinonChai  from "sinon-chai";
import fetchMock from 'fetch-mock';
import sinon from 'sinon';
import { PalindromConnectionError } from '../../src/palindrom-errors';
import { sleep, getTestURL } from '../utils';

chai.use(sinonChai);

describe('Sockets - if `useWebSocket` flag is provided', () => {
    let mockSocketServer;
    const remoteUrl = getTestURL('testURL');
    const wsUrl = getTestURL('testURL', false, true);
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it('should try to open WebSocket connection', async () => {
        mockSocketServer = new MockSocketServer(wsUrl);
        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: remoteUrl },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });
        /* socket should be undefined before HTTP delay */
        assert(typeof palindrom.network._ws === 'undefined');

        await sleep();
        /* socket should NOT be undefined after HTTP delay */
        assert(typeof palindrom.network._ws !== 'undefined');
    });

    it('should calculate WebSocket URL correctly', async () => {
        mockSocketServer = new MockSocketServer(wsUrl);
        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: remoteUrl },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('testURL', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, with root slash /', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: '/default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, relatively', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, with root slash and extra pathname', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL/koko'), {
            status: 200,
            headers: { location: '/default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL/koko'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('default/this_is_a_nice_url', false, true)
        );
    });

    it('should resolve to correct WebSocket URL from location header, without root slash and extra pathname', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('testURL/default/this_is_a_nice_url', false, true)
        );

        fetchMock.mock(getTestURL('testURL/koko'), {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: getTestURL('testURL/koko'),
            useWebSocket: true
        });

        await sleep();
        assert.equal(
            palindrom.network._ws.url,
            getTestURL('testURL/default/this_is_a_nice_url', false, true)
        );
    });
    it('should use wss for https remote URL', async () => {
        mockSocketServer = new MockSocketServer(
            'wss://localhost/testURL/default/this_is_a_nice_url'
        );

        fetchMock.mock('https://localhost/testURL/koko', {
            status: 200,
            headers: { location: 'default/this_is_a_nice_url' },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl: 'https://localhost/testURL/koko',
            useWebSocket: true
        });

        await sleep();
        assert(
            palindrom.network._ws.url ===
                'wss://localhost/testURL/default/this_is_a_nice_url'
        );
    });

    it('should use same host, port, username, and password as provided in remoteUrl', async () => {
        mockSocketServer = new MockSocketServer(
            getTestURL('test/this_is_a_nice_url', false, true)
        );

        const remoteUrl = getTestURL('testURL/koko');

        fetchMock.mock(remoteUrl, {
            status: 200,
            headers: { location: getTestURL('test/this_is_a_nice_url') },
            body: '{"hello": "world"}'
        });

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true
        });

        await sleep();
        assert(
            palindrom.network._ws.url ===
                getTestURL('test/this_is_a_nice_url', false, true)
        );
    });
});
describe('Before HTTP connection is established', () => {
    const remoteUrl = getTestURL('testURL/koko');
    let mockSocketServer;
    beforeEach(() => {
        mockSocketServer = new MockSocketServer(getTestURL('testURL/koko', false, true));
        fetchMock.mock(remoteUrl, {
            status: 200,
            body: '{"hello": "world"}'
        });
    });
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it("shouldn't start a socket connection", async () => {
        let everConnected = false;

        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onStateReset: () =>
                assert(everConnected === false, `shouldn't connect before HTTP`),
            onSocketOpened: () => (everConnected = true)
        });

        await sleep();

        assert.equal(everConnected, true, 'should connect after HTTP');
    });

    it("shouldn't send any change a patch using WebSocket", async () => {
        const messages = [];

        mockSocketServer.on('message', patch => {
            let patchParsed = JSON.parse(patch);
            messages.push(...patchParsed);
        });

        new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onStateReset: obj => (obj.firstName = 'Omar')
        });

        // Wait for HTTP to finish
        await sleep(15);

        assert(messages.length === 0);
    });
});
describe('Sockets events', () => {
    const remoteUrl = getTestURL('testURL/koko');
    let mockSocketServer, mockSocket, socketMessageSpy;
    beforeEach(function(){
        mockSocket = null;
        socketMessageSpy = sinon.spy();
        mockSocketServer = new MockSocketServer(getTestURL('testURL/koko', false, true));
        mockSocketServer.on('connection', socket => {
            mockSocket = socket;
            socket.on('message', socketMessageSpy);
        });

        fetchMock.mock(remoteUrl, {
            status: 200,
            body: '{"hello": "world"}'
        });
    });
    afterEach(() => {
        fetchMock.restore();
        mockSocketServer.stop();
    });
    it('`onSocketOpened` callback should be called', async () => {
        var spy = sinon.spy();
        new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onSocketOpened: spy
        });

        assert.equal(
            spy.callCount,
            0,
            'socket should not be opened before HTTP delay'
        );

        await sleep();

        assert.equal(
            spy.callCount,
            1,
            'socket should be opened before HTTP delay'
        );
    });

    it('Should call onConnectionError even when a non-JSON message is sent', async () => {
        var spy = sinon.spy();
        var palindrom = new Palindrom({
            remoteUrl,
            useWebSocket: true,
            onConnectionError: spy
        });

        /* no issues so far */
        assert(spy.notCalled);

        await sleep();

        mockSocket.send(`[{"op": "replace", "path": "/hello", "value": "bye"}]`);

        assert.equal(palindrom.obj.hello, 'bye');

        /* no issues so far */
        assert(spy.notCalled);

        mockSocket.send(`Some error message from the server`);

        /* Now! */
        assert(spy.calledOnce);

        const error = spy.lastCall.args[0];

        assert(error instanceof PalindromConnectionError);
        assert.equal(
            error.message,
            'Server error\n\tSome error message from the server'
        );
    });

    context('After connection is established', () => {
        it('should send new changes over WebSocket', async () => {
            var palindrom = new Palindrom({
                remoteUrl,
                useWebSocket: true
            });

            /* wait for HTTP */
            await sleep();

            palindrom.obj.firstName = 'Omar';

            await sleep();

            expect(socketMessageSpy).to.have.been.calledOnceWithExactly(JSON.stringify([{
                op: 'add',
                path: '/firstName',
                value: 'Omar'
            }]));
        });

        it('should call onConnectionError event if there is no response after `pingIntervalS`', async () => {
            const connectionErrorSpy = sinon.spy();
            var palindrom = new Palindrom({
                remoteUrl,
                onConnectionError: connectionErrorSpy,
                pingIntervalS: 0.5,
                useWebSocket: true
            });

            /* wait for HTTP & heartbeat */

            await sleep(1200);

            /* onConnectionError should be called once now */
            expect(connectionErrorSpy).to.have.been.calledOnce;
            const argument = connectionErrorSpy.getCall(0).args[0];
            expect(argument).to.be.an.instanceof(PalindromConnectionError);
            expect(argument).to.have.property('message').that.match(/timeout/i);
            expect(argument).to.have.property('side', "Client");
        });

        it('should send a patch over HTTP before ws.readyState is OPENED, and over WebSocket after ws.readyState is OPENED', async () => {
            let tempObj;
            new Palindrom({
                remoteUrl,
                useWebSocket: true,
                onStateReset: obj => {
                    fetchMock.restore();

                    // prepare a response for the patch
                    fetchMock.mock(remoteUrl, {
                        status: 200,
                        headers: { contentType: 'application/json-patch+json' },
                        body: `[]`
                    });

                    /* here, socket connection isn't established yet, let's issue a change */
                    obj.name = 'Mark';

                    assert.equal(
                        '[{"op":"add","path":"/name","value":"Mark"}]',
                        fetchMock.lastOptions().body
                    );

                    tempObj = obj;
                }
            });

            /* make sure there is no socket messages */
            expect(socketMessageSpy).not.to.be.called;

            /* now socket is connected, let's issue a change */
            await sleep();

            tempObj.firstName = 'Omar';

            await sleep();

            expect(socketMessageSpy).to.have.been.calledOnceWithExactly('[{"op":"add","path":"/firstName","value":"Omar"}]');

            /* now socket is connected, let's issue another change */
            await sleep();
            tempObj.firstName = 'Hanan';
            // mock-socket is asynchronous, so let's wait for it to propagate event
            await sleep(10);

            expect(socketMessageSpy).to.have.been.calledTwice;
            expect(socketMessageSpy).to.have.been.calledWithExactly('[{"op":"replace","path":"/firstName","value":"Hanan"}]');
        });
    });
});
<|endoftext|>


<commit_before>import { expect } from 'chai'

import _ from 'lodash'
import VueI18nManager, { routeParser } from '../../../../dist/vue-i18n-manager'
import mutations from '../../../../src/store/module/mutations'
import storeState from '../../../../src/store/module/state'
import {
  REMOVE_LANGUAGE_PERSISTENCY,
  UPDATE_I18N_STATE,
  SET_LANGUAGE,
  SET_TRANSLATION
} from '../../../../src/store/module/events'

let state
let sandbox

const dutch = {
  code: 'nl-NL',
  urlPrefix: 'nl',
  translateTo: 'nl_NL'
}
const english = {
  name: 'English',
  code: 'en-GB',
  urlPrefix: 'en',
  translateTo: 'en_GB'
}
const italian = {
  name: 'Italiano',
  code: 'it-IT',
  urlPrefix: 'it',
  translateTo: 'it_IT'
}

describe('Mutations', () => {

  beforeEach(() => {
    sandbox = sinon.sandbox.create()
    sandbox.stub(window.console, 'warn');
    sandbox.stub(window.console, 'error');

    state = { ...storeState }
  })

  afterEach(() => {
    sandbox.restore()
  })

  /**
   * ======================================
   * REMOVE_LANGUAGE_PERSISTENCY tests
   * ======================================
   */
  describe('REMOVE_LANGUAGE_PERSISTENCY', () => {
    it ('should remove persistency of language in the browser', () => {
      mutations[REMOVE_LANGUAGE_PERSISTENCY](state)
      expect(state.persistent).to.be.false
    })
  })

  /**
   * ======================================
   * UPDATE_I18N_STATE tests
   * ======================================
   */
  describe('UPDATE_I18N_STATE', () => {
    it ('should accept parameters that are in the default state only', () => {
      const newState = {
        foo: 'bar',
        defaultCode: dutch.code,
        languages: [dutch]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.foo).to.be.undefined
      expect(state.defaultCode).to.equal(dutch.code)
    })

    it ('should log a message if an invalid parameters is passed', () => {
      const newState = {
        foo: 'bar'
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn)
    })

    it ('should log a message if the defaultCode doesn\'t match any language', () => {
      const newState = {
        defaultCode: dutch.code
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn);
    })

    it ('should have a defaultCode that matches at least one available languages', () => {
      const newState = {
        defaultCode: dutch.code,
        languages: [dutch, italian, english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.defaultCode).to.equal(dutch.code)

      expect(_.find(state.availableLanguages, { code: dutch.code })).to.deep.equal(dutch)
    })

    it ('should display only languages existing in the availableLanguages array', () => {
      const newState = {
        languageFilter: [italian.code, english.code],
        languages: [dutch, english, italian]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.availableLanguages.length).to.equal(2)
      expect(_.sortBy(state.availableLanguages, 'code')).to.deep.equal(_.sortBy([italian, english], 'code'))
    })

    it ('should log a message for depracated parameter usage', () => {
      const newState = {
        availableLanguages: [italian.code, english.code]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn)
    })
  })

  /**
   * ======================================
   * SET_TRANSLATION tests
   * ======================================
   */
  describe('SET_TRANSLATION', () => {
    it ('should return the translation based on the selected language', () => {
      const translations = {
        [dutch.translateTo]: { hello: 'hallo' },
        [italian.translateTo]: { hello: 'ciao' }
      }

      const newState = {
        defaultCode: dutch.code,
        languages: [ dutch, italian ]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, dutch.code)

      const { translateTo } = state.currentLanguage
      const translation = translations[translateTo]

      mutations[SET_TRANSLATION](state, translation)

      expect(state.translations).to.deep.equal(translation)
    })
  })

  /**
   * ======================================
   * SET_LANGUAGE tests
   * ======================================
   */
  describe('SET_LANGUAGE', () => {
    it ('should set the currentLanguage based on a given language code', () => {
      const newState = {
        defaultCode: english.code,
        languages: [english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)

      expect(state.currentLanguage.code).to.equal(english.code)
    })

    it ('should update the currentLanguage with a new one', () => {
      const newState = {
        languages: [dutch, english, italian]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)
      expect(state.currentLanguage.code).to.equal(english.code)

      mutations[SET_LANGUAGE](state, italian.code)
      expect(state.currentLanguage.code).to.equal(italian.code)
    })

    it ('should set the new language and retrieve its translation', () => {
      const translations = {
        foo: 'bar'
      }
      const newState = {
        languages: [dutch, english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)

      mutations[SET_TRANSLATION](state, translations)

      expect(state.currentLanguage.code).to.equal(english.code)
      expect(state.translations).to.deep.equal(translations)
    })
  })
})
<commit_msg>test(mutations): remove unused module imports<commit_after>import { expect } from 'chai'

import _ from 'lodash'
import mutations from '../../../../src/store/module/mutations'
import storeState from '../../../../src/store/module/state'
import {
  REMOVE_LANGUAGE_PERSISTENCY,
  UPDATE_I18N_STATE,
  SET_LANGUAGE,
  SET_TRANSLATION
} from '../../../../src/store/module/events'

let state
let sandbox

const dutch = {
  code: 'nl-NL',
  urlPrefix: 'nl',
  translateTo: 'nl_NL'
}
const english = {
  name: 'English',
  code: 'en-GB',
  urlPrefix: 'en',
  translateTo: 'en_GB'
}
const italian = {
  name: 'Italiano',
  code: 'it-IT',
  urlPrefix: 'it',
  translateTo: 'it_IT'
}

describe('Mutations', () => {

  beforeEach(() => {
    sandbox = sinon.sandbox.create()
    sandbox.stub(window.console, 'warn');
    sandbox.stub(window.console, 'error');

    state = { ...storeState }
  })

  afterEach(() => {
    sandbox.restore()
  })

  /**
   * ======================================
   * REMOVE_LANGUAGE_PERSISTENCY tests
   * ======================================
   */
  describe('REMOVE_LANGUAGE_PERSISTENCY', () => {
    it ('should remove persistency of language in the browser', () => {
      mutations[REMOVE_LANGUAGE_PERSISTENCY](state)
      expect(state.persistent).to.be.false
    })
  })

  /**
   * ======================================
   * UPDATE_I18N_STATE tests
   * ======================================
   */
  describe('UPDATE_I18N_STATE', () => {
    it ('should accept parameters that are in the default state only', () => {
      const newState = {
        foo: 'bar',
        defaultCode: dutch.code,
        languages: [dutch]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.foo).to.be.undefined
      expect(state.defaultCode).to.equal(dutch.code)
    })

    it ('should log a message if an invalid parameters is passed', () => {
      const newState = {
        foo: 'bar'
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn)
    })

    it ('should log a message if the defaultCode doesn\'t match any language', () => {
      const newState = {
        defaultCode: dutch.code
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn);
    })

    it ('should have a defaultCode that matches at least one available languages', () => {
      const newState = {
        defaultCode: dutch.code,
        languages: [dutch, italian, english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.defaultCode).to.equal(dutch.code)

      expect(_.find(state.availableLanguages, { code: dutch.code })).to.deep.equal(dutch)
    })

    it ('should display only languages existing in the availableLanguages array', () => {
      const newState = {
        languageFilter: [italian.code, english.code],
        languages: [dutch, english, italian]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      expect(state.availableLanguages.length).to.equal(2)
      expect(_.sortBy(state.availableLanguages, 'code')).to.deep.equal(_.sortBy([italian, english], 'code'))
    })

    it ('should log a message for depracated parameter usage', () => {
      const newState = {
        availableLanguages: [italian.code, english.code]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      sinon.assert.calledOnce(console.warn)
    })
  })

  /**
   * ======================================
   * SET_TRANSLATION tests
   * ======================================
   */
  describe('SET_TRANSLATION', () => {
    it ('should return the translation based on the selected language', () => {
      const translations = {
        [dutch.translateTo]: { hello: 'hallo' },
        [italian.translateTo]: { hello: 'ciao' }
      }

      const newState = {
        defaultCode: dutch.code,
        languages: [ dutch, italian ]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, dutch.code)

      const { translateTo } = state.currentLanguage
      const translation = translations[translateTo]

      mutations[SET_TRANSLATION](state, translation)

      expect(state.translations).to.deep.equal(translation)
    })
  })

  /**
   * ======================================
   * SET_LANGUAGE tests
   * ======================================
   */
  describe('SET_LANGUAGE', () => {
    it ('should set the currentLanguage based on a given language code', () => {
      const newState = {
        defaultCode: english.code,
        languages: [english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)

      expect(state.currentLanguage.code).to.equal(english.code)
    })

    it ('should update the currentLanguage with a new one', () => {
      const newState = {
        languages: [dutch, english, italian]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)
      expect(state.currentLanguage.code).to.equal(english.code)

      mutations[SET_LANGUAGE](state, italian.code)
      expect(state.currentLanguage.code).to.equal(italian.code)
    })

    it ('should set the new language and retrieve its translation', () => {
      const translations = {
        foo: 'bar'
      }
      const newState = {
        languages: [dutch, english]
      }

      mutations[UPDATE_I18N_STATE](state, newState)

      mutations[SET_LANGUAGE](state, english.code)

      mutations[SET_TRANSLATION](state, translations)

      expect(state.currentLanguage.code).to.equal(english.code)
      expect(state.translations).to.deep.equal(translations)
    })
  })
})
<|endoftext|>


<commit_before>import { interpreter } from '../src';

const DECISION_TREE_1 = require('./data/interpreter-test-suite/decide/trees/v1/enum.json');
const DECISION_TREE_2 = require('./data/interpreter-test-suite/decide/trees/v1/continuous.json');
const DECISION_TREE_3 = require('./data/interpreter-test-suite/decide/trees/v1/oneColor.json');

const INVALID_DECISION_TREE_1 = require('./data/interpreter-test-suite/decide/trees/v1/emptyArray.json');

describe('interpreter.getDecisionRulesProperties(<tree>)', function() {
  it('can list the properties used in a tree\'s decision rules (enum output)', function() {
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_1)).to.be.deep.equal([
      {
        'is_generated': true,
        'property': 'timeOfDay',
        'type': 'time_of_day'
      }
    ]);
  });

  it('can list the properties used in a tree\'s decision rules (continuous output)', function() {
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_2)).to.be.deep.equal([
      {
        'is_generated': true,
        'property': 'time',
        'type': 'time_of_day'
      },
      {
        'is_generated': true,
        'property': 'day',
        'type': 'day_of_week'
      },
      {
        'property': 'tz',
        'type': 'timezone'
      }
    ]);
  });

  it('can list the properties used in a tree\'s decision rules (single leaf)', function() {
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_3)).to.be.deep.equal([]);
  });

  it('works properly on invalid trees', function() {
    expect(() => interpreter.getDecisionRulesProperties(INVALID_DECISION_TREE_1)).to.throw;
  });
});
<commit_msg>add v2 tests in the getDecisionRulesProperties function<commit_after>import { interpreter } from '../src';

const DECISION_TREE_1_V1 = require('./data/interpreter-test-suite/decide/trees/v1/enum.json');
const DECISION_TREE_2_V1 = require('./data/interpreter-test-suite/decide/trees/v1/continuous.json');
const DECISION_TREE_3_V1 = require('./data/interpreter-test-suite/decide/trees/v1/oneColor.json');

const DECISION_TREE_1_V2 = require('./data/interpreter-test-suite/decide/trees/v2/enum.json');
const DECISION_TREE_2_V2 = require('./data/interpreter-test-suite/decide/trees/v2/continuous.json');
const DECISION_TREE_3_V2 = require('./data/interpreter-test-suite/decide/trees/v2/oneColor.json');
const DECISION_TREE_4_V2 = require('./data/interpreter-test-suite/decide/trees/v2/optional_branch_enum.json');

const INVALID_DECISION_TREE_1 = require('./data/interpreter-test-suite/decide/trees/v1/emptyArray.json');

describe('interpreter.getDecisionRulesProperties(<tree>)', function() {
  it('can list the properties used in a tree\'s decision rules (enum output)', function() {
    const expected_output = [
      {
        'is_generated': true,
        'property': 'timeOfDay',
        'type': 'time_of_day'
      }
    ];
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_1_V1)).to.be.deep.equal(expected_output);
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_1_V2)).to.be.deep.equal(expected_output);
  });

  it('can list the properties used in a tree\'s decision rules (continuous output)', function() {
    const expected_output = [
      {
        'is_generated': true,
        'property': 'time',
        'type': 'time_of_day'
      },
      {
        'is_generated': true,
        'property': 'day',
        'type': 'day_of_week'
      },
      {
        'property': 'tz',
        'type': 'timezone'
      }
    ];
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_2_V1)).to.be.deep.equal(expected_output);
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_2_V2)).to.be.deep.equal(expected_output);
  });

  it('can list the properties used in a tree\'s decision rules (optional property)', function() {
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_4_V2)).to.be.deep.equal([
      {
        'property': 'enum4',
        'type': 'enum'
      },
      {
        'property': 'continuous3',
        'type': 'continuous'
      },
      {
        'property': 'continuous5',
        'type': 'continuous'
      },
      {
        'property': 'continuous4',
        'type': 'continuous'
      },
      {
        'property': 'enum1',
        'type': 'enum'
      },
      {
        'property': 'enum5',
        'type': 'enum'
      },
      {
        'is_optional': true,
        'property': 'enum2',
        'type': 'enum'
      },
      {
        'property': 'enum3',
        'type': 'enum'
      },
      {
        'property': 'enum6',
        'type': 'enum'
      },
      {
        'property': 'continuous2',
        'type': 'continuous'
      },
      {
        'property': 'continuous6',
        'type': 'continuous'
      },
      {
        'property': 'enum7',
        'type': 'enum'
      },
      {
        'property': 'continuous1',
        'type': 'continuous'
      }
    ]);
  });

  it('can list the properties used in a tree\'s decision rules (single leaf)', function() {
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_3_V1)).to.be.deep.equal([]);
    expect(interpreter.getDecisionRulesProperties(DECISION_TREE_3_V2)).to.be.deep.equal([]);
  });

  it('works properly on invalid trees', function() {
    expect(() => interpreter.getDecisionRulesProperties(INVALID_DECISION_TREE_1)).to.throw;
  });
});
<|endoftext|>


<commit_before>require('should');

const transpile = require('../../build/transpile');
const Identifier = require('../../build/classes/Identifier');
const AssignableList = require('../../build/classes/AssignableList');

describe('assignableList', () => {
  it('should transpile lists of a single identifier correctly', () => {
    transpile(AssignableList([Identifier('x')])).should.be.exactly('[x]');
  });

  it('should transpile lists of multiple identifiers correctly', () => {
    transpile(AssignableList([Identifier('x'), Identifier('y')])).should.be.exactly('[x, y]');
    transpile(
      AssignableList([Identifier('x'), Identifier('y'), Identifier('z')])
    ).should.be.exactly('[x, y, z]');
  });
});
<commit_msg>add prefix to test description<commit_after>require('should');

const transpile = require('../../build/transpile');
const Identifier = require('../../build/classes/Identifier');
const AssignableList = require('../../build/classes/AssignableList');

describe('transpilers/assignableList', () => {
  it('should transpile lists of a single identifier correctly', () => {
    transpile(AssignableList([Identifier('x')])).should.be.exactly('[x]');
  });

  it('should transpile lists of multiple identifiers correctly', () => {
    transpile(AssignableList([Identifier('x'), Identifier('y')])).should.be.exactly('[x, y]');
    transpile(
      AssignableList([Identifier('x'), Identifier('y'), Identifier('z')])
    ).should.be.exactly('[x, y, z]');
  });
});
<|endoftext|>


<commit_before>define(
  'ephox.alloy.toolbar.ToolbarSpecs',

  [
    'ephox.boulder.api.FieldPresence',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.compass.Arr',
    'ephox.peanut.Fun'
  ],

  function (FieldPresence, FieldSchema, ValueSchema, Arr, Fun) {
    var itemSchema = ValueSchema.choose(
      'type',
      {
        button: [
          FieldSchema.strict('buttonType'),
          FieldSchema.strict('action'),
          FieldSchema.state('builder', function () {
            return function (info) {
              return {
                uiType: 'button',
                buttonType: info.buttonType(),
                dom: {
                  classes: [ 'toolbar-group-item' ],
                  styles: {
                    display: 'flex'
                  }
                },
                tabstopping: undefined,
                focusing: true,
                action: info.action()
              };
            };
          })
        ]
      }
    );

    // TODO: Standardise all of these.
    var groupSchema = ValueSchema.objOf([
      FieldSchema.option('label'),
      FieldSchema.field(
        'components',
        'components',
        FieldPresence.strict(),
        ValueSchema.arrOf(itemSchema)
      )
    ]);

    var toolbarSchema = ValueSchema.objOf([
      FieldSchema.option('label'),
      FieldSchema.field(
        'groups',
        'groups',
        FieldPresence.strict(),
        ValueSchema.arrOf(
          groupSchema
        )
      )
    ]);

    var buildItem = function (compInfo) {
      return compInfo.builder()(compInfo);
    };

    var buildGroup = function (group) {
      return {
        uiType: 'custom',
        dom: {
          tag: 'div',
          styles: {
            display: 'flex'
          }
        },
        keying: {
          mode: 'flow',
          selector: '.toolbar-group-item'
        },
        tabstopping: true,
        // GOTCHAs. False won't do anything. Fix this so we don't have to pass "undefined"
        focusing: undefined,
        components: Arr.map(group.components(), buildItem)
      };
    };

    return {
      buildGroup: buildGroup,
      buildItem: buildItem,
      groupSchema: Fun.constant(groupSchema),
      toolbarSchema: Fun.constant(toolbarSchema)
    };
  }
);<commit_msg>VAN-44-wheel: toolbar items<commit_after>define(
  'ephox.alloy.toolbar.ToolbarSpecs',

  [
    'ephox.boulder.api.FieldPresence',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.compass.Arr',
    'ephox.peanut.Fun'
  ],

  function (FieldPresence, FieldSchema, ValueSchema, Arr, Fun) {
    var itemSchema = ValueSchema.choose(
      'type',
      {
        button: [
          FieldSchema.strict('buttonType'),
          FieldSchema.strict('action'),
          FieldSchema.state('builder', function () {
            return function (info) {
              return {
                uiType: 'button',
                buttonType: info.buttonType(),
                // dom: {
                //   classes: [ 'toolbar-group-item' ],
                //   styles: {
                //     display: 'flex'
                //   }
                // },
                tabstopping: undefined,
                focusing: true,
                action: info.action()
              };
            };
          })
        ]
      }
    );

    // TODO: Standardise all of these.
    var groupSchema = ValueSchema.objOf([
      FieldSchema.option('label'),
      FieldSchema.field(
        'components',
        'components',
        FieldPresence.strict(),
        ValueSchema.arrOf(itemSchema)
      )
    ]);

    var toolbarSchema = ValueSchema.objOf([
      FieldSchema.option('label'),
      FieldSchema.field(
        'groups',
        'groups',
        FieldPresence.strict(),
        ValueSchema.arrOf(
          groupSchema
        )
      )
    ]);

    var buildItem = function (compInfo) {
      return compInfo.builder()(compInfo);
    };

    var buildGroup = function (group) {
      return {
        uiType: 'custom',
        dom: {
          tag: 'div',
          styles: {
            display: 'flex'
          }
        },
        keying: {
          mode: 'flow',
          selector: '.toolbar-group-item'
        },
        tabstopping: true,
        // GOTCHAs. False won't do anything. Fix this so we don't have to pass "undefined"
        focusing: undefined,
        components: Arr.map(group.components(), buildItem)
      };
    };

    return {
      buildGroup: buildGroup,
      buildItem: buildItem,
      groupSchema: Fun.constant(groupSchema),
      toolbarSchema: Fun.constant(toolbarSchema)
    };
  }
);<|endoftext|>


<commit_before>
import { expect } from 'chai';

//  const RG = require('../../../client/src/battles');
const {CaveGenerator} = require('../../../client/src/cave-generator');

describe('CaveGenerator', () => {
    it('can create Cave-like levels', () => {
        const caveGen = new CaveGenerator();
        const level = caveGen.create(80, 50, {dungeonType: 'Cave'});
        expect(level).to.exist;
    });

    it('can generate simple cave levels', () => {
        const caveGen = new CaveGenerator();
        const conf = {dungeonType: 'Cave', isCollapsed: false};
        const level = caveGen.create(100, 50, conf);
        expect(level).to.exist;

        const cells = level.getMap().getCells(c => (
            (/floor/).test(c.getBaseElem().getType())
        ));
        expect(cells.length).to.be.at.least(50);
    });

    it('can create Lair-like levels', () => {
        for (let i = 0; i < 1; i++) {
            const caveGen = new CaveGenerator();
            const level = caveGen.create(100, 50,
                {dungeonType: 'Lair', isCollapsed: true});
            expect(level).to.exist;

            const extras = level.getExtras();
            expect(extras).to.have.property('startPoint');
            expect(extras).to.have.property('endPoint');
        }
    });

    it('can create Cavern-like levels', () => {
        for (let i = 0; i < 1; i++) {
            const caveGen = new CaveGenerator();
            const level = caveGen.create(150, 80,
                {dungeonType: 'Cavern', isCollapsed: false});
            expect(level).to.exist;

            const extras = level.getExtras();
            expect(extras).to.have.property('startPoint');
            expect(extras).to.have.property('endPoint');
        }
    });

    it('it can generate collapsed cave level', () => {
        const caveGen = new CaveGenerator();
        const conf = {
            dungeonType: 'Lair', isCollapsed: true
        };
        const level = caveGen.create(100, 50, conf);
        expect(level).to.exist;
        // level.debugPrintInASCII();
    });
});
<commit_msg>Added loop to generate 10 Caves and check to see that start/endpoint don't overlap.<commit_after>
import { expect } from 'chai';

//  const RG = require('../../../client/src/battles');
const {CaveGenerator} = require('../../../client/src/cave-generator');

describe('CaveGenerator', () => {
    it('can create Cave-like levels', () => {
        const caveGen = new CaveGenerator();
        const level = caveGen.create(80, 50, {dungeonType: 'Cave'});
        expect(level).to.exist;
    });

    it('can generate simple cave levels', () => {
        for (let i = 0; i < 10; i++) {
            const caveGen = new CaveGenerator();
            const conf = {dungeonType: 'Cave', isCollapsed: false,
                maxDanger: 5};
            const level = caveGen.create(100, 50, conf);
            expect(level).to.exist;

            const extras = level.getExtras();
            const {startPoint, endPoint} = extras;
            expect(startPoint).to.be.an.array;
            expect(endPoint).to.be.an.array;
            expect(startPoint).not.to.deep.equal(endPoint);
        }
    });

    it('can create Lair-like levels', () => {
        for (let i = 0; i < 1; i++) {
            const caveGen = new CaveGenerator();
            const level = caveGen.create(100, 50,
                {dungeonType: 'Lair', isCollapsed: true});
            expect(level).to.exist;

            const extras = level.getExtras();
            expect(extras).to.have.property('startPoint');
            expect(extras).to.have.property('endPoint');
        }
    });

    it('can create Cavern-like levels', () => {
        for (let i = 0; i < 1; i++) {
            const caveGen = new CaveGenerator();
            const level = caveGen.create(150, 80,
                {dungeonType: 'Cavern', isCollapsed: false, maxDanger: 2});
            expect(level).to.exist;

            const extras = level.getExtras();
            expect(extras).to.have.property('startPoint');
            expect(extras).to.have.property('endPoint');
        }
    });

    it('it can generate collapsed cave level', () => {
        const caveGen = new CaveGenerator();
        const conf = {
            dungeonType: 'Lair', isCollapsed: true, maxDanger: 3
        };
        const level = caveGen.create(100, 50, conf);
        expect(level).to.exist;
        // level.debugPrintInASCII();
    });
});
<|endoftext|>


<commit_before>import React from 'react'
import chai, { expect } from 'chai'
import dirtyChai from 'dirty-chai'
import { shallow } from 'enzyme'
import { FeatureToggle, setFeatureConfig } from '../../src/index'

chai.use(dirtyChai)

const { describe, it } = global

describe('<FeatureToggle/>', () => {
  it('renders children if toggle is enabled', () => {
    setFeatureConfig({ testFeature: true })

    const wrapper = shallow(
      <FeatureToggle name="testFeature">

Test

      </FeatureToggle>)

    expect(wrapper.find('div')).to.have.length(1)
  })

  it('ignores children if toggle is disabled', () => {
    setFeatureConfig({ testFeature: false })

    const wrapper = shallow(
      <FeatureToggle name="testFeature">

Test

      </FeatureToggle>)

    expect(wrapper.find('div')).to.have.length(0)
  })

  it('adds routes if toggle is enabled')
  it('ignores routes if toggle is disabled')
})
<commit_msg>add specs for feature toggle<commit_after>import React from 'react'
import chai, { expect } from 'chai'
import dirtyChai from 'dirty-chai'
import { shallow } from 'enzyme'
import { Route, IndexRoute, match } from 'react-router'

import { FeatureToggle, setFeatureConfig } from '../../src/index'

chai.use(dirtyChai)

const { describe, it } = global

describe('<FeatureToggle/>', () => {
  it('renders children if toggle is enabled', () => {
    setFeatureConfig({ testFeature: true })

    const wrapper = shallow(
      <FeatureToggle name="testFeature">

Test

      </FeatureToggle>)

    expect(wrapper.find('div')).to.have.length(1)
  })

  it('ignores children if toggle is disabled', () => {
    setFeatureConfig({ testFeature: false })

    const wrapper = shallow(
      <FeatureToggle name="testFeature">

Test

      </FeatureToggle>)

    expect(wrapper.find('div')).to.have.length(0)
  })

  it('adds routes if toggle is enabled', (done) => {
    setFeatureConfig({ testFeature: true })

    const routes = (
      <Route name="home" path="/">
        <IndexRoute />
        <FeatureToggle name="testFeature">
          <Route name="route1" path="route1">
            <IndexRoute />
            <Route name="route1.sub" path=":routeId">
              <IndexRoute />
            </Route>
          </Route>
        </FeatureToggle>
        <Route name="route2" path="" />
      </Route>)

    match({ routes, location: '/route1/5' }, (err, redirect, props) => {
      expect(props).to.not.be.undefined()
      done()
    })
  })

  it('ignores routes if toggle is disabled', (done) => {
    setFeatureConfig({ testFeature: false })

    const routes = (
      <Route name="home" path="/">
        <IndexRoute />
        <FeatureToggle name="testFeature">
          <Route name="route1" path="route1">
            <IndexRoute />
            <Route name="route1.sub" path=":routeId">
              <IndexRoute />
            </Route>
          </Route>
        </FeatureToggle>
        <Route name="route2" path="" />
      </Route>)

    match({ routes, location: '/route1/5' }, (err, redirect, props) => {
      expect(props).to.be.undefined()
      done()
    })
  })
})
<|endoftext|>


<commit_before>import { shallow } from 'enzyme';
import * as React from 'react';

import Link from 'amo/components/Link';
import Button from 'amo/components/Button';
import { createFakeEvent } from 'tests/unit/helpers';

describe(__filename, () => {
  function render(props = {}) {
    return shallow(<Button {...props} />);
  }

  it('renders a button', () => {
    const onClick = sinon.spy();
    const button = render({
      children: 'My button!',
      className: 'Foo',
      onClick,
    });

    expect(button.type()).toEqual('button');
    expect(button).toHaveClassName('Button');
    expect(button).toHaveClassName('Foo');
    expect(button).toHaveProp('onClick', onClick);
    expect(button.children()).toIncludeText('My button!');
  });

  it('renders an in-app link with a to prop', () => {
    const href = '/profile/';
    const button = render({
      children: 'Link text!',
      className: 'Bar',
      to: href,
    });

    expect(button.type()).toEqual(Link);
    expect(button).toHaveClassName('Button');
    expect(button).toHaveClassName('Bar');
    expect(button).toHaveProp('to', href);
    expect(button.children()).toIncludeText('Link text!');
  });

  it('renders a link with a href', () => {
    const href = 'https://addons.mozilla.org';

    const button = render({
      children: 'Link text!',
      className: 'Bar',
      href,
    });

    expect(button.type()).toEqual(Link);
    expect(button).toHaveClassName('Button');
    expect(button).toHaveClassName('Bar');
    expect(button).toHaveProp('href', href);
    expect(button.children()).toIncludeText('Link text!');
    expect(button.find(Link)).toHaveProp('prependClientApp', false);
    expect(button.find(Link)).toHaveProp('prependLang', false);
  });

  it('can disable an anchor with a `href` prop', () => {
    const onClick = sinon.stub();
    const button = render({
      buttonType: 'action',
      children: 'Link text!',
      disabled: true,
      href: 'https://addons.mozilla.org',
      onClick,
    });

    const event = createFakeEvent();
    button.simulate('click', event);

    sinon.assert.notCalled(onClick);
    sinon.assert.called(event.preventDefault);
  });

  it('can disable an anchor with a `to` prop', () => {
    const onClick = sinon.stub();
    const button = render({
      buttonType: 'action',
      children: 'Link text!',
      disabled: true,
      onClick,
      to: '/addon/foo/',
    });

    const event = createFakeEvent();
    button.simulate('click', event);

    sinon.assert.notCalled(onClick);
    sinon.assert.called(event.preventDefault);
  });

  it('sets a disabled link class when disabled', () => {
    const button = render({
      buttonType: 'action',
      children: 'Link text!',
      className: 'CustomClass',
      disabled: true,
      href: 'https://addons.mozilla.org',
    });

    expect(button).toHaveClassName('Button--disabled');
    expect(button).toHaveClassName('CustomClass');
  });

  it('throws when an invalid type is supplied', () => {
    expect(() => {
      render({
        buttonType: 'not-a-real-type',
        children: 'Link text!',
        href: 'https://addons.mozilla.org',
      });
    }).toThrow(
      /buttonType="not-a-real-type" supplied but that is not a valid button/,
    );
  });

  it('renders a read only button', () => {
    const className = 'som-css-class';
    const button = render({ noLink: true, className });

    expect(button.type()).toEqual('span');
    expect(button).toHaveClassName(className);
  });

  it('renders a read only button with a title', () => {
    const title = 'some title';
    const button = render({ noLink: true, title });

    expect(button.type()).toEqual('span');
    expect(button).toHaveProp('title', title);
  });

  it('renders a link with a title', () => {
    const title = 'some title';
    const button = render({ href: '/', title });

    expect(button.type()).toEqual(Link);
    expect(button).toHaveProp('title', title);
  });

  it('renders a submit button with a title', () => {
    const title = 'some title';
    const button = render({ title });

    expect(button.type()).toEqual('button');
    expect(button).toHaveProp('title', title);
    expect(button).toHaveProp('type', 'submit');
  });

  it('renders a button with a different html type', () => {
    const htmlType = 'button';
    const button = render({ htmlType });

    expect(button).toHaveProp('type', htmlType);
  });
});
<commit_msg>Migrate TestButton.js (#11369)<commit_after>import * as React from 'react';
import { createEvent, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import Button from 'amo/components/Button';
import { render as defaultRender, screen } from 'tests/unit/helpers';

describe(__filename, () => {
  function render(props = {}) {
    return defaultRender(<Button {...props} />);
  }

  it('renders a button', () => {
    const onClick = jest.fn();
    render({
      children: 'My button!',
      className: 'Foo',
      onClick,
    });

    const button = screen.getByRole('button');
    expect(button).toHaveTextContent('My button!');
    expect(button).toHaveClass('Foo');

    userEvent.click(button);
    expect(onClick).toHaveBeenCalled();
  });

  it('renders an in-app link with a to prop', () => {
    const href = '/profile/';
    render({
      children: 'Link text!',
      className: 'Bar',
      to: href,
    });

    const button = screen.getByRole('link');
    expect(button).toHaveTextContent('Link text!');
    expect(button).toHaveClass('Bar');
    expect(button).toHaveAttribute('href', `/en-US/android${href}`);
  });

  it('renders a link with a href', () => {
    const href = 'https://addons.mozilla.org';

    render({
      children: 'Link text!',
      className: 'Bar',
      href,
    });

    const button = screen.getByRole('link');
    expect(button).toHaveTextContent('Link text!');
    expect(button).toHaveClass('Bar');
    expect(button).toHaveAttribute('href', href);
  });

  it('can disable an anchor with a `href` prop', () => {
    const onClick = jest.fn();
    render({
      buttonType: 'action',
      children: 'Link text!',
      disabled: true,
      href: 'https://addons.mozilla.org',
      onClick,
    });

    const button = screen.getByRole('link');
    const clickEvent = createEvent.click(button);
    const preventDefaultWatcher = jest.spyOn(clickEvent, 'preventDefault');

    fireEvent(button, clickEvent);
    expect(onClick).not.toHaveBeenCalled();
    expect(preventDefaultWatcher).toHaveBeenCalled();
  });

  it('can disable an anchor with a `to` prop', () => {
    const onClick = jest.fn();
    render({
      buttonType: 'action',
      children: 'Link text!',
      disabled: true,
      onClick,
      to: '/addon/foo/',
    });

    const button = screen.getByRole('link');
    const clickEvent = createEvent.click(button);
    const preventDefaultWatcher = jest.spyOn(clickEvent, 'preventDefault');

    fireEvent(button, clickEvent);
    expect(onClick).not.toHaveBeenCalled();
    expect(preventDefaultWatcher).toHaveBeenCalled();
  });

  it('sets a disabled link class when disabled', () => {
    render({
      buttonType: 'action',
      children: 'Link text!',
      className: 'CustomClass',
      disabled: true,
      href: 'https://addons.mozilla.org',
    });

    const button = screen.getByRole('link');
    expect(button).toHaveClass('Button--disabled');
    expect(button).toHaveClass('CustomClass');
  });

  it('throws when an invalid type is supplied', () => {
    expect(() => {
      render({
        buttonType: 'not-a-real-type',
        children: 'Link text!',
        href: 'https://addons.mozilla.org',
      });
    }).toThrow(
      /buttonType="not-a-real-type" supplied but that is not a valid button/,
    );
  });

  it('renders a read only button', () => {
    const className = 'some-css-class';
    render({ noLink: true, className });

    expect(screen.getByTagName('span')).toHaveClass(className);
  });

  it('renders a read only button with a title', () => {
    const title = 'some title';
    render({ noLink: true, title });

    expect(screen.getByTitle(title)).toBeInTheDocument();
  });

  it('renders a link with a title', () => {
    const title = 'some title';
    render({ href: '/', title });

    expect(screen.getByRole('link', { title })).toBeInTheDocument();
  });

  it('renders a submit button with a title', () => {
    const title = 'some title';
    render({ title });

    expect(screen.getByRole('button', { title })).toHaveAttribute(
      'type',
      'submit',
    );
  });

  it('renders a button with a different html type', () => {
    const htmlType = 'button';
    render({ htmlType });

    expect(screen.getByRole('button')).toHaveAttribute('type', htmlType);
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import {
  renderIntoDocument,
  findRenderedComponentWithType,
} from 'react-addons-test-utils';
import { findDOMNode } from 'react-dom';
import { Provider } from 'react-redux';

import Footer from 'amo/components/Footer';
import I18nProvider from 'core/i18n/Provider';
import { dispatchSignInActions } from 'tests/unit/amo/helpers';
import { fakeI18n } from 'tests/unit/helpers';

describe('Footer', () => {
  function renderFooter({ ...props }) {
    const { store } = dispatchSignInActions();

    return findDOMNode(findRenderedComponentWithType(renderIntoDocument(
      <Provider store={store}>
        <I18nProvider i18n={fakeI18n()}>
          <Footer {...props} />
        </I18nProvider>
      </Provider>
    ), Footer));
  }

  it('renders a footer', () => {
    const root = renderFooter();

    // None of these links are localised because an unsupported locale will
    // cause a 404 error.
    // See:
    // github.com/mozilla/addons-frontend/pull/2524#pullrequestreview-42911624
    expect(root.querySelector('.Footer-privacy-link').textContent).toEqual('Privacy');
    expect(root.querySelector('.Footer-privacy-link').href).toEqual('https://www.mozilla.org/privacy/websites/');
    expect(root.querySelector('.Footer-legal-link').textContent).toEqual('Legal');
    expect(root.querySelector('.Footer-legal-link').href).toEqual('https://www.mozilla.org/about/legal/');
    expect(root.querySelector('.Footer-cookies-link').textContent).toEqual('Cookies');
    expect(root.querySelector('.Footer-cookies-link').href).toEqual('https://www.mozilla.org/privacy/websites/#cookies');
    expect(root.querySelector('.Footer-trademark-abuse-link').textContent).toEqual('Report Trademark Abuse');
    expect(root.querySelector('.Footer-trademark-abuse-link').href).toEqual('https://www.mozilla.org/about/legal/fraud-report/');

    // This link isn't localized because MDN will 404 on some
    // locales and not others.
    // See also https://bugzilla.mozilla.org/show_bug.cgi?id=1283422
    expect(root.querySelector('.Footer-bug-report-link').href).toEqual('https://developer.mozilla.org/Add-ons/AMO/Policy/Contact');
  });
});
<commit_msg>rewrote footer tests using Enzyme (#3361)<commit_after>import React from 'react';

import Footer, { FooterBase } from 'amo/components/Footer';
import { fakeI18n, shallowUntilTarget } from 'tests/unit/helpers';

describe('Footer', () => {
  function renderFooter({ ...props }) {
    return shallowUntilTarget(
      <Footer i18n={fakeI18n()} {...props} />,
      FooterBase
    );
  }

  it('renders a footer', () => {
    const root = renderFooter();

    // None of these links are localised because an unsupported locale will
    // cause a 404 error.
    // See:
    // github.com/mozilla/addons-frontend/pull/2524#pullrequestreview-42911624
    expect(root.find('.Footer-privacy-link')).toHaveText('Privacy');
    expect(root.find('.Footer-privacy-link')).toHaveProp('href', 'https://www.mozilla.org/privacy/websites/');
    expect(root.find('.Footer-legal-link')).toHaveText('Legal');
    expect(root.find('.Footer-legal-link')).toHaveProp('href', 'https://www.mozilla.org/about/legal/');
    expect(root.find('.Footer-cookies-link')).toHaveText('Cookies');
    expect(root.find('.Footer-cookies-link')).toHaveProp('href', 'https://www.mozilla.org/privacy/websites/#cookies');
    expect(root.find('.Footer-trademark-abuse-link')).toHaveText('Report Trademark Abuse');
    expect(root.find('.Footer-trademark-abuse-link')).toHaveProp('href', 'https://www.mozilla.org/about/legal/fraud-report/');

    // This link isn't localized because MDN will 404 on some
    // locales and not others.
    // See also https://bugzilla.mozilla.org/show_bug.cgi?id=1283422
    expect(root.find('.Footer-bug-report-link')).toHaveProp('href', 'https://developer.mozilla.org/Add-ons/AMO/Policy/Contact');
  });
});
<|endoftext|>


<commit_before>import { module, test, createStore, registerModels, cleanup } from '../helpers/setup';
import { Model, prefix, belongsTo } from 'sofa';

let store;
let db;

let Duck = Model.extend({
  id: prefix(),
  house: belongsTo('house')
});

let House = Model.extend({
  id: prefix()
});

module('belongs-to-persisted', () => {
  registerModels({ Duck, House });
  store = createStore();
  db = store.get('db.main');
  db.set('modelNames', [ 'duck', 'house' ]);
  return cleanup(store, [ 'main' ]);
});

test('serialize relationship', assert => {
  let house = db.model('house', { id: 'big' });
  let duck = db.model('duck', { id: 'yellow', house });
  assert.deepEqual(duck.serialize(), {
    "_id": "duck:yellow",
    "_attachments": {},
    "type": "duck",
    "house": "house:big"
  });
});

test('deserialize relationship', assert => {
  let model = db.push({ _id: 'duck:yellow', type: 'duck', house: 'house:big' });
  assert.deepEqual(model.serialize(), {
    "_id": "duck:yellow",
    "_attachments": {},
    "type": "duck",
    "house": "house:big"
  });
  assert.ok(db.existing('house', 'big'));
});

test('set makes parent dirty', assert => {
  let house = db.model('house', { id: 'big' });
  let duck = db.model('duck', { id: 'yellow', house });

  duck._internal.state.isDirty = false;
  duck.notifyPropertyChange('isDirty');
  assert.ok(duck.get('isDirty') === false);

  duck.set('house', house);
  assert.ok(duck.get('isDirty') === false);

  duck.set('house', db.model('house', { id: 'other' }));
  assert.ok(duck.get('isDirty') === true);
});
<commit_msg>belongs-to-persisted<commit_after>import { configurations, registerModels, cleanup } from '../helpers/setup';
import { Model, prefix, belongsTo } from 'sofa';

configurations(({ module, test, createStore }) => {

  let store;
  let db;

  let Duck = Model.extend({
    id: prefix(),
    house: belongsTo('house')
  });

  let House = Model.extend({
    id: prefix()
  });

  module('belongs-to-persisted', () => {
    registerModels({ Duck, House });
    store = createStore();
    db = store.get('db.main');
    db.set('modelNames', [ 'duck', 'house' ]);
    return cleanup(store, [ 'main' ]);
  });

  test('serialize relationship', assert => {
    let house = db.model('house', { id: 'big' });
    let duck = db.model('duck', { id: 'yellow', house });
    assert.deepEqual(duck.serialize(), {
      "_id": "duck:yellow",
      "_attachments": {},
      "type": "duck",
      "house": "house:big"
    });
  });

  test('deserialize relationship', assert => {
    let model = db.push({ _id: 'duck:yellow', type: 'duck', house: 'house:big' });
    assert.deepEqual(model.serialize(), {
      "_id": "duck:yellow",
      "_attachments": {},
      "type": "duck",
      "house": "house:big"
    });
    assert.ok(db.existing('house', 'big'));
  });

  test('set makes parent dirty', assert => {
    let house = db.model('house', { id: 'big' });
    let duck = db.model('duck', { id: 'yellow', house });

    duck._internal.state.isDirty = false;
    duck.notifyPropertyChange('isDirty');
    assert.ok(duck.get('isDirty') === false);

    duck.set('house', house);
    assert.ok(duck.get('isDirty') === false);

    duck.set('house', db.model('house', { id: 'other' }));
    assert.ok(duck.get('isDirty') === true);
  });

});
<|endoftext|>


<commit_before>(function (require, describe, it) {
  'use strict';

  var superagent = require('superagent');
  var expect = require('expect.js');
  var rek = require('rekuire');
  var testData = rek('testData.js');

  describe('Project API tests', function () {
    var id;
    var users = testData.testUsers;
    var projects = testData.testProjects;
    var agent = superagent.agent();

    it('Reset test', function (done) {
      agent.get('http://localhost:3000/test/project_api/reset/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });
    });

    it('List projects', function (done) {
      agent.get('http://localhost:3000/projects/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          expect(res.body.length)
            .to.be(0);
          //console.log('\nCurrent Projects:\n' + JSON.stringify(res.body));

          done();
        });
    });

    it('Create Project [0]', function (done) {
      var project = projects[0];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('Create Project [1]', function (done) {
      var project = projects[1];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('Create Project [2]', function (done) {
      var project = projects[2];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('List projects', function (done) {
      agent.get('http://localhost:3000/projects/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();

          //console.log('\nCurrent Projects:\n' + JSON.stringify(res.body));
          expect(res.body.length)
            .to.be(3);
          for (var i = 0; i < res.body.length; i++) {
            var project = res.body[i];
            // Hacky but easy way to determine if object contents match by value
            expect(JSON.stringify(projects))
              .to.match(new RegExp(JSON.stringify('*' + project + '*')));
          }

          done();
        });
    });

  });

})(require, describe, it);
<commit_msg>Tests now check for adding existing projects<commit_after>(function (require, describe, it) {
  'use strict';

  var superagent = require('superagent');
  var expect = require('expect.js');
  var rek = require('rekuire');
  var testData = rek('testData.js');

  describe('Project API tests', function () {
    var id;
    var users = testData.testUsers;
    var projects = testData.testProjects;
    var agent = superagent.agent();

    it('Reset test', function (done) {
      agent.get('http://localhost:3000/test/project_api/reset/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });
    });

    it('List projects', function (done) {
      agent.get('http://localhost:3000/projects/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          expect(res.body.length)
            .to.be(0);
          //console.log('\nCurrent Projects:\n' + JSON.stringify(res.body));

          done();
        });
    });

    it('Create Project [0]', function (done) {
      var project = projects[0];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('Create Project [1]', function (done) {
      var project = projects[1];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('Create Project [2]', function (done) {
      var project = projects[2];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();
          done();
        });

    });

    it('List projects', function (done) {
      agent.get('http://localhost:3000/projects/')
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.ok)
            .to.be.ok();

          //console.log('\nCurrent Projects:\n' + JSON.stringify(res.body));
          expect(res.body.length)
            .to.be(3);
          for (var i = 0; i < res.body.length; i++) {
            var project = res.body[i];
            // Hacky but easy way to determine if object contents match by value
            expect(JSON.stringify(projects))
              .to.match(new RegExp(JSON.stringify('*' + project + '*')));
          }

          done();
        });
    });

    it('Create Existing Project [0]', function (done) {
      var project = projects[0];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.status)
            .to.be(409);
          done();
        });

    });

    it('Create Existing Project [1]', function (done) {
      var project = projects[0];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.status)
            .to.be(409);
          done();
        });

    });

    it('Create Existing Project [2]', function (done) {
      var project = projects[0];

      agent.put('http://localhost:3000/projects/' + project.name + '/' +
        project.version + '/')
        .send(project)
        .end(function (e, res) {
          expect(e)
            .to.eql(null);
          expect(res.status)
            .to.be(409);
          done();
        });

    });

  });

})(require, describe, it);
<|endoftext|>


<commit_before>export default {
  mochaTimeout: 5000,
  seleniumTimeout: 5000,
  testClient: 'http://localhost:8080'
}
<commit_msg>increased timeout for mocha tests 5s -> 7s<commit_after>export default {
  mochaTimeout: 7000,
  seleniumTimeout: 5000,
  testClient: 'http://localhost:8080'
}
<|endoftext|>


<commit_before>/* jQRangeSlider
 * A javascript slider selector that supports dates
 *
 * Copyright (C) Guillaume Gautreau 2010
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 */

(function(){
	"use strict";

	function equal(actual, expected, epsilon){
		if (typeof actual !== typeof expected){
			return false;
		}

		if (isNaN(actual)){
			return isNaN(expected);
		}

		return Math.abs(expected - actual) < epsilon;
	}

	function equiv (actual, expected, epsilon){
		if (typeof actual !== typeof expected){
			return false;
		}

		if (typeof expected === "number"){
			return equal(actual, expected, epsilon);
		} else if (typeof expected === "object"){
			return equivObject(actual, expected, epsilon);
		} else {
			return actual === expected;
		}
	}

	function equivObject(actual, expected, epsilon){
		for(var name in expected){
			if (!equiv(actual[name], expected[name], epsilon)){
				return false;
			}
		}

		for(name in actual){
			if (!equiv(actual[name], expected[name], epsilon)){
				return false;
			}
		}

		return true;
	}

	QUnit.equalEpsilon = function(actual, expected, epsilon, message){
		QUnit.push(equal(actual, expected, epsilon), actual, expected, message );
	}

	QUnit.deepEqualEpsilon = function(actual, expected, epsilon, message){
		QUnit.push(equiv(actual, expected, epsilon), actual, expected, message);
	}

}());

<commit_msg>Fix jshint error<commit_after>/* jQRangeSlider
 * A javascript slider selector that supports dates
 *
 * Copyright (C) Guillaume Gautreau 2010
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 */

(function(){
	"use strict";

	function equal(actual, expected, epsilon){
		if (typeof actual !== typeof expected){
			return false;
		}

		if (isNaN(actual)){
			return isNaN(expected);
		}

		return Math.abs(expected - actual) < epsilon;
	}

	function equiv (actual, expected, epsilon){
		if (typeof actual !== typeof expected){
			return false;
		}

		if (typeof expected === "number"){
			return equal(actual, expected, epsilon);
		} else if (typeof expected === "object"){
			return equivObject(actual, expected, epsilon);
		} else {
			return actual === expected;
		}
	}

	function equivObject(actual, expected, epsilon){
		for(var name in expected){
			if (expected.hasOwnProperty(name) && !equiv(actual[name], expected[name], epsilon)){
				return false;
			}
		}

		for(name in actual){
			if (actual.hasOwnProperty(name) &&!equiv(actual[name], expected[name], epsilon)){
				return false;
			}
		}

		return true;
	}

	QUnit.equalEpsilon = function(actual, expected, epsilon, message){
		QUnit.push(equal(actual, expected, epsilon), actual, expected, message );
	}

	QUnit.deepEqualEpsilon = function(actual, expected, epsilon, message){
		QUnit.push(equiv(actual, expected, epsilon), actual, expected, message);
	}

}());

<|endoftext|>


<commit_before>(function ($, Backbone, _) {

    var Upload = Backbone.Model.extend({
        url: function () {
            var links = this.get('links'),
                url = links && links.self;
            if (!url) {
                url = Backbone.Model.prototype.url.call(this);
            }
            return url;
        },
        idAttribute: 'name'
    });

    var UploadCollection = Backbone.Collection.extend({
        model: Upload,
        url: '/uploads/',
        parse: function (response) {
            this._count = response.count;
            return response.files || [];
        }
    });

    var uploads = new UploadCollection();

})(jQuery, Backbone, _);
<commit_msg>Adding view classes for rendering the list of uploads.<commit_after>(function ($, Backbone, _) {

    var Upload = Backbone.Model.extend({
        url: function () {
            var links = this.get('links'),
                url = links && links.self;
            if (!url) {
                url = Backbone.Model.prototype.url.call(this);
            }
            return url;
        },
        idAttribute: 'name'
    });

    var UploadCollection = Backbone.Collection.extend({
        model: Upload,
        url: '/uploads/',
        parse: function (response) {
            this._count = response.count;
            return response.files || [];
        }
    });

    var uploads = new UploadCollection();

    var UploadView = Backbone.View.extend({
        className: 'file',
        template: _.template('<%- name %>'),
        initialize: function () {
            this.listenTo(this.model, 'change', this.render);
            this.listenTo(this.model, 'destroy', this.remove);
        },
        render: function () {
            this.$el.html(this.template(this.model.toJSON()));
        }
    });

    var UploadListingView = Backbone.View.extend({
        el: '#files',
        render: function () {
            this.$el.show();
        },
        addFile: function (file) {
            var view = new UploadView({model: file});
            this.$el.append(view.$el);
            view.render();
        }
    });

})(jQuery, Backbone, _);
<|endoftext|>


<commit_before>import AutoComplete from 'material-ui/AutoComplete';
import createComponent from './createComponent';
import mapError from './mapError';

const mapProps = props => ({
  ...mapError(props),
  floatingLabelFixed: true,
  searchText: props.input.value,
  onNewRequest: props.input.onChange,
});

export default createComponent(AutoComplete, mapProps);
<commit_msg>Fix AutoComplete redux-form component<commit_after>import AutoComplete from 'material-ui/AutoComplete';
import createComponent from './createComponent';
import mapError from './mapError';

const mapProps = props => ({
  ...mapError(props),
  floatingLabelFixed: true,
  searchText: props.input.value,
  onNewRequest: props.input.onChange,
  onUpdateInput: props.input.onChange,
});

export default createComponent(AutoComplete, mapProps);
<|endoftext|>