<commit_before>/**
 * Copyright 2015 Solinea, Inc.
 *
 * 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.
 */

/*global sinon, todo, chai, describe, it, calledOnce*/
//integration tests

describe('spawnsView.js spec', function() {
    beforeEach(function() {

        $('body').html('

' +
            '
 ' +
            '
' +
            '
' +
            '<form class="global-refresh-selector" role="form">' +
            '
' +
            '
' +
            '
' +
            '<select class="form-control" id="global-refresh-range">' +
            '<option value="15">refresh 15s</option>' +
            '<option value="30" selected>refresh 30s</option>' +
            '<option value="60">refresh 1m</option>' +
            '<option value="300">refresh 5m</option>' +
            '<option value="-1">refresh off</option>' +
            '</select>' +
            '
' +
            '
' +
            '
' +
            '</form>' +
            '
' +
            '
' +
            '<form class="global-lookback-selector" role="form">' +
            '
' +
            '
' +
            '
' +
            '<select class="form-control" id="global-lookback-range">' +
            '<option value="15">lookback 15m</option>' +
            '<option value="60" selected>lookback 1h</option>' +
            '<option value="360">lookback 6h</option>' +
            '<option value="1440">lookback 1d</option>' +
            '</select>' +
            '
' +
            '
' +
            '
' +
            '</form>' +
            '
');

        // to answer GET requests
        this.server = sinon.fakeServer.create();
        this.server.respondWith("GET", "/something/fancy", [200, {
            "Content-Type": "application/json"
        }, '[]']);

        // confirm that dom is clear of view elements before each test:
        expect($('svg').length).to.equal(0);
        expect($('#spinner').length).to.equal(0);

        this.testCollection = new SpawnsCollection({
            urlPrefix: '/nova/hypervisor/spawns/'
        });

        this.mockZerosSpy = sinon.spy(this.testCollection, "mockZeros");

        this.testView = new SpawnsView({
            chartTitle: "Tester API Performance",
            collection: this.testCollection,
            height: 300,
            infoCustom: 'novaSpawns',
            el: '.testContainer',
            width: $('body').width(),
            yAxisLabel: 'yAxisTest'
        });
    });
    afterEach(function() {
        $('body').html('');
        this.mockZerosSpy.restore();
        // this.server.respond();
        this.server.restore();
    });
    describe('collection is constructed', function() {
        it('should exist', function() {
            var dataTest = JSON.stringify('hello');
            assert.isDefined(this.testCollection, 'this.testCollection has been defined');
            expect(this.testCollection.parse).to.be.a('function');
            this.testCollection.initialize({
                urlPrefix: 'glance'
            });
            expect(this.testCollection.length).to.equal(1);
            this.testCollection.add({
                test1: 'test1'
            });
            expect(this.testCollection.length).to.equal(2);
            this.testCollection.parse(dataTest);
        });
        it('should have a mock function', function() {
            assert.isDefined(this.testCollection.mockZeros, 'mockZeros function has been defined');
        });
        it('should return normal results when they exist', function() {
            var test1; // undefined
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(1);

            test1 = [];
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(2);

            test1 = [{
                randomKey: []
            }];
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(3);

            test1 = {
                per_interval: []
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(4);

            test1 = {
                aggregations: {}
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(5);

            test1 = {
                aggregations: {
                    per_interval: {}
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(6);

            test1 = {
                aggregations: {
                    per_interval: {
                        buckets: []
                    }
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(7);

            test1 = {
                aggregations: {
                    per_interval: {
                        buckets: [1]
                    }
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(7); // not incremented!
        });
        it('should produce correct mock results', function() {
            var test1 = this.testCollection.mockZeros();
            expect(test1.length).to.equal(24);
            test1 = this.testCollection.mockZeros(100, 1000);
            expect(test1.length).to.be.closeTo(24, 2);

            // all mocks should be equivalent
            test1.forEach(function(sample) {
                expect(sample.success.buckets[0]).to.deep.equal({
                    key: "true",
                    doc_count: 0
                });
            });
        });
    });

    describe('view is constructed', function() {
        it('should exist', function() {
            assert.isDefined(this.testView, 'this.testView has been defined');
            expect(this.testView).to.be.an('object');
            expect(this.testView.el).to.equal('.testContainer');
        });
        it('returns data.per_interval', function() {
            var test1 = this.testCollection.parse(123);
            expect(test1).to.not.deep.equal([]);
            test1 = this.testCollection.parse({
                aggregations: {
                    per_interval: {
                        buckets: [123]
                    }
                }
            });
            expect(test1).to.deep.equal([123]);
        });
        it('view update appends svg and border elements', function() {
            expect(this.testView.update).to.be.a('function');
            this.testView.update();
            expect($('svg').length).to.equal(1);
            expect($('g.legend-items').find('text').text()).to.equal('FailSuccess');
            expect($('.panel-title').text().trim()).to.equal('Tester API Performance');
            expect($('svg').text()).to.not.include('Response was empty');
        });
        it('can handle a null server payload and append appropriate response', function() {
            this.update_spy = sinon.spy(this.testView, "update");
            expect($('#noDataReturned').text()).to.equal('');
            this.testCollection.reset();
            this.testView.update();
            expect($('.popup-message').text()).to.equal('No Data Returned');
            this.testCollection.add({
                url: '/blah'
            });
            this.testView.update();
            expect($('#noDataReturned').text()).to.equal('');
            expect(this.update_spy.callCount).to.equal(2);
            this.update_spy.restore();
        });
        it('listens for changes to the global lookback/refresh selectors', function() {
            this.urlGenerator_spy = sinon.spy(this.testCollection, "urlGenerator");
            this.testView.trigger('lookbackSelectorChanged');
            expect(this.urlGenerator_spy.callCount).to.equal(1);
            this.urlGenerator_spy.restore();
        });
        it('properly parses success and failure events', function() {

            var test = this.testView.dataPrep([{
                "key": 1462468350000
            }]);
            expect(test).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": 0,
                "Failure": 0
            }]);

            var test0 = this.testView.dataPrep([{
                "success": {
                },
                "key": 1462468350000
            }]);
            expect(test0).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": 0,
                "Failure": 0
            }]);

            var test1 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 2
                    }, {
                        "key": "true",
                        "doc_count": 2
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test1).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [2],
                "Failure": [2]
            }]);

            var test2 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 0
                    }, {
                        "key": "true",
                        "doc_count": 2
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test2).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [2],
                "Failure": [0]
            }]);

            var test3 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 3
                    }, {
                        "key": "true",
                        "doc_count": 0
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test3).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [0],
                "Failure": [3]
            }]);

            var test4 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "true",
                        "doc_count": 5
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test4).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [5],
                "Failure": []
            }]);

            var test5 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 5
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test5).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [],
                "Failure": [5]
            }]);

            var test6 = this.testView.dataPrep([{
                "success": {
                    "buckets": []
                },
                "key": 1462468350000
            }]);
            expect(test6).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [],
                "Failure": []
            }]);
        });
        it('properly prepares popovers', function() {
            var test1 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: '6',
                Physical: '16',
                Virtual: '256',
                total: 256,
                stackedBarPrep: [1, 2, 3]
            });
            var test2 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: '16',
                Physical: '26',
                Virtual: '356',
                total: 456,
                stackedBarPrep: [1, 2, 3, 4]
            });
            expect(test1).to.include('
Virtual: 256
Physical: 16
Used: 6
');
            expect(test2).to.include('
Virtual: 356
Physical: 26
Used: 16
');
            // can handle dates but various kinds of missing data
            var test3 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: undefined,
                Physical: undefined,
                Virtual: undefined,
                total: undefined,
                stackedBarPrep: [1, 2, 3]
            });
            expect(test3).to.include('
Virtual: undefined
Physical: undefined
Used: undefined
');
            var test4 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: 0,
                Physical: 0,
                Virtual: 0,
                total: 0,
                stackedBarPrep: [1, 2, 3]
            });
            expect(test4).to.include('
Virtual: 0
Physical: 0
Used: 0
');
            var test5 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093'
            });
            expect(test5).to.include('
');
            var test6 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: 'bicycles',
                Physical: 'discomfort',
                Virtual: 'indestructable'
            });
            expect(test6).to.include('
Virtual: indestructable
Physical: discomfort
Used: bicycles
');
        });
    });
});
<commit_msg>Update tests for spawns.<commit_after>/**
 * Copyright 2015 Solinea, Inc.
 *
 * 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.
 */

/*global sinon, todo, chai, describe, it, calledOnce*/
//integration tests

describe('spawnsView.js spec', function() {
    beforeEach(function() {

        $('body').html('

' +
            '
 ' +
            '
' +
            '
' +
            '<form class="global-refresh-selector" role="form">' +
            '
' +
            '
' +
            '
' +
            '<select class="form-control" id="global-refresh-range">' +
            '<option value="15">refresh 15s</option>' +
            '<option value="30" selected>refresh 30s</option>' +
            '<option value="60">refresh 1m</option>' +
            '<option value="300">refresh 5m</option>' +
            '<option value="-1">refresh off</option>' +
            '</select>' +
            '
' +
            '
' +
            '
' +
            '</form>' +
            '
' +
            '
' +
            '<form class="global-lookback-selector" role="form">' +
            '
' +
            '
' +
            '
' +
            '<select class="form-control" id="global-lookback-range">' +
            '<option value="15">lookback 15m</option>' +
            '<option value="60" selected>lookback 1h</option>' +
            '<option value="360">lookback 6h</option>' +
            '<option value="1440">lookback 1d</option>' +
            '</select>' +
            '
' +
            '
' +
            '
' +
            '</form>' +
            '
');

        // to answer GET requests
        this.server = sinon.fakeServer.create();
        this.server.respondWith("GET", "/something/fancy", [200, {
            "Content-Type": "application/json"
        }, '[]']);

        // confirm that dom is clear of view elements before each test:
        expect($('svg').length).to.equal(0);
        expect($('#spinner').length).to.equal(0);

        this.testCollection = new SpawnsCollection({
            urlPrefix: '/nova/hypervisor/spawns/'
        });

        this.mockZerosSpy = sinon.spy(this.testCollection, "mockZeros");

        this.testView = new SpawnsView({
            chartTitle: "Tester API Performance",
            collection: this.testCollection,
            height: 300,
            infoCustom: 'novaSpawns',
            el: '.testContainer',
            width: $('body').width(),
            yAxisLabel: 'yAxisTest'
        });
    });
    afterEach(function() {
        $('body').html('');
        this.mockZerosSpy.restore();
        // this.server.respond();
        this.server.restore();
    });
    describe('collection is constructed', function() {
        it('should exist', function() {
            var dataTest = JSON.stringify('hello');
            assert.isDefined(this.testCollection, 'this.testCollection has been defined');
            expect(this.testCollection.parse).to.be.a('function');
            this.testCollection.initialize({
                urlPrefix: 'glance'
            });
            expect(this.testCollection.length).to.equal(1);
            this.testCollection.add({
                test1: 'test1'
            });
            expect(this.testCollection.length).to.equal(2);
            this.testCollection.parse(dataTest);
        });
        it('should have a mock function', function() {
            assert.isDefined(this.testCollection.mockZeros, 'mockZeros function has been defined');
        });
        it('should return normal results when they exist', function() {
            var test1; // undefined
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(1);

            test1 = [];
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(2);

            test1 = [{
                randomKey: []
            }];
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(3);

            test1 = {
                per_interval: []
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(4);

            test1 = {
                aggregations: {}
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(5);

            test1 = {
                aggregations: {
                    per_interval: {}
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(6);

            test1 = {
                aggregations: {
                    per_interval: {
                        buckets: []
                    }
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(7);

            test1 = {
                aggregations: {
                    per_interval: {
                        buckets: [1]
                    }
                }
            };
            this.testCollection.preProcessData(test1);
            expect(this.mockZerosSpy.callCount).to.equal(7); // not incremented!
        });
        it('should produce correct mock results', function() {
            var test1 = this.testCollection.mockZeros();
            expect(test1.length).to.equal(24);
            test1 = this.testCollection.mockZeros(100, 1000);
            expect(test1.length).to.be.closeTo(24, 2);

            // all mocks should be equivalent
            test1.forEach(function(sample) {
                expect(sample.success.buckets[0]).to.deep.equal({
                    key: "true",
                    doc_count: 0
                });
            });
        });
    });

    describe('view is constructed', function() {
        it('should exist', function() {
            assert.isDefined(this.testView, 'this.testView has been defined');
            expect(this.testView).to.be.an('object');
            expect(this.testView.el).to.equal('.testContainer');
        });
        it('returns data.per_interval', function() {
            var test1 = this.testCollection.parse(123);
            expect(test1).to.not.deep.equal([]);
            test1 = this.testCollection.parse({
                aggregations: {
                    per_interval: {
                        buckets: [123]
                    }
                }
            });
            expect(test1).to.deep.equal([123]);
        });
        it('view update appends svg and border elements', function() {
            expect(this.testView.update).to.be.a('function');
            this.testView.update();
            expect($('svg').length).to.equal(1);
            expect($('g.legend-items').find('text').text()).to.equal('FailSuccess');
            expect($('.panel-title').text().trim()).to.equal('Tester API Performance');
            expect($('svg').text()).to.not.include('Response was empty');
        });
        it('can handle a null server payload and append appropriate response', function() {
            this.update_spy = sinon.spy(this.testView, "update");
            expect($('#noDataReturned').text()).to.equal('');
            this.testCollection.reset();
            this.testView.update();
            expect($('.popup-message').text()).to.equal('No Data Returned');
            this.testCollection.add({
                url: '/blah'
            });
            this.testView.update();
            expect($('#noDataReturned').text()).to.equal('');
            expect(this.update_spy.callCount).to.equal(2);
            this.update_spy.restore();
        });
        it('listens for changes to the global lookback/refresh selectors', function() {
            this.urlGenerator_spy = sinon.spy(this.testCollection, "urlGenerator");
            this.testView.trigger('lookbackSelectorChanged');
            expect(this.urlGenerator_spy.callCount).to.equal(1);
            this.urlGenerator_spy.restore();
        });
        it('properly parses success and failure events', function() {

            var test = this.testView.dataPrep([{
                "key": 1462468350000
            }]);
            expect(test).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": 0,
                "Failure": 0
            }]);

            var test0 = this.testView.dataPrep([{
                "success": {
                },
                "key": 1462468350000
            }]);
            expect(test0).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": 0,
                "Failure": 0
            }]);

            var test1 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 2
                    }, {
                        "key": "true",
                        "doc_count": 2
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test1).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [2],
                "Failure": [2]
            }]);

            var test2 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 0
                    }, {
                        "key": "true",
                        "doc_count": 2
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test2).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [2],
                "Failure": [0]
            }]);

            var test3 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 3
                    }, {
                        "key": "true",
                        "doc_count": 0
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test3).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [0],
                "Failure": [3]
            }]);

            var test4 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "true",
                        "doc_count": 5
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test4).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [5],
                "Failure": [0]
            }]);

            var test5 = this.testView.dataPrep([{
                "success": {
                    "buckets": [{
                        "key": "false",
                        "doc_count": 5
                    }]
                },
                "key": 1462468350000
            }]);
            expect(test5).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [0],
                "Failure": [5]
            }]);

            var test6 = this.testView.dataPrep([{
                "success": {
                    "buckets": []
                },
                "key": 1462468350000
            }]);
            expect(test6).to.deep.equal([{
                "eventTime": 1462468350000,
                "Success": [0],
                "Failure": [0]
            }]);
        });
        it('properly prepares popovers', function() {
            var test1 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: '6',
                Physical: '16',
                Virtual: '256',
                total: 256,
                stackedBarPrep: [1, 2, 3]
            });
            var test2 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: '16',
                Physical: '26',
                Virtual: '356',
                total: 456,
                stackedBarPrep: [1, 2, 3, 4]
            });
            expect(test1).to.include('
Virtual: 256
Physical: 16
Used: 6
');
            expect(test2).to.include('
Virtual: 356
Physical: 26
Used: 16
');
            // can handle dates but various kinds of missing data
            var test3 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: undefined,
                Physical: undefined,
                Virtual: undefined,
                total: undefined,
                stackedBarPrep: [1, 2, 3]
            });
            expect(test3).to.include('
Virtual: undefined
Physical: undefined
Used: undefined
');
            var test4 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: 0,
                Physical: 0,
                Virtual: 0,
                total: 0,
                stackedBarPrep: [1, 2, 3]
            });
            expect(test4).to.include('
Virtual: 0
Physical: 0
Used: 0
');
            var test5 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093'
            });
            expect(test5).to.include('
');
            var test6 = this.testView.computeHiddenBarText({
                eventTime: '1425071850093',
                Used: 'bicycles',
                Physical: 'discomfort',
                Virtual: 'indestructable'
            });
            expect(test6).to.include('
Virtual: indestructable
Physical: discomfort
Used: bicycles
');
        });
    });
});
<|endoftext|>


<commit_before>/**
 * Created by ksinger on 20.08.2015.
 */
;
import won from '../won-es6.js';
import angular from 'angular';
//import loginComponent from './login.js';
//import logoutComponent from './logout.js';
import dropdownModule from './covering-dropdown.js';
import accountMenuModule from './account-menu.js';
import {
    attach,
    getIn,
 } from '../utils.js';
import { actionCreators }  from '../actions/actions.js';
import {
    connect2Redux,
} from '../won-utils.js';

import * as srefUtils from '../sref-utils.js';

function genTopnavConf() {
    let template = `

            <svg class="si__icon" style="--local-primary:white;">
                <use href="#ico16_indicator_warning"></use>
            </svg>

                Lost connection – make sure your internet-connection
                is working, then click “reconnect”.

            <button
                ng-show="self.connectionHasBeenLost && !self.reconnecting"
                ng-click="self.reconnect()"
                class="si__button">
                    Reconnect
            </button>

                                {{ self.appTitle }}

                        <svg class="topnav__button__icon logo" style="--local-primary:var(--won-primary-color);">
                            <use href="#ico36_plus"></use>
                        </svg>
                        New Post

                                    Sign up

                            <won-account-menu>
                            </won-account-menu>

                    <won-login open="self.open"></won-login>

                    <won-logout open="self.open"></won-logout>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.infoToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_info"></use>
                </svg>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.warnToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_warning"></use>
                </svg>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.errorToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_error"></use>
                </svg>

                        {{toast.get('msg')}}

                        If the problem persists please contact

                            {{self.adminEmail}}

                <svg class="topnav__toasts__element__close clickable"
                    ng-click="self.toasts__delete(toast)"
                    style="--local-primary:var(--won-primary-color);">
                        <use href="#ico27_close"></use>
                </svg>

    `;

    const serviceDependencies = ['$ngRedux', '$scope', '$sanitize', '$state', /*injections as strings here*/];

    class Controller {
        constructor(/* arguments <- serviceDependencies */){
            attach(this, serviceDependencies, arguments);
            Object.assign(this, srefUtils); // bind srefUtils to scope

            window.tnc4dbg = this;

            const selectFromState = (state) => ({
                themeName: getIn(state, ['config', 'theme', 'name']),
                appTitle: getIn(state, ['config', 'theme', 'title']),
                adminEmail: getIn(state, ['config', 'theme', 'adminEmail']),
                WON: won.WON,
                loginVisible: state.get('loginVisible'),
                open: state.get('loginVisible'), // TODO interim while transition to redux-state based solution (i.e. "loginVisible")
                loggedIn: state.getIn(['user', 'loggedIn']),
                email: state.getIn(['user','email']),
                toastsArray: state.getIn(['toasts']).toArray(),
                connectionHasBeenLost: state.getIn(['messages', 'lostConnection']), // name chosen to avoid name-clash with the action-creator
                reconnecting: state.getIn(['messages', 'reconnecting']),
            });

            connect2Redux(selectFromState, actionCreators, [], this);
        }

        showLogin() {
            this.open = true;
        }
    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        scope: {},//isolate scope to allow usage within other controllers/components
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        template: template
    }
}

export default angular.module('won.owner.components.topnav', [
        'ngSanitize',
        //loginComponent,
        //logoutComponent,
        dropdownModule,
        accountMenuModule,
    ])
    .directive('wonTopnav', genTopnavConf)
    .name;

<commit_msg>Hide New Post button in topnav<commit_after>/**
 * Created by ksinger on 20.08.2015.
 */
;
import won from '../won-es6.js';
import angular from 'angular';
//import loginComponent from './login.js';
//import logoutComponent from './logout.js';
import dropdownModule from './covering-dropdown.js';
import accountMenuModule from './account-menu.js';
import {
    attach,
    getIn,
 } from '../utils.js';
import { actionCreators }  from '../actions/actions.js';
import {
    connect2Redux,
} from '../won-utils.js';

import * as srefUtils from '../sref-utils.js';

function genTopnavConf() {
    let template = `

            <svg class="si__icon" style="--local-primary:white;">
                <use href="#ico16_indicator_warning"></use>
            </svg>

                Lost connection – make sure your internet-connection
                is working, then click “reconnect”.

            <button
                ng-show="self.connectionHasBeenLost && !self.reconnecting"
                ng-click="self.reconnect()"
                class="si__button">
                    Reconnect
            </button>

                                {{ self.appTitle }}

                                    Sign up

                            <won-account-menu>
                            </won-account-menu>

                    <won-login open="self.open"></won-login>

                    <won-logout open="self.open"></won-logout>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.infoToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_info"></use>
                </svg>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.warnToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_warning"></use>
                </svg>

                <svg class="topnav__toasts__element__icon"
                    ng-show="toast.get('type') === self.WON.errorToast"
                    style="--local-primary:#CCD2D2">
                        <use href="#ico16_indicator_error"></use>
                </svg>

                        {{toast.get('msg')}}

                        If the problem persists please contact

                            {{self.adminEmail}}

                <svg class="topnav__toasts__element__close clickable"
                    ng-click="self.toasts__delete(toast)"
                    style="--local-primary:var(--won-primary-color);">
                        <use href="#ico27_close"></use>
                </svg>

    `;

    const serviceDependencies = ['$ngRedux', '$scope', '$sanitize', '$state', /*injections as strings here*/];

    class Controller {
        constructor(/* arguments <- serviceDependencies */){
            attach(this, serviceDependencies, arguments);
            Object.assign(this, srefUtils); // bind srefUtils to scope

            window.tnc4dbg = this;

            const selectFromState = (state) => ({
                themeName: getIn(state, ['config', 'theme', 'name']),
                appTitle: getIn(state, ['config', 'theme', 'title']),
                adminEmail: getIn(state, ['config', 'theme', 'adminEmail']),
                WON: won.WON,
                loginVisible: state.get('loginVisible'),
                open: state.get('loginVisible'), // TODO interim while transition to redux-state based solution (i.e. "loginVisible")
                loggedIn: state.getIn(['user', 'loggedIn']),
                email: state.getIn(['user','email']),
                toastsArray: state.getIn(['toasts']).toArray(),
                connectionHasBeenLost: state.getIn(['messages', 'lostConnection']), // name chosen to avoid name-clash with the action-creator
                reconnecting: state.getIn(['messages', 'reconnecting']),
            });

            connect2Redux(selectFromState, actionCreators, [], this);
        }

        showLogin() {
            this.open = true;
        }
    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        scope: {},//isolate scope to allow usage within other controllers/components
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        template: template
    }
}

export default angular.module('won.owner.components.topnav', [
        'ngSanitize',
        //loginComponent,
        //logoutComponent,
        dropdownModule,
        accountMenuModule,
    ])
    .directive('wonTopnav', genTopnavConf)
    .name;

<|endoftext|>


<commit_before>JAR.register({
    MID: 'jar.async.Value',
    deps: [{
        System: ['::isSet', '::isA', '::isFunction']
    }, {
        'jar.lang': ['Array!iterate,reduce', {
            Object: ['!derive,iterate', '::hasOwn']
        }, 'Class', {
            Function: ['!modargs', '::bind', '::identity', '::negate', '::noop']
        }]
    }],
    bundle: ['M$Accumulator', 'M$Decidable', 'M$FlowRegulator', 'M$Debuggable', 'M$Memorizable', 'M$Mergable', 'M$Skipable', 'M$Takeable']
}, function(isSet, isA, isFunction, Arr, Obj, hasOwn, Class, Fn, bind, identity, negate, noop) {
    'use strict';

    var async = this,
        returnTrue = Fn.partial(identity, true),
        returnFalse = negate(returnTrue),
        VALUE_UPDATE = 0,
        VALUE_ERROR = 1,
        VALUE_FREEZE = 2,
        changes = [],
        Value;

    changes[VALUE_UPDATE] = {
        handle: 'onUpdate',

        counter: 'updated',

        key: 'value'
    };

    changes[VALUE_ERROR] = {
        handle: 'onError',

        counter: 'errored',

        key: 'error'
    };

    changes[VALUE_FREEZE] = {
        handle: 'onFreeze',

        counter: 'frozen'
    };

    Value = Class('Value', Obj.extend({
        constant: function(constantValue) {
            return this.map(Fn.partial(identity, constantValue));
        },

        forward: function() {
            return this.chainValue();
        },

        forwardTo: function(value, customSubscription) {
            this.subscribe(Obj.merge({
                onUpdate: bind(value.assign, value),

                onError: bind(value.error, value),

                onFreeze: bind(value.freeze, value)
            }, customSubscription));

            return value;
        },

        chainValue: function(options) {
            var transform = options.transform || identity,
                shouldUpdate = options.guardUpdate || returnTrue,
                shouldFreeze = options.guardFreeze || returnFalse,
                chainedValue = new this.Class();

            this.forwardTo(chainedValue, {
                onUpdate: function(newValue) {
                    if (shouldUpdate(newValue)) {
                        chainedValue.assign(transform(newValue));
                    }

                    shouldFreeze(newValue) && chainedValue.freeze();
                }
            });

            return chainedValue;
        },

        map: function(mapFn) {
            return this.chainValue({
                transform: mapFn
            });
        },

        accept: function(acceptFn) {
            return this.chainValue({
                guardUpdate: acceptFn
            });
        },

        $: {
            construct: function(value) {
                this._$handles = Obj();
                // TODO implement with taskqueue
                this._$scheduledChanges = [];

                arguments.length && this.assign(value);
            },

            assign: assignValue,

            '=': assignValue,

            update: function(updater) {
                return this._$scheduleChange(VALUE_UPDATE, updater);
            },

            error: function(newError) {
                isA(newError, Error) || (newError = new TypeError('Expected value.error() to be called with Error object'));

                return this._$scheduleChange(VALUE_ERROR, Fn.partial(identity, newError));
            },

            freeze: function() {
                return this._$scheduleChange(VALUE_FREEZE, noop);
            },

            subscribe: function(subscription) {
                var value = this,
                    subscriptionID = false,
                    onFreeze = subscription.onFreeze;

                async.wait(value.$proxy, 0, value, function delayInitialCall() {
                    Arr.each(changes, function invokeHandleInitial(change) {
                        if (value['_$' + change.counter]) {
                            value._$attemptInvokeHandle(subscription, change.handle, value['_$' + change.key]);
                        }
                    });
                });

                if (!value._$frozen) {
                    subscriptionID = value.getHash() + ' handle_id:' + value._$nextHandleID;

                    value._$nextHandleID++;
                    value._$handlesCount++;

                    subscription.onFreeze = function() {
                        onFreeze && onFreeze.call(subscription);
                        value.unsubscribe(subscriptionID);
                    };

                    value._$handles[subscriptionID] = subscription;
                }

                return subscriptionID;
            },

            unsubscribe: function(subscriptionID) {
                var handles = this._$handles,
                    unsubscribed = false;

                if (hasOwn(handles, subscriptionID)) {
                    this._$handlesCount--;

                    delete handles[subscriptionID];

                    unsubscribed = true;
                }

                return unsubscribed;
            }
        },

        _$: {
            value: null,

            updated: 0,

            error: null,

            errored: 0,

            frozen: 0,

            handles: null,

            handlesCount: 0,

            nextHandleID: 0,
            // TODO implement with taskqueue
            scheduledChanges: null,
            // TODO implement with taskqueue
            changesScheduled: false,
            // TODO implement with taskqueue
            scheduleChange: function(changeType, changer) {
                this._$scheduledChanges.push({
                    type: changeType,

                    fn: changer
                });

                //TODO improve asynchronous handling
                if (!this._$changesScheduled) {
                    async.wait(this.$proxy, 0, this, this._$doChanges);

                    this._$changesScheduled = true;
                }

                return this;
            },
            // TODO implement with taskqueue
            doChanges: function() {
                var value = this,
                    scheduledChanges = value._$scheduledChanges;

                while (scheduledChanges.length && !value._$frozen) {
                    this._$doChange(scheduledChanges.shift());
                }

                this._$changesScheduled = false;
            },
            // TODO implement with taskqueue
            doChange: function(scheduledChange) {
                var value = this,
                    changer = scheduledChange.fn,
                    changeType = scheduledChange.type,
                    change = changes[changeType],
                    handleMethod = change.handle,
                    key = change.key,
                    currentValue = value['_$' + key],
                    newValue = changer(currentValue);

                value._$handles.each(function forwardValueToHandle(handle) {
                    value._$attemptInvokeHandle(handle, handleMethod, newValue);
                });

                if (changeType === VALUE_ERROR && !value._$handlesCount) {
                    value._$onUnhandledError(newValue);
                }

                key && (value['_$' + key] = newValue);

                value['_$' + change.counter]++;
            },

            attemptInvokeHandle: function(handle, handleType, value) {
                var isUnHandledError = false;

                try {
                    if (handle[handleType]) {
                        handle[handleType](value);
                    }
                    else {
                        isUnHandledError = handleType === changes[VALUE_ERROR].handle;
                    }
                }
                catch (e) {
                    if (handle.error) {
                        handle.error(e);
                    }
                    else {
                        value = e;
                        isUnHandledError = true;
                    }
                }

                isUnHandledError && this._$onUnhandledError(value);
            },

            onUnhandledError: function(error) {
                this.Class.logger.error('Unhandled ${name}: ${message} for ${hash}', {
                    name: error.name,

                    message: error.message,

                    hash: this.getHash()
                });
            }
        }
    }, Arr.reduce(changes, addHandleSubscriber, {})));

    function addHandleSubscriber(handleSubscribers, change) {
        var handleName = change.handle;

        handleSubscribers[handleName] = function(handle) {
            var subscription = {};

            subscription[handleName] = handle;

            return this.subscribe(subscription);
        };

        return handleSubscribers;
    }

    function assignValue(newValue) {
        /*jslint validthis: true */
        return this.update(Fn.partial(identity, newValue));
    }

    return Value;
});<commit_msg>Updated "jar.async.Value"<commit_after>JAR.register({
    MID: 'jar.async.Value',
    deps: [{
        System: ['::isSet', '::isA', '::isFunction']
    }, {
        'jar.lang': ['Array!iterate,reduce', {
            Object: ['!derive,iterate', '::hasOwn']
        }, 'Class', {
            Function: ['!modargs', '::bind', '::identity', '::negate', '::noop']
        }]
    }],
    bundle: ['M$Accumulator', 'M$Decidable', 'M$FlowRegulator', 'M$Debuggable', 'M$Memorizable', 'M$Mergable', 'M$Skipable', 'M$Takeable']
}, function(isSet, isA, isFunction, Arr, Obj, hasOwn, Class, Fn, bind, identity, negate, noop) {
    'use strict';

    var async = this,
        returnTrue = Fn.partial(identity, true),
        returnFalse = negate(returnTrue),
        VALUE_UPDATE = 0,
        VALUE_ERROR = 1,
        VALUE_FREEZE = 2,
        changes = [],
        Value;

    changes[VALUE_UPDATE] = {
        handle: 'onUpdate',

        counter: 'updated',

        key: 'value'
    };

    changes[VALUE_ERROR] = {
        handle: 'onError',

        counter: 'errored',

        key: 'error'
    };

    changes[VALUE_FREEZE] = {
        handle: 'onFreeze',

        counter: 'frozen'
    };

    Value = Class('Value', Obj.extend({
        constant: function(constantValue) {
            return this.map(Fn.partial(identity, constantValue));
        },

        forward: function() {
            return this.chainValue();
        },

        forwardTo: function(forwardedValue, customSubscription) {
            var value = this,
                subscriptionID = value.subscribe(Obj.merge({
                    onUpdate: bind(forwardedValue.assign, forwardedValue),

                    onError: bind(forwardedValue.error, forwardedValue),

                    onFreeze: bind(forwardedValue.freeze, forwardedValue)
                }, customSubscription));

            forwardedValue.onFreeze(function() {
                value.unsubcribe(subscriptionID);
            });

            return forwardedValue;
        },

        chainValue: function(options) {
            var transform = options.transform || identity,
                shouldUpdate = options.guardUpdate || returnTrue,
                shouldFreeze = options.guardFreeze || returnFalse,
                chainedValue = new this.Class();

            this.forwardTo(chainedValue, {
                onUpdate: function(newValue) {
                    if (shouldUpdate(newValue)) {
                        chainedValue.assign(transform(newValue));
                    }

                    shouldFreeze(newValue) && chainedValue.freeze();
                }
            });

            return chainedValue;
        },

        map: function(mapFn) {
            return this.chainValue({
                transform: mapFn
            });
        },

        accept: function(acceptFn) {
            return this.chainValue({
                guardUpdate: acceptFn
            });
        },

        $: {
            construct: function(value) {
                this._$handles = Obj();
                // TODO implement with taskqueue
                this._$scheduledChanges = [];

                arguments.length && this.assign(value);
            },

            assign: assignValue,

            '=': assignValue,

            update: function(updater) {
                return this._$scheduleChange(VALUE_UPDATE, updater);
            },

            error: function(newError) {
                isA(newError, Error) || (newError = new TypeError('Expected value.error() to be called with Error object'));

                return this._$scheduleChange(VALUE_ERROR, Fn.partial(identity, newError));
            },

            freeze: function() {
                return this._$scheduleChange(VALUE_FREEZE, noop);
            },

            subscribe: function(subscription) {
                var value = this,
                    subscriptionID = false,
                    onFreeze = subscription.onFreeze;

                async.wait(value.$proxy, 0, value, function delayInitialCall() {
                    Arr.each(changes, function invokeHandleInitial(change) {
                        if (value['_$' + change.counter]) {
                            value._$attemptInvokeHandle(subscription, change.handle, value['_$' + change.key]);
                        }
                    });
                });

                if (!value._$frozen) {
                    subscriptionID = value.getHash() + ' handle_id:' + value._$nextHandleID;

                    value._$nextHandleID++;
                    value._$handlesCount++;

                    subscription.onFreeze = function() {
                        onFreeze && onFreeze.call(subscription);
                        value.unsubscribe(subscriptionID);
                    };

                    value._$handles[subscriptionID] = subscription;
                }

                return subscriptionID;
            },

            unsubscribe: function(subscriptionID) {
                var handles = this._$handles,
                    unsubscribed = false;

                if (hasOwn(handles, subscriptionID)) {
                    this._$handlesCount--;

                    delete handles[subscriptionID];

                    unsubscribed = true;
                }

                return unsubscribed;
            }
        },

        _$: {
            value: null,

            updated: 0,

            error: null,

            errored: 0,

            frozen: 0,

            handles: null,

            handlesCount: 0,

            nextHandleID: 0,
            // TODO implement with taskqueue
            scheduledChanges: null,
            // TODO implement with taskqueue
            changesScheduled: false,
            // TODO implement with taskqueue
            scheduleChange: function(changeType, changer) {
                this._$scheduledChanges.push({
                    type: changeType,

                    fn: changer
                });

                //TODO improve asynchronous handling
                if (!this._$changesScheduled) {
                    async.wait(this.$proxy, 0, this, this._$doChanges);

                    this._$changesScheduled = true;
                }

                return this;
            },
            // TODO implement with taskqueue
            doChanges: function() {
                var value = this,
                    scheduledChanges = value._$scheduledChanges;

                while (scheduledChanges.length && !value._$frozen) {
                    this._$doChange(scheduledChanges.shift());
                }

                this._$changesScheduled = false;
            },
            // TODO implement with taskqueue
            doChange: function(scheduledChange) {
                var value = this,
                    changer = scheduledChange.fn,
                    changeType = scheduledChange.type,
                    change = changes[changeType],
                    handleMethod = change.handle,
                    key = change.key,
                    currentValue = value['_$' + key],
                    newValue = changer(currentValue);

                value._$handles.each(function forwardValueToHandle(handle) {
                    value._$attemptInvokeHandle(handle, handleMethod, newValue);
                });

                if (changeType === VALUE_ERROR && !value._$handlesCount) {
                    value._$onUnhandledError(newValue);
                }

                key && (value['_$' + key] = newValue);

                value['_$' + change.counter]++;
            },

            attemptInvokeHandle: function(handle, handleType, value) {
                var isUnHandledError = false;

                try {
                    if (handle[handleType]) {
                        handle[handleType](value);
                    }
                    else {
                        isUnHandledError = handleType === changes[VALUE_ERROR].handle;
                    }
                }
                catch (e) {
                    if (handle.error) {
                        handle.error(e);
                    }
                    else {
                        value = e;
                        isUnHandledError = true;
                    }
                }

                isUnHandledError && this._$onUnhandledError(value);
            },

            onUnhandledError: function(error) {
                this.Class.logger.error('Unhandled ${name}: ${message} for ${hash}', {
                    name: error.name,

                    message: error.message,

                    hash: this.getHash()
                });
            }
        }
    }, Arr.reduce(changes, addHandleSubscriber, {})));

    function addHandleSubscriber(handleSubscribers, change) {
        var handleName = change.handle;

        handleSubscribers[handleName] = function(handle) {
            var subscription = {};

            subscription[handleName] = handle;

            return this.subscribe(subscription);
        };

        return handleSubscribers;
    }

    function assignValue(newValue) {
        /*jslint validthis: true */
        return this.update(Fn.partial(identity, newValue));
    }

    return Value;
});<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import { fetchUserPosts } from '../../actions/profile/profileActions';
import PostList from './postList/PostList';
import ProfileEdit from './ProfileEdit';
import ProfileDetails from './ProfileDetails';
import styles from './Profile.scss';

class Profile extends React.Component {
  constructor(props, context) {
    super();

    // props.auth.on('profile_updated', (newProfile) => {
    //   this.setState({ profile: newProfile })
    // })
  }

  componentDidMount() {
    const { dispatch } = this.props;
    const profile = JSON.parse(localStorage.getItem('profile'));
    dispatch(fetchUserPosts(profile.user_id));
  };

  render() {
    const {
      posts,
    } = this.props;
    const profile = JSON.parse(localStorage.getItem('profile'));

    return (

{ profile.nickname }'s PostStream

        <ProfileDetails profile={ profile }></ProfileDetails>

        <ProfileEdit profile={ profile } ></ProfileEdit>

        <PostList
          posts={ posts }
        />

    );
  }
};

const mapStateToProps = (state) => {
  return {
    posts: state.root.profile.get('posts').toJS(),
  }
};

export default connect(
  mapStateToProps
)(Profile);
<commit_msg>user profile operational<commit_after>import React from 'react';
import { connect } from 'react-redux';
import { fetchUserPosts } from '../../actions/profile/profileActions';
import PostList from './postList/PostList';
import ProfileEdit from './ProfileEdit';
import ProfileDetails from './ProfileDetails';
import styles from './Profile.scss';

class Profile extends React.Component {
  constructor(props, context) {
    super();

    // props.auth.on('profile_updated', (newProfile) => {
    //   this.setState({ profile: newProfile })
    // })
  }

  componentDidMount() {
    const { dispatch } = this.props;
    const { userName} = this.props.params;
    dispatch(fetchUserPosts(userName));
  };

  render() {
    const {
      posts,
      isAuthenticated,
    } = this.props;
    const profile = JSON.parse(localStorage.getItem('profile'));
    const { userName} = this.props.params;

    return (

{ userName }'s PostStream

        { isAuthenticated &&

            <ProfileDetails profile={ profile }></ProfileDetails>
            <ProfileEdit profile={ profile } ></ProfileEdit>

        }

        <PostList
          posts={ posts }
        />

    );
  }
};

const mapStateToProps = (state) => {
  const { auth } = state.root;
  const { isAuthenticated } = auth

  return {
    isAuthenticated: auth.get('isAuthenticated'),
    posts: state.root.profile.get('posts').toJS(),
  }
};

export default connect(
  mapStateToProps
)(Profile);
<|endoftext|>


<commit_before>

function setup() {
    createCanvas( windowWidth, windowHeight );
}

var headAngle = 0;
var headRotationRate = 0;
var armAngle = 0;
var headWidth = 80;
var headHeight = 40;

function draw() {
    // erase background
    background( 'rgb(56, 177, 255)' );

    // update values
    headRotationRate = (mouseY * 0.1) - 20;
    headAngle = headAngle + headRotationRate;
    armAngle = armAngle - 3;

    push();
    noCursor();
    translate( mouseX, mouseY );

    // arms
    push();
    // right arm
    strokeWeight( 10 );
    stroke( 0 );
    push();
    translate( 60, -40 );
    rotate( radians(armAngle) );
    line( 0, 0, 50, 0 );
    fill( 'rgb(255, 176, 59)' );
    noStroke();
    ellipse( 50, 0, 20 );
    pop();
    line( 10, -20, 60, -40 );

    // left arm
    push();
    translate( -10, -20 );
    rotate( radians( mouseX) );
    line( 0, 0, 150, 0);
    fill( 'rgb(255, 176, 59)' );
    noStroke();
    ellipse( 150, 0, 20 );
    pop();
    pop();

    // body
    ellipse( 0, 0, 40, 100 );

    // head
    push();
    noStroke();
    fill( 'rgb(255, 176, 59)' );
    translate( 0, -60 );
    rotate( radians(headAngle) );
    ellipse( 0, 0, headWidth, headHeight );
    stroke(0);
    fill(255);
    // eyes
    strokeWeight(2);
    push();
    translate( headWidth * -0.2, headHeight * -0.2 );
    ellipse( 0, 0, headWidth * 0.33, headHeight * 0.33 );
    noStroke();
    fill( 'rgb(255, 31, 111)' );
    ellipse( 0, 0, 10 );
    fill( 0 );
    ellipse( 0, 0, 5 );
    pop();
    push();
    translate( headWidth * 0.2, headHeight * -0.2 );
    ellipse( 0, 0, 20 );
    noStroke();
    fill( 'rgb(255, 31, 111)' );
    ellipse( 0, 0, 10 );
    fill( 0 );
    ellipse( 0, 0, 5 );
    pop();
    // mouth
    push();
    fill( 0 );
    arc( 0, headHeight * 0.2, 60, 20, 0, PI );
    pop();
    pop();

    // legs
    fill( 255 );
    noStroke();
    triangle( -15, 35, 5, 35, -40, height+100 );
    triangle( 15, 35, -5, 35, 40, height+100 );

    pop();

}
<commit_msg>small changes<commit_after>/**
 * Creepy Spinning Variable Person
 *
 */

function setup() {
    createCanvas( windowWidth, windowHeight );
}

var headAngle = 0;
var headRotationRate = 0;
var armAngle = 0;
var headWidth = 80;
var headHeight = 40;

function draw() {
    // erase every frame
    background( 'rgb(56, 177, 255)' );
    // turn the cursor off
    noCursor();

    // UPDATE VALUES
    // base head rotation rate on mouseY pos
    headRotationRate = (mouseY * 0.1) - 20;
    // update head angle,
    // to equal itself plus headRotationRate
    headAngle = headAngle + headRotationRate;
    // set the arm to spin at a constant rate
    armAngle = armAngle - 3;

    // *****************************
    // PERSON SANDBOX
    // *****************************
    push();

    // make the person follow the mouse.
    translate( mouseX, mouseY );

    // ARMS
    push();
    // right arm
    strokeWeight( 10 );
    stroke( 0 );
    // draw the spinning forarm
    push();
    // move the position of the arm
    // to facilitate rotation
    translate( 60, -40 );
    // rotate the arm
    rotate( radians(armAngle) );
    // draw the arm
    line( 0, 0, 50, 0 );
    // define and draw a hand-thing
    fill( 'rgb(255, 176, 59)' );
    noStroke();
    ellipse( 50, 0, 20 );
    pop();
    // draw the static upper arm
    line( 10, -20, 60, -40 );

    // left arm
    push();
    // move the center to facilitate rotate
    translate( -10, -20 );
    // rotate, based on mouseX position
    rotate( radians( mouseX) );
    // draw arm and hand
    line( 0, 0, 150, 0);
    fill( 'rgb(255, 176, 59)' );
    noStroke();
    ellipse( 150, 0, 20 );
    pop();
    pop();

    // BODY
    // boring body shape
    ellipse( 0, 0, 40, 100 );

    // HEAD
    push();
    noStroke();
    fill( 'rgb(255, 176, 59)' );
    // move center
    translate( 0, -60 );
    // rotate head based on headAngle
    rotate( radians(headAngle) );
    // draw head skull
    ellipse( 0, 0, headWidth, headHeight );
    stroke(0);
    fill(255);
    // eyes
    strokeWeight(2);
    push();
    // draw eyes based on head size
    translate( headWidth * -0.2, headHeight * -0.2 );
    ellipse( 0, 0, headWidth * 0.33, headHeight * 0.33 );
    noStroke();
    fill( 'rgb(255, 31, 111)' );
    ellipse( 0, 0, 10 );
    fill( 0 );
    ellipse( 0, 0, 5 );
    pop();
    push();
    translate( headWidth * 0.2, headHeight * -0.2 );
    ellipse( 0, 0, 20 );
    noStroke();
    fill( 'rgb(255, 31, 111)' );
    ellipse( 0, 0, 10 );
    fill( 0 );
    ellipse( 0, 0, 5 );
    pop();

    // MOUTH
    push();
    fill( 0 );
    arc( 0, headHeight * 0.2, 60, 20, 0, PI );
    pop();
    pop(); // <- END HEAD

    // LEGS
    fill( 255 );
    noStroke();
    // keep legs out off bottom of window
    triangle( -15, 35, 5, 35, -40, height+100 );
    triangle( 15, 35, -5, 35, 40, height+100 );

    pop(); // <- END PERSON

}
<|endoftext|>


<commit_before>/*global setImmediate:true*/

if (typeof setImmediate === 'undefined') {
    setImmediate = process.nextTick;
}

var BufferedStream = require('bufferedstream'),
    URL = require('url'),
    http = require('http'),
    _ = require('underscore'),
    messy = require('messy');

module.exports = function (expect) {
    expect.addType({
        name: 'messy.Headers',
        equal: function (headers1, headers2) {
            return headers1.equal(headers2);
        },
        identify: function (obj) {
            return obj instanceof messy.Headers;
        },
        inspect: function (output, headers, inspect) {
            headers.getNames().forEach(function (headerName) {
                headers.valuesByName[headerName].forEach(function (headerValue) {
                    output
                        .text(messy.formatHeaderName(headerName + ':'), 'gray')
                        .text(' ')
                        .text(headerValue, 'cyan')
                        .nl();
                });
            });
            return output;
        }
    }).addType({
        name: 'messy.HttpRequest',
        identify: function (obj) {
            return obj instanceof messy.HttpRequest;
        },
        equal: function (httpRequest1, httpRequest2) {
            return httpRequest1.equal(httpRequest2);
        },
        inspect: function (output, httpRequest, inspect) {
            output
                .text(httpRequest.method, 'blue')
                .text(' ')
                .text(httpRequest.url, 'gray')
                .text(' ')
                .text(httpRequest.protocolName, 'blue')
                .text('/')
                .text(httpRequest.protocolVersion, 'cyan')
                .nl();

            inspect(output, httpRequest.headers);
            return output;
        }
    }).addType({
        name: 'messy.HttpResponse',
        equal: function (httpResponse1, httpResponse2) {
            return httpResponse1.equal(httpResponse2);
        },
        identify: function (obj) {
            return obj instanceof messy.HttpResponse;
        },
        inspect: function (output, httpResponse, inspect) {
            output
                .text(httpResponse.protocolName, 'blue')
                .text('/')
                .text(httpResponse.protocolVersion, 'cyan')
                .text(' ')
                .text(httpResponse.statusCode, 'cyan')
                .text(' ')
                .text(httpResponse.statusMessage, 'yellow')
                .nl();
            inspect(output, httpResponse.headers);
            return output;
        }
    });

    expect.addAssertion('to be middleware that processes', function (expect, subject, value, _done) {
        this.errorMode = 'nested';
        expect(_done, 'to be a function');

        var doneCalled = false;

        function done() {
            if (!doneCalled) {
                doneCalled = true;
                return _done.apply(this, arguments);
            }
        }

        var requestProperties = typeof value.request === 'string' ? {url: value.request} : _.extend({}, value.request),
            httpRequest = new messy.HttpRequest({
                url: requestProperties.url,
                method: requestProperties.method,
                headers: requestProperties.headers
            });
        delete value.request;
        delete requestProperties.method;
        delete requestProperties.headers;
        delete requestProperties.url;
        if (typeof httpRequest.url === 'string') {
            var matchMethod = httpRequest.url.match(/^([A-Z]+) ([\s\S]*)$/);
            if (matchMethod) {
                httpRequest.method = httpRequest.method || matchMethod[1];
                httpRequest.url = matchMethod[2];
            }
        }
        httpRequest.method = httpRequest.method || 'GET';
        if (/^https?:\/\//.test(httpRequest.url)) {
            var urlObj = URL.parse(httpRequest.url);
            if (!httpRequest.headers.has('Host')) {
                httpRequest.headers.set('Host', urlObj.host);
            }
            if (urlObj.protocol === 'https:' && typeof requestProperties.https === 'undefined') {
                requestProperties.https = true;
            }
            httpRequest.url = urlObj.path;
        }

        var expectedResponseProperties;

        if (typeof value.response === 'number') {
            expectedResponseProperties = {statusCode: value.response};
        } else if (typeof value.response === 'string' || Buffer.isBuffer(value.response)) {
            expectedResponseProperties = {body: value.response};
        } else {
            expectedResponseProperties = _.extend({}, value.response);
        }
        delete value.response;

        var responseProperties = {},
            requestStream,
            body = requestProperties.body,
            req;

        if (typeof body !== 'undefined') {
            delete requestProperties.body;
            if (body.pipe) {
                requestStream = body;
                if (requestStream.constructor && requestStream.constructor.name === 'FormData') {
                    if (!httpRequest.headers.has('Content-Type')) {
                        httpRequest.headers.set('Content-Type', 'multipart/form-data; boundary=' + requestStream.getBoundary());
                        // form-data pauses its streams by default for some reason:
                        setImmediate(function () {
                            requestStream.resume();
                        });
                    }
                }
                if (!httpRequest.headers.has('Transfer-Encoding')) {
                    httpRequest.headers.set('Transfer-Encoding', 'chunked');
                }
                requestStream.on('data', function (chunk) {
                    req.emit('data', new Buffer(chunk, 'utf-8'));
                }).on('end', function () {
                    req.emit('end');
                }).on('error', function (err) {
                    req.emit('error', err);
                });
            } else {
                if (typeof body === 'object' && !Buffer.isBuffer(body)) {
                    if (!httpRequest.headers.has('Content-Type')) {
                        httpRequest.headers.set('Content-Type', 'application/json');
                    }
                    body = JSON.stringify(body);
                }

                if (!Buffer.isBuffer(body)) {
                    body = new Buffer(String(body), 'utf-8');
                }
                if (!httpRequest.headers.has('Content-Length') && !httpRequest.headers.has('Transfer-Encoding')) {
                    httpRequest.headers.set('Content-Length', String(body.length));
                }
                requestStream = new BufferedStream();
                setImmediate(function () {
                    req.emit('data', body);
                    req.emit('end');
                });
            }
        } else {
            requestStream = new BufferedStream();
            requestStream.destroy = function () {
                responseProperties.requestDestroyed = true;
            };
            setImmediate(function () {
                requestStream.emit('end');
                req.emit('end');
            });
        }

        req = new http.IncomingMessage(requestStream);
        req.connection = req.connection || {};
        req.connection.encrypted = !!requestProperties.https;
        delete requestProperties.https;
        req.connection.remoteAddress = requestProperties.remoteAddress || requestProperties.ip || '127.0.0.1';
        delete requestProperties.ip;
        delete requestProperties.remoteAddress;
        req.headers = {};
        httpRequest.headers.getNames().forEach(function (headerName) {
            if (headerName === 'set-cookie') {
                req.headers[headerName] = [].concat(httpRequest.headers.valuesByName[headerName]);
            } else {
                req.headers[headerName] = httpRequest.headers.valuesByName[headerName].join(', ');
            }
        });
        req.method = httpRequest.method;
        req.url = httpRequest.url;
        _.extend(req, requestProperties);

        var res = new http.ServerResponse(req);
        _.extend(res, requestProperties.res); // Allows for specifying eg. res.locals
        res.connection = new BufferedStream();
        res.connection._httpMessage = res;

        var nextCallCount = 0,
            next = function (err, _req, _res, _next) {
                nextCallCount += 1;
                if (typeof err === 'number') {
                    var statusCode = err;
                    err = new Error('' + statusCode);
                    err.statusCode = statusCode;
                }
                res.statusCode = err && (err.statusCode || err.status) || 404;
                doTheAssertions(err);
            };

        var responseBodyChunks = [],
            isDestroyed = false,
            isAsync = false;

        setImmediate(function () {
            isAsync = true;
        });

        function doTheAssertions(errorPassedToNext) {
            var context = {
                req: req,
                res: res,
                next: next,
                httpRequest: httpRequest,
                metadata: {
                    strictAsync: isAsync,
                    errorPassedToNext: false,
                    isDestroyed: isDestroyed,
                    nextCalled: nextCallCount > 0
                }
            };

            // Apparently setImmediate (or throwing an exception) is not an option here. If we don't call done, errors won't make it into mocha.
            var err = null;
            try {
                if (errorPassedToNext) {
                    context.metadata.errorPassedToNext = errorPassedToNext;
                    if (typeof value.errorPassedToNext !== 'undefined') {
                        if (value.errorPassedToNext === true) {
                            context.metadata.errorPassedToNext = true;
                        } else if (typeof value.errorPassedToNext === 'string') {
                            context.metadata.errorPassedToNext = errorPassedToNext.message;
                        } else {
                            context.metadata.errorPassedToNext = errorPassedToNext;
                        }
                    } else {
                        return setImmediate(function () {
                            done(errorPassedToNext);
                        });
                    }
                }
                var httpResponse = context.httpResponse = new messy.HttpResponse(res._header || undefined); // Avoid a parse error if empty string
                httpResponse.statusCode = res.statusCode;
                httpResponse.body = Buffer.concat(responseBodyChunks.map(function (bufferOrString) {
                    if (!Buffer.isBuffer(bufferOrString)) {
                        return new Buffer(String(bufferOrString), 'utf-8');
                    } else {
                        return bufferOrString;
                    }
                }));

                var httpResponseMatches = httpResponse.satisfies(expectedResponseProperties),
                    headersMatch = httpResponseMatches || httpResponse.headers.satisfy(expectedResponseProperties.headers),
                    bodyMatches = httpResponseMatches || !('body' in expectedResponseProperties) || httpResponse.satisfies({body: expectedResponseProperties.body});

                expect(context.metadata, 'to have properties', value);

                //delete expectedResponseProperties.body;
                // expect(responseProperties, 'to have properties', expectedResponseProperties);
                if (!headersMatch || !bodyMatches) {
                    // console.log(expect.inspect(httpResponse, expect.output.clone()).toString('ansi'));
                }
            } catch (assertionError) {
                err = assertionError;
            }
            setImmediate(function () {
                done(err, context);
            });
        }
        ['write', 'end', 'destroy'].forEach(function (methodName) {
            var orig = res[methodName];
            res[methodName] = function (chunk, encoding) {
                var returnValue = orig.apply(this, arguments);
                if (methodName !== 'destroy') {
                    if (encoding && !/^utf-?8$/i.test(encoding)) {
                        throw new Error('encoding parameter not supported except for "utf-8": ' + encoding);
                    }
                    if (chunk) {
                        responseBodyChunks.push(chunk);
                    }
                }
                if (methodName === 'end' || methodName === 'destroy') {
                    isDestroyed = methodName === 'destroy';
                    doTheAssertions();
                }
                return returnValue;
            };
        });
        subject(req, res, next);
    });
};
<commit_msg>Use httpRequest.body to hold the request body.<commit_after>/*global setImmediate:true*/

if (typeof setImmediate === 'undefined') {
    setImmediate = process.nextTick;
}

var BufferedStream = require('bufferedstream'),
    URL = require('url'),
    http = require('http'),
    _ = require('underscore'),
    messy = require('messy');

module.exports = function (expect) {
    expect.addType({
        name: 'messy.Headers',
        equal: function (headers1, headers2) {
            return headers1.equal(headers2);
        },
        identify: function (obj) {
            return obj instanceof messy.Headers;
        },
        inspect: function (output, headers, inspect) {
            headers.getNames().forEach(function (headerName) {
                headers.valuesByName[headerName].forEach(function (headerValue) {
                    output
                        .text(messy.formatHeaderName(headerName + ':'), 'gray')
                        .text(' ')
                        .text(headerValue, 'cyan')
                        .nl();
                });
            });
            return output;
        }
    }).addType({
        name: 'messy.HttpRequest',
        identify: function (obj) {
            return obj instanceof messy.HttpRequest;
        },
        equal: function (httpRequest1, httpRequest2) {
            return httpRequest1.equal(httpRequest2);
        },
        inspect: function (output, httpRequest, inspect) {
            output
                .text(httpRequest.method, 'blue')
                .text(' ')
                .text(httpRequest.url, 'gray')
                .text(' ')
                .text(httpRequest.protocolName, 'blue')
                .text('/')
                .text(httpRequest.protocolVersion, 'cyan')
                .nl();

            inspect(output, httpRequest.headers);
            return output;
        }
    }).addType({
        name: 'messy.HttpResponse',
        equal: function (httpResponse1, httpResponse2) {
            return httpResponse1.equal(httpResponse2);
        },
        identify: function (obj) {
            return obj instanceof messy.HttpResponse;
        },
        inspect: function (output, httpResponse, inspect) {
            output
                .text(httpResponse.protocolName, 'blue')
                .text('/')
                .text(httpResponse.protocolVersion, 'cyan')
                .text(' ')
                .text(httpResponse.statusCode, 'cyan')
                .text(' ')
                .text(httpResponse.statusMessage, 'yellow')
                .nl();
            inspect(output, httpResponse.headers);
            return output;
        }
    });

    expect.addAssertion('to be middleware that processes', function (expect, subject, value, _done) {
        this.errorMode = 'nested';
        expect(_done, 'to be a function');

        var doneCalled = false;

        function done() {
            if (!doneCalled) {
                doneCalled = true;
                return _done.apply(this, arguments);
            }
        }

        var requestProperties = typeof value.request === 'string' ? {url: value.request} : _.extend({}, value.request),
            httpRequest = new messy.HttpRequest({
                method: requestProperties.method,
                url: requestProperties.url,
                headers: requestProperties.headers,
                body: requestProperties.body
            });
        delete value.request;
        delete requestProperties.method;
        delete requestProperties.url;
        delete requestProperties.headers;
        delete requestProperties.body;
        if (typeof httpRequest.url === 'string') {
            var matchMethod = httpRequest.url.match(/^([A-Z]+) ([\s\S]*)$/);
            if (matchMethod) {
                httpRequest.method = httpRequest.method || matchMethod[1];
                httpRequest.url = matchMethod[2];
            }
        }
        httpRequest.method = httpRequest.method || 'GET';
        if (/^https?:\/\//.test(httpRequest.url)) {
            var urlObj = URL.parse(httpRequest.url);
            if (!httpRequest.headers.has('Host')) {
                httpRequest.headers.set('Host', urlObj.host);
            }
            if (urlObj.protocol === 'https:' && typeof requestProperties.https === 'undefined') {
                requestProperties.https = true;
            }
            httpRequest.url = urlObj.path;
        }

        var expectedResponseProperties;

        if (typeof value.response === 'number') {
            expectedResponseProperties = {statusCode: value.response};
        } else if (typeof value.response === 'string' || Buffer.isBuffer(value.response)) {
            expectedResponseProperties = {body: value.response};
        } else {
            expectedResponseProperties = _.extend({}, value.response);
        }
        delete value.response;

        var responseProperties = {},
            requestStream,
            req;

        if (typeof httpRequest.body !== 'undefined') {
            if (httpRequest.body.pipe) {
                requestStream = httpRequest.body;
                if (requestStream.constructor && requestStream.constructor.name === 'FormData') {
                    if (!httpRequest.headers.has('Content-Type')) {
                        httpRequest.headers.set('Content-Type', 'multipart/form-data; boundary=' + requestStream.getBoundary());
                        // form-data pauses its streams by default for some reason:
                        setImmediate(function () {
                            requestStream.resume();
                        });
                    }
                }
                if (!httpRequest.headers.has('Transfer-Encoding')) {
                    httpRequest.headers.set('Transfer-Encoding', 'chunked');
                }
                requestStream.on('data', function (chunk) {
                    req.emit('data', new Buffer(chunk, 'utf-8'));
                }).on('end', function () {
                    req.emit('end');
                }).on('error', function (err) {
                    req.emit('error', err);
                });
            } else {
                if (typeof httpRequest.body === 'object' && !Buffer.isBuffer(httpRequest.body)) {
                    if (!httpRequest.headers.has('Content-Type')) {
                        httpRequest.headers.set('Content-Type', 'application/json');
                    }
                    httpRequest.body = JSON.stringify(httpRequest.body);
                }

                if (!Buffer.isBuffer(httpRequest.body)) {
                    httpRequest.body = new Buffer(String(httpRequest.body), 'utf-8');
                }
                if (!httpRequest.headers.has('Content-Length') && !httpRequest.headers.has('Transfer-Encoding')) {
                    httpRequest.headers.set('Content-Length', String(httpRequest.body.length));
                }
                requestStream = new BufferedStream();
                setImmediate(function () {
                    req.emit('data', httpRequest.body);
                    req.emit('end');
                });
            }
        } else {
            requestStream = new BufferedStream();
            requestStream.destroy = function () {
                responseProperties.requestDestroyed = true;
            };
            setImmediate(function () {
                requestStream.emit('end');
                req.emit('end');
            });
        }

        req = new http.IncomingMessage(requestStream);
        req.connection = req.connection || {};
        req.connection.encrypted = !!requestProperties.https;
        delete requestProperties.https;
        req.connection.remoteAddress = requestProperties.remoteAddress || requestProperties.ip || '127.0.0.1';
        delete requestProperties.ip;
        delete requestProperties.remoteAddress;
        req.headers = {};
        httpRequest.headers.getNames().forEach(function (headerName) {
            if (headerName === 'set-cookie') {
                req.headers[headerName] = [].concat(httpRequest.headers.valuesByName[headerName]);
            } else {
                req.headers[headerName] = httpRequest.headers.valuesByName[headerName].join(', ');
            }
        });
        req.method = httpRequest.method;
        req.url = httpRequest.url;
        _.extend(req, requestProperties);

        var res = new http.ServerResponse(req);
        _.extend(res, requestProperties.res); // Allows for specifying eg. res.locals
        res.connection = new BufferedStream();
        res.connection._httpMessage = res;

        var nextCallCount = 0,
            next = function (err, _req, _res, _next) {
                nextCallCount += 1;
                if (typeof err === 'number') {
                    var statusCode = err;
                    err = new Error('' + statusCode);
                    err.statusCode = statusCode;
                }
                res.statusCode = err && (err.statusCode || err.status) || 404;
                doTheAssertions(err);
            };

        var responseBodyChunks = [],
            isDestroyed = false,
            isAsync = false;

        setImmediate(function () {
            isAsync = true;
        });

        function doTheAssertions(errorPassedToNext) {
            var context = {
                req: req,
                res: res,
                next: next,
                httpRequest: httpRequest,
                metadata: {
                    strictAsync: isAsync,
                    errorPassedToNext: false,
                    isDestroyed: isDestroyed,
                    nextCalled: nextCallCount > 0
                }
            };

            // Apparently setImmediate (or throwing an exception) is not an option here. If we don't call done, errors won't make it into mocha.
            var err = null;
            try {
                if (errorPassedToNext) {
                    context.metadata.errorPassedToNext = errorPassedToNext;
                    if (typeof value.errorPassedToNext !== 'undefined') {
                        if (value.errorPassedToNext === true) {
                            context.metadata.errorPassedToNext = true;
                        } else if (typeof value.errorPassedToNext === 'string') {
                            context.metadata.errorPassedToNext = errorPassedToNext.message;
                        } else {
                            context.metadata.errorPassedToNext = errorPassedToNext;
                        }
                    } else {
                        return setImmediate(function () {
                            done(errorPassedToNext);
                        });
                    }
                }
                var httpResponse = context.httpResponse = new messy.HttpResponse(res._header || undefined); // Avoid a parse error if empty string
                httpResponse.statusCode = res.statusCode;
                httpResponse.body = Buffer.concat(responseBodyChunks.map(function (bufferOrString) {
                    if (!Buffer.isBuffer(bufferOrString)) {
                        return new Buffer(String(bufferOrString), 'utf-8');
                    } else {
                        return bufferOrString;
                    }
                }));

                var httpResponseMatches = httpResponse.satisfies(expectedResponseProperties),
                    headersMatch = httpResponseMatches || httpResponse.headers.satisfy(expectedResponseProperties.headers),
                    bodyMatches = httpResponseMatches || !('body' in expectedResponseProperties) || httpResponse.satisfies({body: expectedResponseProperties.body});

                expect(context.metadata, 'to have properties', value);

                //delete expectedResponseProperties.body;
                // expect(responseProperties, 'to have properties', expectedResponseProperties);
                if (!headersMatch || !bodyMatches) {
                    // console.log(expect.inspect(httpResponse, expect.output.clone()).toString('ansi'));
                }
            } catch (assertionError) {
                err = assertionError;
            }
            setImmediate(function () {
                done(err, context);
            });
        }
        ['write', 'end', 'destroy'].forEach(function (methodName) {
            var orig = res[methodName];
            res[methodName] = function (chunk, encoding) {
                var returnValue = orig.apply(this, arguments);
                if (methodName !== 'destroy') {
                    if (encoding && !/^utf-?8$/i.test(encoding)) {
                        throw new Error('encoding parameter not supported except for "utf-8": ' + encoding);
                    }
                    if (chunk) {
                        responseBodyChunks.push(chunk);
                    }
                }
                if (methodName === 'end' || methodName === 'destroy') {
                    isDestroyed = methodName === 'destroy';
                    doTheAssertions();
                }
                return returnValue;
            };
        });
        subject(req, res, next);
    });
};
<|endoftext|>