<commit_before>import {getTagged} from './deps/bp_logger.js';
import {Url} from './core/util/url.js';
import {Remuxer} from './core/remuxer/remuxer.js';
import DEFAULT_CLIENT from './client/rtsp/client.js';
import DEFAULT_TRANSPORT from './transport/websocket.js';

const Log = getTagged('wsp');

export class StreamType {
    static get HLS() {return 'hls';}
    static get RTSP() {return 'rtsp';}

    static isSupported(type) {
        return [StreamType.HLS, StreamType.RTSP].includes(type);
    }

    static fromUrl(url) {
        let parsed;
        try {
            parsed = Url.parse(url);
        } catch (e) {
            return null;
        }
        switch (parsed.protocol) {
            case 'rtsp':
                return StreamType.RTSP;
            case 'http':
            case 'https':
                if (url.indexOf('.m3u8')>=0) {
                    return StreamType.HLS;
                } else {
                    return null;
                }
            default:
                return null;
        }
    }

    static fromMime(mime) {
        switch (mime) {
            case 'application/x-rtsp':
                return StreamType.RTSP;
            case 'application/vnd.apple.mpegurl':
            case 'application/x-mpegurl':
                return StreamType.HLS;
            default:
                return null;
        }
    }
}

export class WSPlayer {

    constructor(node, opts) {
        if (typeof node == typeof '') {
            this.player = document.getElementById(node);
        } else {
            this.player = node;
        }

        let modules = opts.modules || {
            client: DEFAULT_CLIENT,
            transport: {
                constructor: DEFAULT_TRANSPORT
            }
        };
        this.errorHandler = opts.errorHandler || null;

        this.modules = {};
        for (let module of modules) {
            let transport = module.transport || DEFAULT_TRANSPORT;
            let client = module.client || DEFAULT_CLIENT;
            if (transport.constructor.canTransfer(client.streamType())) {
                this.modules[client.streamType()] = {
                    client: client,
                    transport: transport
                }
            } else {
                Log.warn(`Client stream type ${client.streamType()} is incompatible with transport types [${transport.streamTypes().join(', ')}]. Skip`)
            }
        }

        this.type = StreamType.RTSP;
        this.url = null;
        if (opts.url && opts.type) {
            this.url = opts.url;
            this.type = opts.type;
        } else {
            if (!this._checkSource(this.player)) {
                for (let i=0; i<this.player.children.length; ++i) {
                    if (this._checkSource(this.player.children[i])) {
                        break;
                    }
                }
            }
            // if (!this.url) {
            //      throw new Error('No playable endpoint found');
            // }
        }

        if (this.url) {
            this.setSource(this.url, this.type);
        }

        this.player.addEventListener('play', ()=>{
            if (!this.isPlaying()) {
                this.client.start();
            }
        }, false);

        this.player.addEventListener('pause', ()=>{
            this.client.stop();
        }, false);
    }

    // TODO: check native support

    isPlaying() {
        return !(this.player.paused || this.client.paused);
    }

    static canPlayWithModules(mimeType, modules) {

        let filteredModules = {};
        for (let module of modules) {
            let transport = module.transport || DEFAULT_TRANSPORT;
            let client = module.client || DEFAULT_CLIENT;
            if (transport.canTransfer(client.streamType())) {
                filteredModules[client.streamType()] = true;
            }
        }

        for (let type in filteredModules) {
            if (type == StreamType.fromMime(mimeType)) {
                return true;
            }
        }
        return false;
    }

    /// TODO: deprecate it?
    static canPlay(resource) {
        return StreamType.fromMime(resource.type) || StreamType.fromUrl(resource.src);
    }

    canPlayUrl(src) {
        let type = StreamType.fromUrl(src);
        return (type in this.modules);
    }

    _checkSource(src) {
        if (!src.dataset['ignore'] && src.src && !this.player.canPlayType(src.type) && (StreamType.fromMime(src.type) || StreamType.fromUrl(src.src))) {
            this.url = src.src;
            this.type = src.type ? StreamType.fromMime(src.type) : StreamType.fromUrl(src.src);
            return true;
        }
        return false;
    }

    async setSource(url, type) {
        if (this.transport) {
            if (this.client) {
                await this.client.detachTransport();
            }
            await this.transport.destroy();
        }
        try {
            this.endpoint = Url.parse(url);
        } catch (e) {
            return;
        }
        this.url = url;
        let transport = this.modules[type].transport;
        this.transport = new transport.constructor(this.endpoint, this.type, transport.options);

        let lastType = this.type;
        this.type = (StreamType.isSupported(type)?type:false) || StreamType.fromMime(type);
        if (!this.type) {
            throw new Error("Bad stream type");
        }

        if (lastType!=this.type || !this.client) {
            if (this.client) {
                await this.client.destroy();
            }
            let client = this.modules[type].client;
            this.client = new client();
        }

        this.client.reset();
        if (this.remuxer) {
            this.remuxer.destroy();
            this.remuxer = null;
        }
        this.remuxer = new Remuxer(this.player);
        this.remuxer.attachClient(this.client);

        this.client.attachTransport(this.transport);
        this.client.setSource(this.endpoint);

        if (this.player.autoplay) {
            this.start();
        }
    }

    start() {
        if (this.client) {
            this.client.start().catch((e)=>{
                if (this.errorHandler) {
                    this.errorHandler(e);
                }
            });
        }
    }

    stop() {
        if (this.client) {
            this.client.stop();
        }
    }

    async destroy() {
        if (this.transport) {
            if (this.client) {
                await this.client.detachTransport();
            }
            await this.transport.destroy();
        }
        if (this.client) {
            await this.client.destroy();
        }
        if (this.remuxer) {
            this.remuxer.destroy();
            this.remuxer = null;
        }
    }

}
<commit_msg>don't call client.reset<commit_after>import {getTagged} from './deps/bp_logger.js';
import {Url} from './core/util/url.js';
import {Remuxer} from './core/remuxer/remuxer.js';
import DEFAULT_CLIENT from './client/rtsp/client.js';
import DEFAULT_TRANSPORT from './transport/websocket.js';

const Log = getTagged('wsp');

export class StreamType {
    static get HLS() {return 'hls';}
    static get RTSP() {return 'rtsp';}

    static isSupported(type) {
        return [StreamType.HLS, StreamType.RTSP].includes(type);
    }

    static fromUrl(url) {
        let parsed;
        try {
            parsed = Url.parse(url);
        } catch (e) {
            return null;
        }
        switch (parsed.protocol) {
            case 'rtsp':
                return StreamType.RTSP;
            case 'http':
            case 'https':
                if (url.indexOf('.m3u8')>=0) {
                    return StreamType.HLS;
                } else {
                    return null;
                }
            default:
                return null;
        }
    }

    static fromMime(mime) {
        switch (mime) {
            case 'application/x-rtsp':
                return StreamType.RTSP;
            case 'application/vnd.apple.mpegurl':
            case 'application/x-mpegurl':
                return StreamType.HLS;
            default:
                return null;
        }
    }
}

export class WSPlayer {

    constructor(node, opts) {
        if (typeof node == typeof '') {
            this.player = document.getElementById(node);
        } else {
            this.player = node;
        }

        let modules = opts.modules || {
            client: DEFAULT_CLIENT,
            transport: {
                constructor: DEFAULT_TRANSPORT
            }
        };
        this.errorHandler = opts.errorHandler || null;

        this.modules = {};
        for (let module of modules) {
            let transport = module.transport || DEFAULT_TRANSPORT;
            let client = module.client || DEFAULT_CLIENT;
            if (transport.constructor.canTransfer(client.streamType())) {
                this.modules[client.streamType()] = {
                    client: client,
                    transport: transport
                }
            } else {
                Log.warn(`Client stream type ${client.streamType()} is incompatible with transport types [${transport.streamTypes().join(', ')}]. Skip`)
            }
        }

        this.type = StreamType.RTSP;
        this.url = null;
        if (opts.url && opts.type) {
            this.url = opts.url;
            this.type = opts.type;
        } else {
            if (!this._checkSource(this.player)) {
                for (let i=0; i<this.player.children.length; ++i) {
                    if (this._checkSource(this.player.children[i])) {
                        break;
                    }
                }
            }
            // if (!this.url) {
            //      throw new Error('No playable endpoint found');
            // }
        }

        if (this.url) {
            this.setSource(this.url, this.type);
        }

        this.player.addEventListener('play', ()=>{
            if (!this.isPlaying()) {
                this.client.start();
            }
        }, false);

        this.player.addEventListener('pause', ()=>{
            this.client.stop();
        }, false);
    }

    // TODO: check native support

    isPlaying() {
        return !(this.player.paused || this.client.paused);
    }

    static canPlayWithModules(mimeType, modules) {

        let filteredModules = {};
        for (let module of modules) {
            let transport = module.transport || DEFAULT_TRANSPORT;
            let client = module.client || DEFAULT_CLIENT;
            if (transport.canTransfer(client.streamType())) {
                filteredModules[client.streamType()] = true;
            }
        }

        for (let type in filteredModules) {
            if (type == StreamType.fromMime(mimeType)) {
                return true;
            }
        }
        return false;
    }

    /// TODO: deprecate it?
    static canPlay(resource) {
        return StreamType.fromMime(resource.type) || StreamType.fromUrl(resource.src);
    }

    canPlayUrl(src) {
        let type = StreamType.fromUrl(src);
        return (type in this.modules);
    }

    _checkSource(src) {
        if (!src.dataset['ignore'] && src.src && !this.player.canPlayType(src.type) && (StreamType.fromMime(src.type) || StreamType.fromUrl(src.src))) {
            this.url = src.src;
            this.type = src.type ? StreamType.fromMime(src.type) : StreamType.fromUrl(src.src);
            return true;
        }
        return false;
    }

    async setSource(url, type) {
        if (this.transport) {
            if (this.client) {
                await this.client.detachTransport();
            }
            await this.transport.destroy();
        }
        try {
            this.endpoint = Url.parse(url);
        } catch (e) {
            return;
        }
        this.url = url;
        let transport = this.modules[type].transport;
        this.transport = new transport.constructor(this.endpoint, this.type, transport.options);

        let lastType = this.type;
        this.type = (StreamType.isSupported(type)?type:false) || StreamType.fromMime(type);
        if (!this.type) {
            throw new Error("Bad stream type");
        }

        if (lastType!=this.type || !this.client) {
            if (this.client) {
                await this.client.destroy();
            }
            let client = this.modules[type].client;
            this.client = new client();
        } else {
            this.client.reset();
        }

        if (this.remuxer) {
            this.remuxer.destroy();
            this.remuxer = null;
        }
        this.remuxer = new Remuxer(this.player);
        this.remuxer.attachClient(this.client);

        this.client.attachTransport(this.transport);
        this.client.setSource(this.endpoint);

        if (this.player.autoplay) {
            this.start();
        }
    }

    start() {
        if (this.client) {
            this.client.start().catch((e)=>{
                if (this.errorHandler) {
                    this.errorHandler(e);
                }
            });
        }
    }

    stop() {
        if (this.client) {
            this.client.stop();
        }
    }

    async destroy() {
        if (this.transport) {
            if (this.client) {
                await this.client.detachTransport();
            }
            await this.transport.destroy();
        }
        if (this.client) {
            await this.client.destroy();
        }
        if (this.remuxer) {
            this.remuxer.destroy();
            this.remuxer = null;
        }
    }

}
<|endoftext|>


<commit_before>const { assign, camelCase, find, get, set } = require('lodash')
const { client } = require('nightwatch-cucumber')
const { When } = require('cucumber')

const fixtures = require('../../fixtures')

When(/^I (?:navigate|go|open|visit).*? `(.+)` page$/, async function (pageName) {
  try {
    const page = get(client.page, pageName)
    await page().navigate()
  } catch (error) {
    throw new Error(`The page object '${pageName}' does not exist`)
  }
})

When(/^I (?:navigate|go|open|visit).*? `(.+)` page using `(.+)` `(.+)` fixture$/, async function (pageName, entity, fixtureName) {
  const Page = get(client.page, pageName)()

  const fixture = find(fixtures[entity], { name: fixtureName })

  // TODO: Need to find a way to remove needing to store the item in state
  const entityTypeFieldName = camelCase(entity)
  set(this.state, entityTypeFieldName, assign({}, get(this.state, entityTypeFieldName), fixture))

  await Page.navigate(Page.url(fixtureName))
})

When('I click the {string} link', async function (linkText) {
  await client
    .useXpath()
    .click(`//a[text()='${linkText}']`)
    .useCss()
})
<commit_msg>Update common navigation step definitions<commit_after>const { assign, camelCase, find, get, set } = require('lodash')
const { client } = require('nightwatch-cucumber')
const { When } = require('cucumber')

const fixtures = require('../../fixtures')

When(/^I (?:navigate|go|open|visit).*? `(.+)` page$/, async function (pageName) {
  try {
    const page = get(client.page, pageName)()
    await page.navigate()
  } catch (error) {
    throw new Error(`The page object '${pageName}' does not exist`)
  }
})

When(/^I (?:navigate|go|open|visit).*? `(.+)` page using `(.+)` `(.+)` fixture$/, async function (pageName, entity, fixtureName) {
  try {
    const page = get(client.page, pageName)()

    const fixture = find(fixtures[entity], { name: fixtureName })

    // TODO: Need to find a way to remove needing to store the item in state
    const entityTypeFieldName = camelCase(entity)
    set(this.state, entityTypeFieldName, assign({}, get(this.state, entityTypeFieldName), fixture))

    await page.navigate(page.url(fixtureName))
  } catch (error) {
    throw new Error(`The page object '${pageName}' does not exist`)
  }
})

When('I click the {string} link', async function (linkText) {
  await client
    .useXpath()
    .click(`//a[text()='${linkText}']`)
    .useCss()
})
<|endoftext|>


<commit_before>var pulsar = require('../package.json');
var p5 = require('p5');

pulsar.config = pulsarInitConfig;
pulsarInitConfig = undefined;

pulsar.sketch = function (p) {

  // pulsar utils
  p.pulsar = {};
  p.pulsar.merge = function(defaults, pulse) {
    for (var attribute in pulse) {
      defaults[attribute] = pulse[attribute];
    }
  }

  var Receiver = require('./Receiver.js');
  var receiver = new Receiver();

  var Processor = require('./Processor.js');
  var processor = new Processor();

  var DrawingManager = require('./DrawingManager.js');
  var dM = new DrawingManager(p);

  var versionTag = pulsar.name.toUpperCase() + "(" + pulsar.config.col + ", " + pulsar.config.row + ") - v" + pulsar.version;

  p.setup = function() {
    p.frameRate(30);
    receiver.connect();

    receiver.on('pulse', function(data) {
      console.log("Pulsar: received: " + data);
      var drawing = processor.createDrawing(p, data, pulsar.config);
      if (drawing) {
        dM.add(drawing);
      }
    });

    receiver.on('pulsar control', function(data) {
      console.log("Pulsar: received: " + data);
      processor.processControl(data, pulsar.config);
    });

    p.createCanvas(p.windowWidth, p.windowHeight);

    dM.add(processor.createDrawing(p, {name: 'pulsar-splash', version: pulsar.version}));
  }

  p.draw = function() {
    p.noStroke();
    p.background(0);

    dM.drawAll();

    p.textSize(15);
    p.fill(175);
    p.textAlign(p.LEFT);
    var verWidth = p.textWidth(versionTag);
    p.text(versionTag, p.windowWidth - verWidth - 10, p.windowHeight - 10);
  }

  p.windowResized = function() {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
  }
}

new p5(pulsar.sketch);<commit_msg>Remove cursor<commit_after>var pulsar = require('../package.json');
var p5 = require('p5');

pulsar.config = pulsarInitConfig;
pulsarInitConfig = undefined;

pulsar.sketch = function (p) {

  // pulsar utils
  p.pulsar = {};
  p.pulsar.merge = function(defaults, pulse) {
    for (var attribute in pulse) {
      defaults[attribute] = pulse[attribute];
    }
  }

  var Receiver = require('./Receiver.js');
  var receiver = new Receiver();

  var Processor = require('./Processor.js');
  var processor = new Processor();

  var DrawingManager = require('./DrawingManager.js');
  var dM = new DrawingManager(p);

  var versionTag = pulsar.name.toUpperCase() + "(" + pulsar.config.col + ", " + pulsar.config.row + ") - v" + pulsar.version;

  p.setup = function() {
    p.noCursor();
    p.frameRate(30);
    receiver.connect();

    receiver.on('pulse', function(data) {
      console.log("Pulsar: received: " + data);
      var drawing = processor.createDrawing(p, data, pulsar.config);
      if (drawing) {
        dM.add(drawing);
      }
    });

    receiver.on('pulsar control', function(data) {
      console.log("Pulsar: received: " + data);
      processor.processControl(data, pulsar.config);
    });

    p.createCanvas(p.windowWidth, p.windowHeight);

    dM.add(processor.createDrawing(p, {name: 'pulsar-splash', version: pulsar.version}));
  }

  p.draw = function() {
    p.noStroke();
    p.background(0);

    dM.drawAll();

    p.textSize(15);
    p.fill(175);
    p.textAlign(p.LEFT);
    var verWidth = p.textWidth(versionTag);
    p.text(versionTag, p.windowWidth - verWidth - 10, p.windowHeight - 10);
  }

  p.windowResized = function() {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
  }
}

new p5(pulsar.sketch);<|endoftext|>


<commit_before>/*
Copyright 2021 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import "../../../skinned-sdk";

import React from "react";
import {configure, mount} from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import {act} from "react-dom/test-utils";

import * as TestUtils from "../../../test-utils";
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../src/utils/DMRoomMap";
import {RoomPermalinkCreator} from "../../../../src/utils/permalinks/Permalinks";
import ForwardDialog from "../../../../src/components/views/dialogs/ForwardDialog";

configure({ adapter: new Adapter() });

describe("ForwardDialog", () => {
    const sourceRoom = "!111111111111111111:example.org";
    const defaultMessage = TestUtils.mkMessage({
        room: sourceRoom,
        user: "@alice:example.org",
        msg: "Hello world!",
        event: true,
    });
    const defaultRooms = ["a", "A", "b"].map(name => TestUtils.mkStubRoom(name, name));

    const mountForwardDialog = async (message = defaultMessage, rooms = defaultRooms) => {
        const client = MatrixClientPeg.get();
        client.getVisibleRooms = jest.fn().mockReturnValue(rooms);

        let wrapper;
        await act(async () => {
            wrapper = mount(
                <ForwardDialog
                    cli={client}
                    event={message}
                    permalinkCreator={new RoomPermalinkCreator(undefined, sourceRoom)}
                    onFinished={jest.fn()}
                />,
            );
            // Wait one tick for our profile data to load so the state update happens within act
            await new Promise(resolve => setImmediate(resolve));
        });

        return wrapper;
    };

    beforeEach(() => {
        TestUtils.stubClient();
        DMRoomMap.makeShared();
        MatrixClientPeg.get().getUserId = jest.fn().mockReturnValue("@bob:example.org");
    });

    it("shows a preview with us as the sender", async () => {
        const wrapper = await mountForwardDialog();

        const previewBody = wrapper.find(".mx_EventTile_body");
        expect(previewBody.text()).toBe("Hello world!");

        // We would just test SenderProfile for the user ID, but it's stubbed
        const previewAvatar = wrapper.find(".mx_EventTile_avatar .mx_BaseAvatar_image");
        expect(previewAvatar.prop("title")).toBe("@bob:example.org");
    });

    it("filters the rooms", async () => {
        const wrapper = await mountForwardDialog();

        expect(wrapper.find("Entry")).toHaveLength(3);

        const searchInput = wrapper.find("SearchBox input");
        searchInput.instance().value = "a";
        searchInput.simulate("change");

        expect(wrapper.find("Entry")).toHaveLength(2);
    });

    it("tracks message sending progress across multiple rooms", async () => {
        const wrapper = await mountForwardDialog();

        // Make sendEvent require manual resolution so we can see the sending state
        let finishSend;
        let cancelSend;
        MatrixClientPeg.get().sendEvent = jest.fn(() => new Promise((resolve, reject) => {
            finishSend = resolve;
            cancelSend = reject;
        }));

        const firstButton = wrapper.find("Entry AccessibleButton").first();
        expect(firstButton.text()).toBe("Send");

        act(() => { firstButton.simulate("click"); });
        expect(firstButton.text()).toBe("Sending…");

        await act(async () => {
            cancelSend();
            // Wait one tick for the button to realize the send failed
            await new Promise(resolve => setImmediate(resolve));
        });
        expect(firstButton.text()).toBe("Failed to send");

        const secondButton = wrapper.find("Entry AccessibleButton").at(1);
        expect(secondButton.text()).toBe("Send");

        act(() => { secondButton.simulate("click"); });
        expect(secondButton.text()).toBe("Sending…");

        await act(async () => {
            finishSend();
            // Wait one tick for the button to realize the send succeeded
            await new Promise(resolve => setImmediate(resolve));
        });
        expect(secondButton.text()).toBe("Sent");
    });

    it("can render replies", async () => {
        const replyMessage = TestUtils.mkEvent({
            type: "m.room.message",
            room: "!111111111111111111:example.org",
            user: "@alice:example.org",
            content: {
                msgtype: "m.text",
                body: "> <@bob:example.org> Hi Alice!\n\nHi Bob!",
                "m.relates_to": {
                    "m.in_reply_to": {
                        event_id: "$2222222222222222222222222222222222222222222",
                    },
                },
            },
            event: true,
        });

        const wrapper = await mountForwardDialog(replyMessage);
        expect(wrapper.find("ReplyThread")).toBeTruthy();
    });

    it("disables buttons for rooms without send permissions", async () => {
        const readOnlyRoom = TestUtils.mkStubRoom("a", "a");
        readOnlyRoom.maySendMessage = jest.fn().mockReturnValue(false);
        const rooms = [readOnlyRoom, TestUtils.mkStubRoom("b", "b")];

        const wrapper = await mountForwardDialog(undefined, rooms);

        const firstButton = wrapper.find("Entry AccessibleButton").first();
        expect(firstButton.prop("disabled")).toBe(true);
        const secondButton = wrapper.find("Entry AccessibleButton").last();
        expect(secondButton.prop("disabled")).toBe(false);
    });
});
<commit_msg>Fix lints<commit_after>/*
Copyright 2021 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import "../../../skinned-sdk";

import React from "react";
import {configure, mount} from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import {act} from "react-dom/test-utils";

import * as TestUtils from "../../../test-utils";
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../src/utils/DMRoomMap";
import {RoomPermalinkCreator} from "../../../../src/utils/permalinks/Permalinks";
import ForwardDialog from "../../../../src/components/views/dialogs/ForwardDialog";

configure({ adapter: new Adapter() });

describe("ForwardDialog", () => {
    const sourceRoom = "!111111111111111111:example.org";
    const defaultMessage = TestUtils.mkMessage({
        room: sourceRoom,
        user: "@alice:example.org",
        msg: "Hello world!",
        event: true,
    });
    const defaultRooms = ["a", "A", "b"].map(name => TestUtils.mkStubRoom(name, name));

    const mountForwardDialog = async (message = defaultMessage, rooms = defaultRooms) => {
        const client = MatrixClientPeg.get();
        client.getVisibleRooms = jest.fn().mockReturnValue(rooms);

        let wrapper;
        await act(async () => {
            wrapper = mount(
                <ForwardDialog
                    cli={client}
                    event={message}
                    permalinkCreator={new RoomPermalinkCreator(undefined, sourceRoom)}
                    onFinished={jest.fn()}
                />,
            );
            // Wait one tick for our profile data to load so the state update happens within act
            await new Promise(resolve => setImmediate(resolve));
        });

        return wrapper;
    };

    beforeEach(() => {
        TestUtils.stubClient();
        DMRoomMap.makeShared();
        MatrixClientPeg.get().getUserId = jest.fn().mockReturnValue("@bob:example.org");
    });

    it("shows a preview with us as the sender", async () => {
        const wrapper = await mountForwardDialog();

        const previewBody = wrapper.find(".mx_EventTile_body");
        expect(previewBody.text()).toBe("Hello world!");

        // We would just test SenderProfile for the user ID, but it's stubbed
        const previewAvatar = wrapper.find(".mx_EventTile_avatar .mx_BaseAvatar_image");
        expect(previewAvatar.prop("title")).toBe("@bob:example.org");
    });

    it("filters the rooms", async () => {
        const wrapper = await mountForwardDialog();

        expect(wrapper.find("Entry")).toHaveLength(3);

        const searchInput = wrapper.find("SearchBox input");
        searchInput.instance().value = "a";
        searchInput.simulate("change");

        expect(wrapper.find("Entry")).toHaveLength(2);
    });

    it("tracks message sending progress across multiple rooms", async () => {
        const wrapper = await mountForwardDialog();

        // Make sendEvent require manual resolution so we can see the sending state
        let finishSend;
        let cancelSend;
        MatrixClientPeg.get().sendEvent = jest.fn(() => new Promise((resolve, reject) => {
            finishSend = resolve;
            cancelSend = reject;
        }));

        const firstButton = wrapper.find("Entry AccessibleButton").first();
        expect(firstButton.text()).toBe("Send");

        act(() => { firstButton.simulate("click"); });
        expect(firstButton.text()).toBe("Sending…");

        await act(async () => {
            cancelSend();
            // Wait one tick for the button to realize the send failed
            await new Promise(resolve => setImmediate(resolve));
        });
        expect(firstButton.text()).toBe("Failed to send");

        const secondButton = wrapper.find("Entry AccessibleButton").at(1);
        expect(secondButton.text()).toBe("Send");

        act(() => { secondButton.simulate("click"); });
        expect(secondButton.text()).toBe("Sending…");

        await act(async () => {
            finishSend();
            // Wait one tick for the button to realize the send succeeded
            await new Promise(resolve => setImmediate(resolve));
        });
        expect(secondButton.text()).toBe("Sent");
    });

    it("can render replies", async () => {
        const replyMessage = TestUtils.mkEvent({
            type: "m.room.message",
            room: "!111111111111111111:example.org",
            user: "@alice:example.org",
            content: {
                "msgtype": "m.text",
                "body": "> <@bob:example.org> Hi Alice!\n\nHi Bob!",
                "m.relates_to": {
                    "m.in_reply_to": {
                        event_id: "$2222222222222222222222222222222222222222222",
                    },
                },
            },
            event: true,
        });

        const wrapper = await mountForwardDialog(replyMessage);
        expect(wrapper.find("ReplyThread")).toBeTruthy();
    });

    it("disables buttons for rooms without send permissions", async () => {
        const readOnlyRoom = TestUtils.mkStubRoom("a", "a");
        readOnlyRoom.maySendMessage = jest.fn().mockReturnValue(false);
        const rooms = [readOnlyRoom, TestUtils.mkStubRoom("b", "b")];

        const wrapper = await mountForwardDialog(undefined, rooms);

        const firstButton = wrapper.find("Entry AccessibleButton").first();
        expect(firstButton.prop("disabled")).toBe(true);
        const secondButton = wrapper.find("Entry AccessibleButton").last();
        expect(secondButton.prop("disabled")).toBe(false);
    });
});
<|endoftext|>


<commit_before>describe('Request name scripts', function() {
    var _ = require('lodash'),
        testrun;

    before(function(done) {
        this.run({
            collection: {
                item: [{
                    name: 'r1',
                    event: [{
                        listen: 'test',
                        script: {
                            exec: 'tests[\'working\'] = (request.name===\'r1\' && request.description===\'testDesc\')'
                        }
                    }, {
                        listen: 'prerequest',
                        script: {
                            exec: 'if(request.name!==\'r1\' || request.description!==\'testDesc\') {undefFunction()}'
                        }
                    }],
                    request: {
                        url: 'postman-echo.com/get',
                        method: 'GET',
                        body: {
                            mode: 'formdata',
                            formdata: []
                        },
                        description: 'testDesc'
                    }
                }]
            }
        }, function(err, results) {
            testrun = results;
            done(err);
        });
    });

    it('must have run the test script successfully', function() {
        expect(testrun).be.ok();
        expect(testrun.test.calledOnce).be.ok();
        expect(testrun.prerequest.calledOnce).be.ok();

        expect(testrun.test.getCall(0).args[0]).to.be(null);
        expect(_.get(testrun.test.getCall(0).args[2], '0.result.globals.tests.working')).to.be(true);
    });

    it('must have completed the run', function() {
        expect(testrun).be.ok();
        expect(testrun.done.calledOnce).be.ok();
        expect(testrun.done.getCall(0).args[0]).to.be(null);
        expect(testrun.start.calledOnce).be.ok();
    });
});
<commit_msg>corrected the checks for request name in sandbox tests<commit_after>describe('Request name scripts', function() {
    var _ = require('lodash'),
        testrun;

    before(function(done) {
        this.run({
            collection: {
                item: [{
                    name: 'r1',
                    event: [{
                        listen: 'test',
                        script: {
                            exec: [
                                'var failed = postman.getEnvironmentVariable(\'fail\');',
                                'tests[\'working\'] = !failed && (request.name===\'r1\' && request.description===\'testDesc\')'
                            ]
                        }
                    }, {
                        listen: 'prerequest',
                        script: {
                            exec: [
                                'if(request.name!==\'r1\' || request.description!==\'testDesc\') {',
                                '    postman.setEnvironmentVariable(\'fail\', \'true\')',
                                '}'
                            ]
                        }
                    }],
                    request: {
                        url: 'postman-echo.com/get',
                        method: 'GET',
                        body: {
                            mode: 'formdata',
                            formdata: []
                        },
                        description: 'testDesc'
                    }
                }]
            }
        }, function(err, results) {
            testrun = results;
            done(err);
        });
    });

    it('must have run the test script successfully', function() {
        expect(testrun).be.ok();
        expect(testrun.test.calledOnce).be.ok();
        expect(testrun.prerequest.calledOnce).be.ok();

        expect(testrun.test.getCall(0).args[0]).to.be(null);
        expect(_.get(testrun.test.getCall(0).args[2], '0.result.globals.tests.working')).to.be(true);
    });

    it('must have completed the run', function() {
        expect(testrun).be.ok();
        expect(testrun.done.calledOnce).be.ok();
        expect(testrun.done.getCall(0).args[0]).to.be(null);
        expect(testrun.start.calledOnce).be.ok();
    });
});
<|endoftext|>


<commit_before>'use strict';
var assert = require('power-assert').customize({output: {maxDepth: 2}});
var sinon = require('sinon');

require('../../mocks/angular');
var AddLatentVariable = require('../../../../app/src/views/concretes/dialogs/add-latent-variable/add-latent-variable');
var ControllerStatic = AddLatentVariable.Controller;

var mockRootScope, stubRootScope, mockScope, stubScope;
var Controller = (() => {
  mockRootScope = {
    $broadcast: () => {}
  };
  stubRootScope = {
    $broadcast: sinon.stub(mockRootScope, '$broadcast')
  };

  mockScope = {
    dialog: {close: () => {}}
  };
  stubScope = {
    dialog: {
      close: sinon.stub(mockScope.dialog, 'close')
    }
  };
  return new ControllerStatic(mockRootScope, mockScope);
})();
var Definition = AddLatentVariable.Definition;

describe('DialogAddLatentVariable', () => {
  it('Controller has loaded', () => {
    assert(ControllerStatic !== void 0);
  });

  it('Definition has loaded', () => {
    assert(Definition !== void 0);
  });

  describe('Controller', () => {
    describe('#add()', () => {
      var dummy = 'dummy';
      before(() => {
        Controller.add(dummy);
      });

      it('should give the event name to arg[0] of $broadcast()', () => {
        assert(stubRootScope.$broadcast.getCall(0).args[0] === 'isem:addVariable');
      });

      it('should give the value to arg[1] of $broadcast()', () => {
        assert(stubRootScope.$broadcast.getCall(0).args[1] === dummy);
      });

      it('should do close()', () => {
        assert(stubScope.dialog.close.callCount === 1);
      });
    });
  });

  describe('Definition', () => {
    describe('.ddo()', () => {
      it('should return the field of require including ^cwModal', () => {
        assert(Definition.ddo().require === '^cwModal');
      });

      it('should return the field of controllerAs including AddLatentVariable', () => {
        assert(Definition.ddo().controllerAs === 'AddLatentVariable');
      });
    });
  });

});<commit_msg>chore(add-latent-variable-spec): remove insurance tests<commit_after>'use strict';
var assert = require('power-assert').customize({output: {maxDepth: 2}});
var sinon = require('sinon');

require('../../mocks/angular');
var AddLatentVariable = require('../../../../app/src/views/concretes/dialogs/add-latent-variable/add-latent-variable');
var ControllerStatic = AddLatentVariable.Controller;

var mockRootScope, stubRootScope, mockScope, stubScope;
var Controller = (() => {
  mockRootScope = {
    $broadcast: () => {}
  };
  stubRootScope = {
    $broadcast: sinon.stub(mockRootScope, '$broadcast')
  };

  mockScope = {
    dialog: {close: () => {}}
  };
  stubScope = {
    dialog: {
      close: sinon.stub(mockScope.dialog, 'close')
    }
  };
  return new ControllerStatic(mockRootScope, mockScope);
})();
var Definition = AddLatentVariable.Definition;

describe('DialogAddLatentVariable', () => {
  describe('Controller', () => {
    describe('#add()', () => {
      var dummy = 'dummy';
      before(() => {
        Controller.add(dummy);
      });

      it('should give the event name to arg[0] of $broadcast()', () => {
        assert(stubRootScope.$broadcast.getCall(0).args[0] === 'isem:addVariable');
      });

      it('should give the value to arg[1] of $broadcast()', () => {
        assert(stubRootScope.$broadcast.getCall(0).args[1] === dummy);
      });

      it('should do close()', () => {
        assert(stubScope.dialog.close.callCount === 1);
      });
    });
  });

  describe('Definition', () => {
    describe('.ddo()', () => {
      it('should return the field of require including ^cwModal', () => {
        assert(Definition.ddo().require === '^cwModal');
      });

      it('should return the field of controllerAs including AddLatentVariable', () => {
        assert(Definition.ddo().controllerAs === 'AddLatentVariable');
      });
    });
  });

});<|endoftext|>


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

moduleForComponent('ember-kalendae', 'Integration | Component | ember kalendae', {
  integration: true
});

test('it allows block usage', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#ember-kalendae}}
      template block text
    {{/ember-kalendae}}
  `);
  assert.ok(this.$().text().trim().indexOf('template block text') >= 0);
});

test('it initialises correctly without any config', function(assert) {
  assert.expect(1);

  this.set('kalendae', null);
  this.render(hbs`{{ember-kalendae instanceAPI=(action (mut kalendae))}}`);

  // it should initialise to today
  assert.equal(
    this.get('kalendae').getSelected(),
    new Date().toISOString().slice(0,10)
  );
});

test('it passes mode through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('mode', 'range');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      mode=mode
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.mode,
    this.get('mode')
  );
});

test('it passes months through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('months', '2');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      months=months
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.months,
    this.get('months')
  );
});

test('it passes weekStart through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('weekStart', '2');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      weekStart=weekStart
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.weekStart,
    this.get('weekStart')
  );
});

test('it passes direction through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('direction', 'past');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      direction=direction
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.direction,
    this.get('direction')
  );
});

test('it passes directionScrolling through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('directionScrolling', false);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      directionScrolling=directionScrolling
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.directionScrolling,
    this.get('directionScrolling')
  );
});

test('it passes blackout through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('blackout', '20170725T132629Z');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      blackout=blackout
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.blackout,
    this.get('blackout')
  );
});

test('it passes viewStartDate through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('viewStartDate', '20170725T132629Z');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      viewStartDate=viewStartDate
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.viewStartDate,
    this.get('viewStartDate')
  );
});

test('it passes dateClassMap through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dateClassMap', { foo: 'bar' });

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dateClassMap=dateClassMap
    }}`
  );

  assert.deepEqual(
    this.get('kalendae').settings.dateClassMap,
    this.get('dateClassMap')
  );
});

test('it passes dayOutOfMonthClickable through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayOutOfMonthClickable', true);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayOutOfMonthClickable=dayOutOfMonthClickable
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayOutOfMonthClickable,
    this.get('dayOutOfMonthClickable')
  );
});

test('it passes dayHeaderClickable through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayHeaderClickable', true);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayHeaderClickable=dayHeaderClickable
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayHeaderClickable,
    this.get('dayHeaderClickable')
  );
});

test('it passes useYearNav through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('useYearNav', false);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      useYearNav=useYearNav
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.useYearNav,
    this.get('useYearNav')
  );
});

test('it passes side through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('side', 'top');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      side=side
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.side,
    this.get('side')
  );
});

test('it passes columnHeaderFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('columnHeaderFormat', 'd');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      columnHeaderFormat=columnHeaderFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.columnHeaderFormat,
    this.get('columnHeaderFormat')
  );
});

test('it passes titleFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('titleFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      titleFormat=titleFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.titleFormat,
    this.get('titleFormat')
  );
});

test('it passes dayNumberFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayNumberFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayNumberFormat=dayNumberFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayNumberFormat,
    this.get('dayNumberFormat')
  );
});

test('it passes dayAttributeFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayAttributeFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayAttributeFormat=dayAttributeFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayAttributeFormat,
    this.get('dayAttributeFormat')
  );
});

test('it passes parseSplitDelimiter through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('parseSplitDelimiter', null);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      parseSplitDelimiter=parseSplitDelimiter
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.parseSplitDelimiter,
    this.get('parseSplitDelimiter')
  );
});

<commit_msg>=it passes it passes rangeDelimiter through to kalendae correctly<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('ember-kalendae', 'Integration | Component | ember kalendae', {
  integration: true
});

test('it allows block usage', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#ember-kalendae}}
      template block text
    {{/ember-kalendae}}
  `);
  assert.ok(this.$().text().trim().indexOf('template block text') >= 0);
});

test('it initialises correctly without any config', function(assert) {
  assert.expect(1);

  this.set('kalendae', null);
  this.render(hbs`{{ember-kalendae instanceAPI=(action (mut kalendae))}}`);

  // it should initialise to today
  assert.equal(
    this.get('kalendae').getSelected(),
    new Date().toISOString().slice(0,10)
  );
});

test('it passes mode through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('mode', 'range');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      mode=mode
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.mode,
    this.get('mode')
  );
});

test('it passes months through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('months', '2');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      months=months
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.months,
    this.get('months')
  );
});

test('it passes weekStart through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('weekStart', '2');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      weekStart=weekStart
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.weekStart,
    this.get('weekStart')
  );
});

test('it passes direction through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('direction', 'past');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      direction=direction
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.direction,
    this.get('direction')
  );
});

test('it passes directionScrolling through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('directionScrolling', false);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      directionScrolling=directionScrolling
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.directionScrolling,
    this.get('directionScrolling')
  );
});

test('it passes blackout through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('blackout', '20170725T132629Z');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      blackout=blackout
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.blackout,
    this.get('blackout')
  );
});

test('it passes viewStartDate through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('viewStartDate', '20170725T132629Z');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      viewStartDate=viewStartDate
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.viewStartDate,
    this.get('viewStartDate')
  );
});

test('it passes dateClassMap through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dateClassMap', { foo: 'bar' });

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dateClassMap=dateClassMap
    }}`
  );

  assert.deepEqual(
    this.get('kalendae').settings.dateClassMap,
    this.get('dateClassMap')
  );
});

test('it passes dayOutOfMonthClickable through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayOutOfMonthClickable', true);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayOutOfMonthClickable=dayOutOfMonthClickable
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayOutOfMonthClickable,
    this.get('dayOutOfMonthClickable')
  );
});

test('it passes dayHeaderClickable through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayHeaderClickable', true);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayHeaderClickable=dayHeaderClickable
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayHeaderClickable,
    this.get('dayHeaderClickable')
  );
});

test('it passes useYearNav through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('useYearNav', false);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      useYearNav=useYearNav
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.useYearNav,
    this.get('useYearNav')
  );
});

test('it passes side through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('side', 'top');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      side=side
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.side,
    this.get('side')
  );
});

test('it passes columnHeaderFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('columnHeaderFormat', 'd');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      columnHeaderFormat=columnHeaderFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.columnHeaderFormat,
    this.get('columnHeaderFormat')
  );
});

test('it passes titleFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('titleFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      titleFormat=titleFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.titleFormat,
    this.get('titleFormat')
  );
});

test('it passes dayNumberFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayNumberFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayNumberFormat=dayNumberFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayNumberFormat,
    this.get('dayNumberFormat')
  );
});

test('it passes dayAttributeFormat through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('dayAttributeFormat', 'MMMM');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      dayAttributeFormat=dayAttributeFormat
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.dayAttributeFormat,
    this.get('dayAttributeFormat')
  );
});

test('it passes parseSplitDelimiter through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('parseSplitDelimiter', null);

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      parseSplitDelimiter=parseSplitDelimiter
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.parseSplitDelimiter,
    this.get('parseSplitDelimiter')
  );
});

test('it passes rangeDelimiter through to kalendae correctly', function(assert) {
  assert.expect(1);

  this.set('rangeDelimiter', '-');

  this.render(hbs`
    {{ember-kalendae
      instanceAPI=(action (mut kalendae))
      rangeDelimiter=rangeDelimiter
    }}`
  );

  assert.equal(
    this.get('kalendae').settings.rangeDelimiter,
    this.get('rangeDelimiter')
  );
});

<|endoftext|>


<commit_before>/*jshint bitwise: true, camelcase: true, curly: true, eqeqeq: true, forin: true, immed: true, indent: 4, latedef: true, newcap: true, noarg: true, noempty: true, nonew: true, regexp: true, undef: true, unused: true, strict: true*/
/*global define*/
define(["util"], function (util) {

    "use strict";

    function error(msg) {
        return function (state) {
            throw new Error(msg + " (line " + state.lineNum + ", char " + state.charNum + ")");
        };
    }

    var skip = { toString: function () { return "{skip}"; } };

    function newline(state) {
        state.i++;
        state.lineNum++;
        state.charNum = 1;
        return read(state);
    }

    function readList(state) {
        var origState = state.clone();
        var openChr = state.input.charAt(state.i);
        var closeChr = openChr === "(" ? ")" :
                       openChr === "[" ? "]" :
                       openChr === "{" ? "}" :
                       error("Unknown list opener '" + openChr + "'")(state);
        var sym = openChr === "(" ? "paren" :
                  openChr === "[" ? "bracket" :
                  openChr === "{" ? "brace" : null;
        state.i++;
        var values = [];
        var closed = false;
        while (state.i < state.l) {
            if (state.input.charAt(state.i) === closeChr) {
                state.i++;
                closed = true;
                break;
            } else {
                var s = read(state);
                values.push(s);
            }
        }
        if (!closed) {
            error("Expected '" + closeChr + "'")(origState);
        }
        return util.createForm("list", values, { sym: sym });
    }

    function readNum(state) {
        var rxNum = /^[0-9\.]+$/;
        var rxHex = /^0x[0-9A-F]+$/i;
        var chunk = readToDelim(state);
        if (rxNum.test(chunk)) {
            return util.createForm("literal", parseFloat(chunk, 10));
        } else if (rxHex.test(chunk)) {
            return util.createForm("literal", parseInt(chunk, 16));
        } else {
            error("Invalid characters in number literal '" + chunk + "'")(state);
        }
    }

    function readString(state) {
        state.i++;
        var origState = state.clone();

        var chunk = "";
        var lastChr = null;
        var input = state.input;
        while (state.i < state.l) {
            var chr = input.charAt(state.i);
            if (chr === '"' && lastChr !== "\\") {
                break;
            } else {
                chunk += chr;
                lastChr = chr;
                state.i++;
                state.charNum++;
            }
        }

        if (state.i === state.l) {
            error("Unclosed string")(origState);
        }
        state.i++;
        return util.createForm("literal", '"' + chunk + '"');
    }

    function readSpecial(state) {
        var chunk = readToDelim(state);
        if (chunk === "#t") {
            return util.createForm("literal", true);
        } else if (chunk === "#f") {
            return util.createForm("literal", false);
        }
    }

    function readSymbol(state) {
        // TODO: this might be a tad too relaxed
        return util.createForm("symbol", readToDelim(state));
    }

    function readComment(state) {
        var text = "";
        state.i++;
        while (state.i < state.l) {
            var chr = state.input.charAt(state.i++);
            if (chr === "\n") {
                break;
            } else if (chr !== "\r") {
                text += chr;
            }
        }
        return util.createForm("list", [util.createForm("symbol", "comment"), text]);
    }

    function readQuote(type) {
        return function (state) {
            state.i++;
            var x = read(state);
            if (x === null) {
                error("Expected something for " + type.substring(0, type.length - 1) + "ing")(state);
            }
            return util.createForm("list", [util.createForm("symbol", type), x]);
        };
    }

    function readUnquote(state) {
        state.i++;
        var type = "unquote";
        if (state.input.charAt(state.i) === "@") {
            type += "-splicing";
            state.i++;
        }
        var x = read(state);
        if (x === null) {
            error("Expected something for " + (type === "unquote" ? "unquoting" : type))(state);
        }
        return util.createForm("list", [util.createForm("symbol", type), x]);
    }

    var delimiters = {
        "(" : true,
        "[" : true,
        "{" : true,
        ")" : true,
        "]" : true,
        "}" : true,
        '"' : true,
        "'" : true,
        "`" : true,
        "," : true,
        ";" : true,
        " " : true,
        "\t": true,
        "\r": true,
        "\n": true
    };

    function readToDelim(state) {
        var chunk = "";
        var input = state.input;
        while (state.i < state.l) {
            var chr = input.charAt(state.i);
            if (delimiters.hasOwnProperty(chr)) {
                break;
            } else {
                chunk += chr;
                state.i++;
                state.charNum++;
            }
        }
        return chunk;
    }

    var readers = {
        "(" : readList,
        "[" : readList,
        "{" : readList,
        ")" : error("Unexpected ')' in input"),
        "]" : error("Unexpected ']' in input"),
        "}" : error("Unexpected '}' in input"),
        "'" : readQuote("quote"),
        "`" : readQuote("quasiquote"),
        "," : readUnquote,
        ";" : readComment,
        "0" : readNum,
        "1" : readNum,
        "2" : readNum,
        "3" : readNum,
        "4" : readNum,
        "5" : readNum,
        "6" : readNum,
        "7" : readNum,
        "8" : readNum,
        "9" : readNum,
        '"' : readString,
        '#' : readSpecial,
        " " : skip,
        "\t": skip,
        "\n": newline,
        "\r": skip
    };

    function read(state) {
        while (state.i < state.l) {
            var chr = state.input.charAt(state.i);
            var reader = readers[chr];
            if (reader === skip) {
                state.i++;
                continue;
            } else if (reader) {
                return reader(state);
            } else {
                return readSymbol(state);
            }
        }
        return null;
    }

    function readAll(input) {
        var result = [];
        var state = {
            input: input,
            i: 0,
            l: input.length,
            lineNum: 1,
            charNum: 1,
            clone: function () {
                return util.copyProps(state, {});
            }
        };
        while (true) {
            var atom = read(state);
            if (atom === null) {
                return result;
            } else {
                result.push(atom);
            }
        }
    }

    return { read: readAll };

});<commit_msg>Altered string literals, probably not done yet<commit_after>/*jshint bitwise: true, camelcase: true, curly: true, eqeqeq: true, forin: true, immed: true, indent: 4, latedef: true, newcap: true, noarg: true, noempty: true, nonew: true, regexp: true, undef: true, unused: true, strict: true*/
/*global define*/
define(["util"], function (util) {

    "use strict";

    function error(msg) {
        return function (state) {
            throw new Error(msg + " (line " + state.lineNum + ", char " + state.charNum + ")");
        };
    }

    var skip = { toString: function () { return "{skip}"; } };

    function newline(state) {
        state.i++;
        state.lineNum++;
        state.charNum = 1;
        return read(state);
    }

    function readList(state) {
        var origState = state.clone();
        var openChr = state.input.charAt(state.i);
        var closeChr = openChr === "(" ? ")" :
                       openChr === "[" ? "]" :
                       openChr === "{" ? "}" :
                       error("Unknown list opener '" + openChr + "'")(state);
        var sym = openChr === "(" ? "paren" :
                  openChr === "[" ? "bracket" :
                  openChr === "{" ? "brace" : null;
        state.i++;
        var values = [];
        var closed = false;
        while (state.i < state.l) {
            if (state.input.charAt(state.i) === closeChr) {
                state.i++;
                closed = true;
                break;
            } else {
                var s = read(state);
                values.push(s);
            }
        }
        if (!closed) {
            error("Expected '" + closeChr + "'")(origState);
        }
        return util.createForm("list", values, { sym: sym });
    }

    function readNum(state) {
        var rxNum = /^[0-9\.]+$/;
        var rxHex = /^0x[0-9A-F]+$/i;
        var chunk = readToDelim(state);
        if (rxNum.test(chunk)) {
            return util.createForm("literal", parseFloat(chunk, 10));
        } else if (rxHex.test(chunk)) {
            return util.createForm("literal", parseInt(chunk, 16));
        } else {
            error("Invalid characters in number literal '" + chunk + "'")(state);
        }
    }

    function readString(state) {
        // TODO: escaping probably needs more work
        state.i++;
        var origState = state.clone();
        var chunk = "";
        var escaped = false;
        var input = state.input;
        while (state.i < state.l) {
            var chr = input.charAt(state.i);
            if (chr === '"' && !escaped) {
                break;
            }
            if (escaped || chr !== "\\") {
                chunk += chr;
                escaped = false;
            } else if (chr === "\\") {
                escaped = true;
            }
            state.i++;
            state.charNum++;
        }

        if (state.i === state.l) {
            error("Unclosed string")(origState);
        }
        state.i++;
        return util.createForm("literal", chunk);
    }

    function readSpecial(state) {
        var chunk = readToDelim(state);
        if (chunk === "#t") {
            return util.createForm("literal", true);
        } else if (chunk === "#f") {
            return util.createForm("literal", false);
        }
    }

    function readSymbol(state) {
        // TODO: this might be a tad too relaxed
        return util.createForm("symbol", readToDelim(state));
    }

    function readComment(state) {
        var text = "";
        state.i++;
        while (state.i < state.l) {
            var chr = state.input.charAt(state.i++);
            if (chr === "\n") {
                break;
            } else if (chr !== "\r") {
                text += chr;
            }
        }
        return util.createForm("list", [util.createForm("symbol", "comment"), text]);
    }

    function readQuote(type) {
        return function (state) {
            state.i++;
            var x = read(state);
            if (x === null) {
                error("Expected something for " + type.substring(0, type.length - 1) + "ing")(state);
            }
            return util.createForm("list", [util.createForm("symbol", type), x]);
        };
    }

    function readUnquote(state) {
        state.i++;
        var type = "unquote";
        if (state.input.charAt(state.i) === "@") {
            type += "-splicing";
            state.i++;
        }
        var x = read(state);
        if (x === null) {
            error("Expected something for " + (type === "unquote" ? "unquoting" : type))(state);
        }
        return util.createForm("list", [util.createForm("symbol", type), x]);
    }

    var delimiters = {
        "(" : true,
        "[" : true,
        "{" : true,
        ")" : true,
        "]" : true,
        "}" : true,
        '"' : true,
        "'" : true,
        "`" : true,
        "," : true,
        ";" : true,
        " " : true,
        "\t": true,
        "\r": true,
        "\n": true
    };

    function readToDelim(state) {
        var chunk = "";
        var input = state.input;
        while (state.i < state.l) {
            var chr = input.charAt(state.i);
            if (delimiters.hasOwnProperty(chr)) {
                break;
            } else {
                chunk += chr;
                state.i++;
                state.charNum++;
            }
        }
        return chunk;
    }

    var readers = {
        "(" : readList,
        "[" : readList,
        "{" : readList,
        ")" : error("Unexpected ')' in input"),
        "]" : error("Unexpected ']' in input"),
        "}" : error("Unexpected '}' in input"),
        "'" : readQuote("quote"),
        "`" : readQuote("quasiquote"),
        "," : readUnquote,
        ";" : readComment,
        "0" : readNum,
        "1" : readNum,
        "2" : readNum,
        "3" : readNum,
        "4" : readNum,
        "5" : readNum,
        "6" : readNum,
        "7" : readNum,
        "8" : readNum,
        "9" : readNum,
        '"' : readString,
        '#' : readSpecial,
        " " : skip,
        "\t": skip,
        "\n": newline,
        "\r": skip
    };

    function read(state) {
        while (state.i < state.l) {
            var chr = state.input.charAt(state.i);
            var reader = readers[chr];
            if (reader === skip) {
                state.i++;
                continue;
            } else if (reader) {
                return reader(state);
            } else {
                return readSymbol(state);
            }
        }
        return null;
    }

    function readAll(input) {
        var result = [];
        var state = {
            input: input,
            i: 0,
            l: input.length,
            lineNum: 1,
            charNum: 1,
            clone: function () {
                return util.copyProps(state, {});
            }
        };
        while (true) {
            var atom = read(state);
            if (atom === null) {
                return result;
            } else {
                result.push(atom);
            }
        }
    }

    return { read: readAll };

});<|endoftext|>


<commit_before>var normalizeCss = require("normalize.css"),
    React = require("react"),
    normalize = require("react-style-normalizer"),
    CleanCSS = require("clean-css"),
    _ = require("lodash"),
    base = require("./base"),
    buttons = require("./buttons"),
    card = require("./card"),
    forms = require("./forms"),
    grid = require("./grid"),
    headings = require("./headings"),
    helpers = require("./helpers"),
    images = require("./images"),
    labels = require("./labels"),
    listGroup = require("./listGroup"),
    nav = require("./nav"),
    sizes = require("./sizes"),
    responsive = require("./responsive"),
    styleObjects = [
        base,
        buttons,
        card,
        forms,
        grid,
        headings,
        helpers,
        images,
        labels,
        listGroup,
        nav,
        sizes
    ],
    recess;

function setPropertyHidden(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: false,
        value: value,
        writable: true
    });
}

function setPropertyPermanent(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: true,
        value: value,
        writable: true
    });
}

function setPropertyReadonly(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: false,
        value: value,
        writable: false
    });
}

function setResponsive(size) {
    _.forOwn(responsive(size),function(style,key){
        _.assign(this.styles[key],style);
    }.bind(this));
}

function Recess() {
    setPropertyHidden(this,"_app",undefined);
    setPropertyHidden(this,"_appWarn",true);
    setPropertyReadonly(this,"_component",{});
    setPropertyReadonly(this,"_componentOptions",{});
    setPropertyReadonly(this,"_componentStyles",{});
    setPropertyPermanent(this,"size",sizes.sizeName());
    setPropertyPermanent(this,"styles",{});

    _.forEach(styleObjects,function(style){
        _.assign(this.styles,style);
    }.bind(this));

    setResponsive.call(this,this.size);

    Object.preventExtensions(this);

    return this;
}

_.assign(Recess.prototype,{
    application:function(app){
        setPropertyReadonly(this,"_app",app);
        return this;
    },

    combine:function() {
        var obj = {};

        _.forEach(arguments,function(argument,i) {
            _.merge(obj,argument);
        });

        return obj;
    },

    componentOptions:function(component,options) {
        var name;

        if(!this._app && this._appWarn) {
            console.warn("Warning: You haven't created an application, which means each component will be managed independently. This is unavoidable if " +
                "you are using a different library as your application base, however if you are using React + Flux then providing an application " +
                "will increase performance of Recess and is highly advised.");

            this._appWarn = false;
        }

        if(_.isUndefined(component)) {
            console.error("Error: No component has been specified.");
            return this;
        }

        if(_.isString(component)) {
            return this._componentOptions[component];
        }

        if(_.isObject(component)) {
            name = component._reactInternalInstance && component._reactInternalInstance._currentElement.type.displayName;

            if(!this._component[name]) {
                this._component[name] = {};
            }

            if(!this._componentOptions[name]) {
                this._componentOptions[name] = {};
            }

            if(_.isUndefined(options)) {
                return this._componentOptions[name];
            }

            this._component[name] = component;
            _.assign(this._componentOptions[name],options);
        }

        return this;
    },

    componentStyles:function(component,styles) {
        var name;

        if(!this._app && this._appWarn) {
            console.warn("Warning: You haven't created an application, which means each component will be managed independently. This is unavoidable if " +
                "you are using a different library as your application base, however if you are using React + Flux then providing an application " +
                "will increase performance of Recess and is highly advised.");

            this._appWarn = false;
        }

        if(_.isUndefined(component)) {
            console.error("Error: No component has been specified.");
            return this;
        }

        if(_.isString(component)) {
            return this._componentStyles[component];
        }

        if(_.isObject(component)) {
            name = component._reactInternalInstance && component._reactInternalInstance._currentElement.type.displayName;

            if(!this._component[name]) {
                this._component[name] = {};
            }

            if(!this._componentStyles[name]) {
                this._componentStyles[name] = {};
            }

            if(_.isUndefined(styles)) {
                return this._componentStyles[name];
            }

            this._component[name] = component;
            _.assign(this._componentStyles[name],styles);
        }

        return this;
    },

    element:function(Element) {
        var Component = React.createClass({
            componentWillReceiveProps(newProps) {
                this.setState({
                    options:newProps.options || {},
                    style:newProps.style
                });
            },

            getInitialState() {
                return {
                    options:this.props.options || {},
                    style:this.props.style
                };
            },

            onBlur() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onBlur) {
                    this.props.onBlur.call();
                }
            },

            onDrag() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.drag)
                });

                if(this.props.onDrag) {
                    this.props.onDrag.call();
                }
            },

            onDragEnter() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.dragEnter)
                });

                if(this.props.onDragEnter) {
                    this.props.onDragEnter.call();
                }
            },

            onDragLeave() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onDragLeave) {
                    this.props.onDragLeave.call();
                }
            },

            onFocus() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.focus)
                });

                if(this.props.onFocus) {
                    this.props.onFocus.call();
                }
            },

            onMouseDown() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onMouseDown) {
                    this.props.onMouseDown.call();
                }
            },

            onMouseEnter() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.hover)
                });

                if(this.props.onMouseEnter) {
                    this.props.onMouseEnter.call();
                }
            },

            onMouseLeave() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onMouseLeave) {
                    this.props.onMouseLeave.call();
                }
            },

            onMouseUp() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.hover)
                });

                if(this.props.onMouseUp) {
                    this.props.onMouseUp.call();
                }
            },

            render() {
                var {
                        children,
                        onDragEnter,
                        onDragExit,
                        onDragLeave,
                        onDragOver,
                        onLoad,
                        onMouseDown,
                        onMouseEnter,
                        onMouseLeave,
                        onMouseUp,
                        onTouchEnd,
                        onTouchStart,
                        options,
                        style,
                        ...otherProps
                        } = this.props,
                    style = this.state.style;

                if(this.props.disabled) {
                    style = this.props.options.disabled;
                }

                if(this.props.readonly) {
                    style = this.props.options.readonly;
                }

                return (
                    <Element.type
                        onBlur={this.onBlur}
                        onDrag={this.onDrag}
                        onDragEnter={this.onDragEnter}
                        onDragLeave={this.onDragLeave}
                        onFocus={this.onFocus}
                        onLoad={this.onLoad}
                        onMouseDown={this.onMouseDown}
                        onMouseEnter={this.onMouseEnter}
                        onMouseLeave={this.onMouseLeave}
                        onMouseUp={this.onMouseUp}
                        onTouchEnd={this.onTouchEnd}
                        onTouchStart={this.onTouchStart}
                        style={style}
                        {...otherProps}>
                        {children}
                    </Element.type>
                );
            },

            onTouchEnd() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onTouchEnd) {
                    this.props.onTouchEnd.call();
                }
            },

            onTouchStart() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onTouchStart) {
                    this.props.onTouchStart.call();
                }
            }
        });

        return Component;
    },

    extend:function(styles) {
        _.forOwn(styles,function(value,key) {
            if(!this.styles[key]) {
                this.styles[key] = {}
            }

            if(_.isFunction(value)) {
                this.styles[key] = value;
            } else {
                assign(this.styles[key],value);
            }
        }.bind(this));

        return this;
    },

    onResize:function() {
        if(sizes.sizeName() !== this.size) {
            this.size = sizes.sizeName();
            this.render();
        }
    },

    prefix:normalize,

    render:function() {
        setResponsive.call(this,this.size);

        if(this._app) {
            this._app.forceUpdate();
        } else {
            _.forOwn(this._components,function(component){
                component.forceUpdate();
            });
        }

        return this;
    },

    stylesheet:function(id, styles) {
        if(_.isUndefined(id)) {
            console.error("Error: generated stylesheets need to be given an id.");
            return this;
        }

        if(document.getElementById(id) !== null) {
            return this;
        }

        let style = document.createElement("style");

        style.type = "text/css";
        style.id = id;

        if(_.isString(styles)) {
            style.textContent = new CleanCSS().minify(styles).styles;
        } else if(_.isObject(styles)) {
            let str = "";

            _.forOwn(styles,function(style,key) {
                str += key + "{";

                style = normalize(style);

                _.forOwn(style,function(value,property) {
                    if(property.charAt(0).toUpperCase() === property.charAt(0)) {
                        str += "-";
                    }

                    str += _.kebabCase(property) + ":" + value + ";";
                });

                str += "}"
            });

            style.textContent = new CleanCSS().minify(str).styles;
        } else {
            console.error("Error: You either need to provide an object or a string when creating a new stylesheet");
            return this;
        }

        document.head.appendChild(style);

        return this;
    }
});

module.exports = Recess;
<commit_msg>Forgot to fix the function syntax on the element piece<commit_after>var normalizeCss = require("normalize.css"),
    React = require("react"),
    normalize = require("react-style-normalizer"),
    CleanCSS = require("clean-css"),
    _ = require("lodash"),
    base = require("./base"),
    buttons = require("./buttons"),
    card = require("./card"),
    forms = require("./forms"),
    grid = require("./grid"),
    headings = require("./headings"),
    helpers = require("./helpers"),
    images = require("./images"),
    labels = require("./labels"),
    listGroup = require("./listGroup"),
    nav = require("./nav"),
    sizes = require("./sizes"),
    responsive = require("./responsive"),
    styleObjects = [
        base,
        buttons,
        card,
        forms,
        grid,
        headings,
        helpers,
        images,
        labels,
        listGroup,
        nav,
        sizes
    ],
    recess;

function setPropertyHidden(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: false,
        value: value,
        writable: true
    });
}

function setPropertyPermanent(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: true,
        value: value,
        writable: true
    });
}

function setPropertyReadonly(obj,prop,value) {
    Object.defineProperty(obj,prop,{
        configurable: false,
        enumerable: false,
        value: value,
        writable: false
    });
}

function setResponsive(size) {
    _.forOwn(responsive(size),function(style,key){
        _.assign(this.styles[key],style);
    }.bind(this));
}

function Recess() {
    setPropertyHidden(this,"_app",undefined);
    setPropertyHidden(this,"_appWarn",true);
    setPropertyReadonly(this,"_component",{});
    setPropertyReadonly(this,"_componentOptions",{});
    setPropertyReadonly(this,"_componentStyles",{});
    setPropertyPermanent(this,"size",sizes.sizeName());
    setPropertyPermanent(this,"styles",{});

    _.forEach(styleObjects,function(style){
        _.assign(this.styles,style);
    }.bind(this));

    setResponsive.call(this,this.size);

    Object.preventExtensions(this);

    return this;
}

_.assign(Recess.prototype,{
    application:function(app){
        setPropertyReadonly(this,"_app",app);
        return this;
    },

    combine:function() {
        var obj = {};

        _.forEach(arguments,function(argument,i) {
            _.merge(obj,argument);
        });

        return obj;
    },

    componentOptions:function(component,options) {
        var name;

        if(!this._app && this._appWarn) {
            console.warn("Warning: You haven't created an application, which means each component will be managed independently. This is unavoidable if " +
                "you are using a different library as your application base, however if you are using React + Flux then providing an application " +
                "will increase performance of Recess and is highly advised.");

            this._appWarn = false;
        }

        if(_.isUndefined(component)) {
            console.error("Error: No component has been specified.");
            return this;
        }

        if(_.isString(component)) {
            return this._componentOptions[component];
        }

        if(_.isObject(component)) {
            name = component._reactInternalInstance && component._reactInternalInstance._currentElement.type.displayName;

            if(!this._component[name]) {
                this._component[name] = {};
            }

            if(!this._componentOptions[name]) {
                this._componentOptions[name] = {};
            }

            if(_.isUndefined(options)) {
                return this._componentOptions[name];
            }

            this._component[name] = component;
            _.assign(this._componentOptions[name],options);
        }

        return this;
    },

    componentStyles:function(component,styles) {
        var name;

        if(!this._app && this._appWarn) {
            console.warn("Warning: You haven't created an application, which means each component will be managed independently. This is unavoidable if " +
                "you are using a different library as your application base, however if you are using React + Flux then providing an application " +
                "will increase performance of Recess and is highly advised.");

            this._appWarn = false;
        }

        if(_.isUndefined(component)) {
            console.error("Error: No component has been specified.");
            return this;
        }

        if(_.isString(component)) {
            return this._componentStyles[component];
        }

        if(_.isObject(component)) {
            name = component._reactInternalInstance && component._reactInternalInstance._currentElement.type.displayName;

            if(!this._component[name]) {
                this._component[name] = {};
            }

            if(!this._componentStyles[name]) {
                this._componentStyles[name] = {};
            }

            if(_.isUndefined(styles)) {
                return this._componentStyles[name];
            }

            this._component[name] = component;
            _.assign(this._componentStyles[name],styles);
        }

        return this;
    },

    element:function(Element) {
        var Component = React.createClass({
            componentWillReceiveProps:function(newProps) {
                this.setState({
                    options:newProps.options || {},
                    style:newProps.style
                });
            },

            getInitialState:function() {
                return {
                    options:this.props.options || {},
                    style:this.props.style
                };
            },

            onBlur:function() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onBlur) {
                    this.props.onBlur.call();
                }
            },

            onDrag:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.drag)
                });

                if(this.props.onDrag) {
                    this.props.onDrag.call();
                }
            },

            onDragEnter:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.dragEnter)
                });

                if(this.props.onDragEnter) {
                    this.props.onDragEnter.call();
                }
            },

            onDragLeave:function() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onDragLeave) {
                    this.props.onDragLeave.call();
                }
            },

            onFocus:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.focus)
                });

                if(this.props.onFocus) {
                    this.props.onFocus.call();
                }
            },

            onMouseDown:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onMouseDown) {
                    this.props.onMouseDown.call();
                }
            },

            onMouseEnter:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.hover)
                });

                if(this.props.onMouseEnter) {
                    this.props.onMouseEnter.call();
                }
            },

            onMouseLeave:function() {
                this.setState({
                    style:this.props.style
                });

                if(this.props.onMouseLeave) {
                    this.props.onMouseLeave.call();
                }
            },

            onMouseUp:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.hover)
                });

                if(this.props.onMouseUp) {
                    this.props.onMouseUp.call();
                }
            },

            render:function() {
                var {
                        children,
                        onDragEnter,
                        onDragExit,
                        onDragLeave,
                        onDragOver,
                        onLoad,
                        onMouseDown,
                        onMouseEnter,
                        onMouseLeave,
                        onMouseUp,
                        onTouchEnd,
                        onTouchStart,
                        options,
                        style,
                        ...otherProps
                    } = this.props,
                    style = this.state.style;

                if(this.props.disabled) {
                    style = this.props.options.disabled;
                }

                if(this.props.readonly) {
                    style = this.props.options.readonly;
                }

                return (
                    <Element.type
                        onBlur={this.onBlur}
                        onDrag={this.onDrag}
                        onDragEnter={this.onDragEnter}
                        onDragLeave={this.onDragLeave}
                        onFocus={this.onFocus}
                        onLoad={this.onLoad}
                        onMouseDown={this.onMouseDown}
                        onMouseEnter={this.onMouseEnter}
                        onMouseLeave={this.onMouseLeave}
                        onMouseUp={this.onMouseUp}
                        onTouchEnd={this.onTouchEnd}
                        onTouchStart={this.onTouchStart}
                        style={style}
                        {...otherProps}>
                        {children}
                    </Element.type>
                );
            },

            onTouchEnd:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onTouchEnd) {
                    this.props.onTouchEnd.call();
                }
            },

            onTouchStart:function() {
                this.setState({
                    style:_.assign({},this.props.style,this.state.options.active)
                });

                if(this.props.onTouchStart) {
                    this.props.onTouchStart.call();
                }
            }
        });

        return Component;
    },

    extend:function(styles) {
        _.forOwn(styles,function(value,key) {
            if(!this.styles[key]) {
                this.styles[key] = {}
            }

            if(_.isFunction(value)) {
                this.styles[key] = value;
            } else {
                assign(this.styles[key],value);
            }
        }.bind(this));

        return this;
    },

    onResize:function() {
        if(sizes.sizeName() !== this.size) {
            this.size = sizes.sizeName();
            this.render();
        }
    },

    prefix:normalize,

    render:function() {
        setResponsive.call(this,this.size);

        if(this._app) {
            this._app.forceUpdate();
        } else {
            _.forOwn(this._components,function(component){
                component.forceUpdate();
            });
        }

        return this;
    },

    stylesheet:function(id, styles) {
        if(_.isUndefined(id)) {
            console.error("Error: generated stylesheets need to be given an id.");
            return this;
        }

        if(document.getElementById(id) !== null) {
            return this;
        }

        let style = document.createElement("style");

        style.type = "text/css";
        style.id = id;

        if(_.isString(styles)) {
            style.textContent = new CleanCSS().minify(styles).styles;
        } else if(_.isObject(styles)) {
            let str = "";

            _.forOwn(styles,function(style,key) {
                str += key + "{";

                style = normalize(style);

                _.forOwn(style,function(value,property) {
                    if(property.charAt(0).toUpperCase() === property.charAt(0)) {
                        str += "-";
                    }

                    str += _.kebabCase(property) + ":" + value + ";";
                });

                str += "}"
            });

            style.textContent = new CleanCSS().minify(str).styles;
        } else {
            console.error("Error: You either need to provide an object or a string when creating a new stylesheet");
            return this;
        }

        document.head.appendChild(style);

        return this;
    }
});

module.exports = Recess;
<|endoftext|>