<commit_before>const test = require("tape");

const util = require("./util");

const DEFAULT_TARGET = [
    "one",
    "two",
    "three",
];

test("Test mergeList - null source", function(assert) {
    const source = null;
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = DEFAULT_TARGET;
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - empty source", function(assert) {
    const source = [];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = DEFAULT_TARGET;
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - null target", function(assert) {
    const source = [
        "four",
        "five",
        "six",
    ];
    const merged = util.mergeList(null, source);
    const expected = source;
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - empty target", function(assert) {
    const source = [
        "four",
        "five",
        "six",
    ];
    const merged = util.mergeList([], source);
    const expected = source;
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - null source and target", function(assert) {
    const merged = util.mergeList(null, null);
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify([]),
    );
    assert.end();
});

test("Test mergeList - nothing common", function(assert) {
    const source = [
        "four",
        "five",
        "six",
    ];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = [
        ...DEFAULT_TARGET,
        ...source,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common at beginning", function(assert) {
    const source = [
        "one",
        "four",
        "five",
        "six",
    ];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = [
        ...DEFAULT_TARGET,
        "four",
        "five",
        "six",
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common at the end", function(assert) {
    const source = [
        "four",
        "five",
        "six",
        "one",
    ];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = [
        ...DEFAULT_TARGET,
        "four",
        "five",
        "six",
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common in the middle", function(assert) {
    const source = [
        "four",
        "four",
        "five",
        "six",
    ];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = [
        ...DEFAULT_TARGET,
        ...source,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - different order", function(assert) {
    const source = [
        "three",
        "two",
        "one",
    ];
    const merged = util.mergeList(DEFAULT_TARGET, source);
    const expected = DEFAULT_TARGET;
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});
<commit_msg>Harmonise util tests<commit_after>const test = require("tape");

const util = require("./util");

const DEFAULT_TARGET = [
    "one",
    "two",
    "three",
];

const DEFAULT_SOURCE = [
    "four",
    "five",
    "six",
];

test("Test mergeList - null source", function(assert) {
    const source = null;
    const merged = util.mergeList(
        DEFAULT_TARGET,
        source,
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(DEFAULT_TARGET),
    );
    assert.end();
});

test("Test mergeList - empty source", function(assert) {
    const merged = util.mergeList(
        DEFAULT_TARGET,
        [],
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(DEFAULT_TARGET),
    );
    assert.end();
});

test("Test mergeList - null target", function(assert) {
    const merged = util.mergeList(
        null,
        DEFAULT_SOURCE,
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(DEFAULT_SOURCE),
    );
    assert.end();
});

test("Test mergeList - empty target", function(assert) {
    const merged = util.mergeList(
        [],
        DEFAULT_SOURCE,
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(DEFAULT_SOURCE),
    );
    assert.end();
});

test("Test mergeList - null source and target", function(assert) {
    const merged = util.mergeList(
        null,
        null,
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify([]),
    );
    assert.end();
});

test("Test mergeList - empty source and target", function(assert) {
    const merged = util.mergeList(
        [],
        [],
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify([]),
    );
    assert.end();
});

test("Test mergeList - nothing common", function(assert) {
    const merged = util.mergeList(
        DEFAULT_TARGET,
        DEFAULT_SOURCE,
    );
    const expected = [
        ...DEFAULT_TARGET,
        ...DEFAULT_SOURCE,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common at beginning", function(assert) {
    const source = [
        "one",
        ...DEFAULT_SOURCE,
    ];
    const merged = util.mergeList(
        DEFAULT_TARGET,
        source,
    );
    const expected = [
        ...DEFAULT_TARGET,
        ...DEFAULT_SOURCE,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common at the end", function(assert) {
    const source = [
        ...DEFAULT_SOURCE,
        "one",
    ];
    const merged = util.mergeList(
        DEFAULT_TARGET,
        source,
    );
    const expected = [
        ...DEFAULT_TARGET,
        ...DEFAULT_SOURCE,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - common in the middle", function(assert) {
    const source = [...DEFAULT_SOURCE];
    source.splice(2, 0, "one");
    const merged = util.mergeList(
        DEFAULT_TARGET,
        source,
    );
    const expected = [
        ...DEFAULT_TARGET,
        ...DEFAULT_SOURCE,
    ];
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(expected),
    );
    assert.end();
});

test("Test mergeList - different order", function(assert) {
    const source = [
        "three",
        "two",
        "one",
    ];
    const merged = util.mergeList(
        DEFAULT_TARGET,
        source,
    );
    assert.equal(
        JSON.stringify(merged),
        JSON.stringify(DEFAULT_TARGET),
    );
    assert.end();
});
<|endoftext|>


<commit_before>var expect = require('chai').expect
var md = require('../snarkdown')

describe('snarkdown test suite', function() {
  it('parses bold', function() {
    expect(md.parse('I **like** tiny libraries')).to.be.eql('I like tiny libraries')
  })
})
<commit_msg>Adds tests for the rest of markdown parsing<commit_after>var expect = require('chai').expect
var md = require('../snarkdown')

describe('snarkdown test suite', function () {
  it('parses bold with **', function () {
    expect(md.parse('I **like** tiny libraries')).to.be.eql('I like tiny libraries')
  })

  it('parses bold with __', function () {
    expect(md.parse('I __like__ tiny libraries')).to.be.eql('I like tiny libraries')
  })

  it('parses italics with *', function () {
    expect(md.parse('I *like* tiny libraries')).to.be.eql('I like tiny libraries')
  })

  it('parses italics with _', function () {
    expect(md.parse('I _like_ tiny libraries')).to.be.eql('I like tiny libraries')
  })

  it('parses H1 titles', function () {
    expect(md.parse('# I like tiny libraries')).to.be.eql('
I like tiny libraries
')
  })

  it('parses underlined H1 titles', function () {
    expect(md.parse('I like tiny libraries\n===')).to.be.eql('
I like tiny libraries
')
  })

  it('parses H2 titles', function () {
    expect(md.parse('## I like tiny libraries')).to.be.eql('
I like tiny libraries
')
  })

  it('parses H3 titles', function () {
    expect(md.parse('### I like tiny libraries')).to.be.eql('
I like tiny libraries
')
  })

  it('parses links', function () {
    expect(md.parse('[Snarkdown](http://github.com/developit/snarkdown)')).to.be.eql('Snarkdown')
  })

  it('parses internal links', function () {
    expect(md.parse('[Example](#example)')).to.be.eql('Example')
  })

  it('parses inline code', function () {
    expect(md.parse('Here is some code `var a = 1`.')).to.be.eql('Here is some code var a = 1.')
  })

  it('parses an unordered list with *', function () {
    expect(md.parse('* One\n* Two')).to.be.eql('
\n\t
One
\n\t
Two
\n
')
  })

  it('parses an unordered list with -', function () {
    expect(md.parse('- One\n- Two')).to.be.eql('
\n\t
One
\n\t
Two
\n
')
  })

  it('parses an unordered list with +', function () {
    expect(md.parse('+ One\n+ Two')).to.be.eql('
\n\t
One
\n\t
Two
\n
')
  })

  it('parses an unordered list with mixed bullet point styles', function () {
    expect(md.parse('+ One\n* Two\n- Three')).to.be.eql('
\n\t
One
\n\t
Two
\n\t
Three
\n
')
  })

  it('parses an ordered list', function () {
    expect(md.parse('1. Ordered\n2. Lists\n4. Numbers are ignored')).to.be.eql('
\n\t
Ordered
\n\t
Lists
\n\t
Numbers are ignored
\n
')
  })

  it('parses a block quote', function () {
    expect(md.parse('> To be or not to be')).to.be.eql('
\nTo be or not to be\n
')
  })

  it('parses two new lines as line breaks', function () {
    expect(md.parse('Something with\n\na line break')).to.be.eql('Something with
\n\na line break')
  })

  it('parses two spaces as a line break', function () {
    expect(md.parse('Something with  \na line break')).to.be.eql('Something with
\n\na line break')
  })

  it('parses tabs as a code poetry block', function () {
    expect(md.parse('\tvar a = 1')).to.be.eql('
var a = 1
')
  })

  it('parses three backtricks (```) as a code block', function () {
    expect(md.parse('```\nfunction codeBlocks() {\n\treturn "Can be inserted";\n}\n```')).to.be.eql('
function codeBlocks() {\n\treturn "Can be inserted";\n}
')
  })
})
<|endoftext|>


<commit_before>'use strict';

const childProcess = require('child_process');
const gulp = require('gulp');
const gutil = require('gulp-util');
const webpack = require('webpack');

const config = require('../config');

gulp.task('webpack', (callback) => {

    if (config.watch) {
        runWebpackDevServer();
        return;
    }

    childProcess.spawn('webpack', [], { stdio: 'inherit', env: process.env });
});

const runWebpackDevServer = () => {

    const options = [
        '--inline',
        '--hot',
    ];

    childProcess.spawn('webpack-dev-server', options, { stdio: 'inherit', env: process.env } );
};
<commit_msg>Spawn<commit_after>'use strict';

const gulp = require('gulp');
const gutil = require('gulp-util');
const spawn = require('child_process').spawn;
const webpack = require('webpack');

const config = require('../config');

gulp.task('webpack', (callback) => {

    if (config.watch) {
        runWebpackDevServer();
        return;
    }

    spawn('webpack', [], { stdio: 'inherit', env: process.env })
        .on('close', callback);
});

const runWebpackDevServer = () => {

    const options = [
        '--inline',
        '--hot',
    ];

    spawn('webpack-dev-server', options, { stdio: 'inherit', env: process.env } )
        .on('close', callback);
};
<|endoftext|>


<commit_before>import { expect } from 'chai';
import List from '../src/List';

describe('List.js', () => {
  describe('List.range', () => {
    it('Should return a list of numbers according to the given boundaries', () => {
      expect(List.range(0)).to.deep.equal([]);
      expect(List.range(1)).to.deep.equal([1]);
      expect(List.range(3)).to.deep.equal([1, 2, 3]);
      expect(List.range(10, 8)).to.deep.equal([8, 9, 10]);
      expect(List.range(100, 50).length).to.equal(51);
    });
  });

  describe('List.each', () => {
    it('Should apply a function to each item in a list, not returning any value', () => {
      const input = [1, 2, 3, 4, 5];
      const output = [];
      const expected = [2, 3, 4, 5, 6];
      List.each((x) => output.push(++x), input);
      expect(output).to.deep.equal(expected);
    });
  });

  describe('List.map', () => {
    it('Should apply a function to each item in a list, returning a new list with the result', () => {
      const input = [1, 2, 3, 4, 5];
      expect(List.map((x) => ++x, input)).to.deep.equal([2, 3, 4, 5, 6]);
      expect(List.map((x) => ++x)(input)).to.deep.equal([2, 3, 4, 5, 6]);
    });
  });

  describe('List.compact', () => {
    it('Should return a list of truthy values in a list', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.compact(input)).to.deep.equal([true, 1, 2, 4, 5]);
    });
  });

  describe('List.filter', () => {
    it('Should return the values in a list that satisfy a given predicate', () => {
      const input = [0, 1, 2, 3, 4, 5];
      expect(List.filter((x) => x > 3, input)).to.deep.equal([4, 5]);
    });
  });

  describe('List.reject', () => {
    it('Should return the values in a list that doesn\'t satisfy the given predicate', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.reject((x) => x, input)).to.deep.equal([0, false]);
    });
  });

  describe('List.partition', () => {
    it('Should return a list with two lists containing the passed and failed values given a predicate', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.partition((x) => x, input)).to.deep.equal([[true, 1, 2, 4, 5], [0, false]]);
    });
  });

  describe('List.find', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the exact value in a list that satisfies a given predicate', () => {
      expect(List.find((x) => x === 4, input)).to.equal(4);
    });
    it('Should return the first value in a list that satisfies an ambiguous predicate', () => {
      expect(List.find((x) => x > 2, input)).to.equal(3);
    });
    it('Should return undefined when no value in a list satisfies a given predicate', () => {
      expect(List.find((x) => x === 12, input)).to.equal(undefined);
    });
  });

  describe('List.head', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the first value in a list', () => {
      expect(List.head(input)).to.equal(1);
    });
  });

  describe('List.first (alias => List.head)', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the first value in a list', () => {
      expect(List.first(input)).to.equal(1);
    });
  });

  describe('List.tail', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return all but the first value in a list', () => {
      expect(List.tail(input)).to.deep.equal([2, 3, 4, 5]);
    });
  });

  describe('List.last', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the last value in a list', () => {
      expect(List.last(input)).to.equal(5);
    });
  });

  describe('List.initial', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return all but the last value in a list', () => {
      expect(List.initial(input)).to.deep.equal([1, 2, 3, 4]);
    });
  });

  describe('List.empty', () => {
    it('Should return true for an empty list', () => {
      expect(List.empty([])).to.equal(true);
    });
    it('Should return false for an non-empty list', () => {
      expect(List.empty([1, 2, 3])).to.equal(false);
    });
  });

  describe('List.reverse', () => {
    const input = [1, 2, 0, 5, 4, 3];
    it('Should return the items in a list in a reversed order', () => {
      expect(List.reverse(input)).to.deep.equal([3, 4, 5, 0, 2, 1]);
      expect(List.reverse(input)).to.deep.equal(input.reverse());
    });
  });

  describe('List.uniqueBy', () => {
    it('Should find the unique items in a list given a predicate', () => {
      const input = [
        { color: 'orange' },
        { color: 'green' },
        { color: 'orange' },
        { color: 'blue' },
        { color: 'green' },
        { color: 'orange' }
      ];
      expect(List.uniqueBy((x) => x.color, input)).to.deep.equal(['orange', 'green', 'blue']);
    });
  });

  describe('List.unique', () => {
    it('Should find the unique items in a list', () => {
      const input = [1, 2, 3, 2, 2, 1, 3, 2, 0, 9];
      expect(List.unique(input)).to.deep.equal([1, 2, 3, 0, 9]);
    });
  });

  describe('List.foldl', () => {
    it('Should calculate the sum of items in a list', () => {
      const input = [1, 2, 3, 4, 5, 6, 7, 8, 9];
      expect(List.foldl((x, y) => x + y, 0, input)).to.equal(45);
    });
  });

  describe('List.foldl1', () => {
    it('Should calculate the number of items in a list', () => {
      const input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
      expect(List.foldl1((x) => x + 1, input)).to.equal(10);
    });
  });

  describe('List.foldr', () => {
    it('Should concatenate the letters with the initial value', () => {
      const input = ['h', 'e', 'l', 'l'];
      expect(List.foldr((x, y) => x + y, 'o')(input)).to.equal('hello');
    });
  });

  describe('List.foldr1', () => {
    it('Should calculate the number of items in a list', () => {
      const input = [1, 2, 3, 4, 9];
      expect(List.foldr1((x, y) => x - y, input)).to.equal(7);
    });
  });

  describe('List.concat', () => {
    it('Should concatenate a list of lists into one list', () => {
      const input = [[1, 2], [3], [4, 5]];
      expect(List.concat(input)).to.deep.equal([1, 2, 3, 4, 5]);
    });
  });

  describe('List.concatMap', () => {
    it('Should concatenate a list of lists generated by a function, into one list', () => {
      expect(List.concatMap((x) => [`${x}`, x], [1, 2, 3])).to.deep.equal(['1', 1, '2', 2, '3', 3]);
    });
  });

  describe('List.flatten', () => {
    it('Should flatten a list', () => {
      expect(List.flatten([1, [[2], 3], [4, [[5]]]])).to.deep.equal([1, 2, 3, 4, 5]);
    });
  });

  describe('List.difference', () => {
    it('Should calculate the difference between lists', () => {
      expect(List.difference([1, 2, 3, 4], [1], [4])).to.deep.equal([2, 3]);
      expect(List.difference([1, 2, 3], [2, 1, 3], [3, 1, 2])).to.deep.equal([]);
      expect(List.difference([1, 2, 3], [101, 2, 1, 10], [2, 1], [-1, 0, 1, 2])).to.deep.equal([3]);
      expect(List.difference([1, 2, 3, 4, 5], [5, 2, 10], [9])).to.deep.equal([1, 3, 4]);
    });
  });

  describe('List.intersection', () => {
    it('Should calculate the intersection between lists', () => {
      expect(List.intersection([1, 2, 3], [2, 1, 3], [3, 1, 2])).to.deep.equal([1, 2, 3]);
      expect(List.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1], [-1, 0, 1, 2])).to.deep.equal([1, 2]);
      expect(List.intersection([2, 3], [9, 8], [12, 1], [99])).to.deep.equal([]);
    });
  });

  describe('List.union', () => {
    it('Should calculate the union between lists', () => {
      expect(List.union([1, 2, 3, 4], [2, 4, 5], [9], [])).to.deep.equal([1, 2, 3, 4, 5, 9]);
      expect(List.union([1, 5, 7], [3, 5], [])).to.deep.equal([1, 5, 7, 3]);
    });
  });

  describe('List.countBy', () => {
    it('Should count the occurences by a given predicate', () => {
      expect(List.countBy(Math.floor, [4.2, 4.4, 9.8])).to.deep.equal({ 4: 2, 9: 1 });
      expect(List.countBy((x) => x.length, ['foo', 'bar', 'burp'])).to.deep.equal({ 3: 2, 4: 1 });
      expect(List.countBy((x) => x > 2, [-3, 1, 2, 3, 4, 5])).to.deep.equal({ true: 3, false: 3 });
    });
  });

  describe('List.groupBy', () => {
    it('Should group the matching results by a given predicate', () => {
      expect(List.groupBy(Math.floor, [4.2, 4.4, 9.8])).to.deep.equal({ 4: [4.2, 4.4], 9: [9.8] });
      expect(List.groupBy((x) => x.length, ['one', 'two', 'three'])).to.deep.equal({ 3: ['one', 'two'], 5: ['three'] });
      expect(List.groupBy((x) => x > 2, [-3, 1, 2, 3, 4, 5])).to.deep.equal({ true: [3, 4, 5], false: [-3, 1, 2] });
    });
  });

  describe('List.and', () => {
    it('Should return false if any item in the list is false, otherwise returns true', () => {
      expect(List.and([1, 2, 3])).to.deep.equal(true);
      expect(List.and([3, 2, false])).to.deep.equal(false);
    });
  });

  describe('List.or', () => {
    it('Should return true if any item in the list is true, otherwise returns false', () => {
      expect(List.or([1, 2, 3])).to.deep.equal(true);
      expect(List.or([0, '', null, false])).to.deep.equal(false);
    });
  });

});
<commit_msg>implement tests for List.all<commit_after>import { expect } from 'chai';
import * as List from '../src/List';

describe('List.js', () => {
  describe('List.range', () => {
    it('Should return a list of numbers according to the given boundaries', () => {
      expect(List.range(0)).to.deep.equal([]);
      expect(List.range(1)).to.deep.equal([1]);
      expect(List.range(3)).to.deep.equal([1, 2, 3]);
      expect(List.range(10, 8)).to.deep.equal([8, 9, 10]);
      expect(List.range(100, 50).length).to.equal(51);
    });
  });

  describe('List.each', () => {
    it('Should apply a function to each item in a list, not returning any value', () => {
      const input = [1, 2, 3, 4, 5];
      const output = [];
      const expected = [2, 3, 4, 5, 6];
      List.each((x) => output.push(++x), input);
      expect(output).to.deep.equal(expected);
    });
  });

  describe('List.map', () => {
    it('Should apply a function to each item in a list, returning a new list with the result', () => {
      const input = [1, 2, 3, 4, 5];
      expect(List.map((x) => ++x, input)).to.deep.equal([2, 3, 4, 5, 6]);
      expect(List.map((x) => ++x)(input)).to.deep.equal([2, 3, 4, 5, 6]);
    });
  });

  describe('List.compact', () => {
    it('Should return a list of truthy values in a list', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.compact(input)).to.deep.equal([true, 1, 2, 4, 5]);
    });
  });

  describe('List.filter', () => {
    it('Should return the values in a list that satisfy a given predicate', () => {
      const input = [0, 1, 2, 3, 4, 5];
      expect(List.filter((x) => x > 3, input)).to.deep.equal([4, 5]);
    });
  });

  describe('List.reject', () => {
    it('Should return the values in a list that doesn\'t satisfy the given predicate', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.reject((x) => x, input)).to.deep.equal([0, false]);
    });
  });

  describe('List.partition', () => {
    it('Should return a list with two lists containing the passed and failed values given a predicate', () => {
      const input = [0, true, 1, 2, false, 4, 5];
      expect(List.partition((x) => x, input)).to.deep.equal([[true, 1, 2, 4, 5], [0, false]]);
    });
  });

  describe('List.find', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the exact value in a list that satisfies a given predicate', () => {
      expect(List.find((x) => x === 4, input)).to.equal(4);
    });
    it('Should return the first value in a list that satisfies an ambiguous predicate', () => {
      expect(List.find((x) => x > 2, input)).to.equal(3);
    });
    it('Should return undefined when no value in a list satisfies a given predicate', () => {
      expect(List.find((x) => x === 12, input)).to.equal(undefined);
    });
  });

  describe('List.head', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the first value in a list', () => {
      expect(List.head(input)).to.equal(1);
    });
  });

  describe('List.first (alias => List.head)', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the first value in a list', () => {
      expect(List.first(input)).to.equal(1);
    });
  });

  describe('List.tail', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return all but the first value in a list', () => {
      expect(List.tail(input)).to.deep.equal([2, 3, 4, 5]);
    });
  });

  describe('List.last', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return the last value in a list', () => {
      expect(List.last(input)).to.equal(5);
    });
  });

  describe('List.initial', () => {
    const input = [1, 2, 3, 4, 5];
    it('Should return all but the last value in a list', () => {
      expect(List.initial(input)).to.deep.equal([1, 2, 3, 4]);
    });
  });

  describe('List.empty', () => {
    it('Should return true for an empty list', () => {
      expect(List.empty([])).to.equal(true);
    });
    it('Should return false for an non-empty list', () => {
      expect(List.empty([1, 2, 3])).to.equal(false);
    });
  });

  describe('List.reverse', () => {
    const input = [1, 2, 0, 5, 4, 3];
    it('Should return the items in a list in a reversed order', () => {
      expect(List.reverse(input)).to.deep.equal([3, 4, 5, 0, 2, 1]);
      expect(List.reverse(input)).to.deep.equal(input.reverse());
    });
  });

  describe('List.uniqueBy', () => {
    it('Should find the unique items in a list given a predicate', () => {
      const input = [
        { color: 'orange' },
        { color: 'green' },
        { color: 'orange' },
        { color: 'blue' },
        { color: 'green' },
        { color: 'orange' }
      ];
      expect(List.uniqueBy((x) => x.color, input)).to.deep.equal(['orange', 'green', 'blue']);
    });
  });

  describe('List.unique', () => {
    it('Should find the unique items in a list', () => {
      const input = [1, 2, 3, 2, 2, 1, 3, 2, 0, 9];
      expect(List.unique(input)).to.deep.equal([1, 2, 3, 0, 9]);
    });
  });

  describe('List.foldl', () => {
    it('Should calculate the sum of items in a list', () => {
      const input = [1, 2, 3, 4, 5, 6, 7, 8, 9];
      expect(List.foldl((x, y) => x + y, 0, input)).to.equal(45);
    });
  });

  describe('List.foldl1', () => {
    it('Should calculate the number of items in a list', () => {
      const input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
      expect(List.foldl1((x) => x + 1, input)).to.equal(10);
    });
  });

  describe('List.foldr', () => {
    it('Should concatenate the letters with the initial value', () => {
      const input = ['h', 'e', 'l', 'l'];
      expect(List.foldr((x, y) => x + y, 'o')(input)).to.equal('hello');
    });
  });

  describe('List.foldr1', () => {
    it('Should calculate the number of items in a list', () => {
      const input = [1, 2, 3, 4, 9];
      expect(List.foldr1((x, y) => x - y, input)).to.equal(7);
    });
  });

  describe('List.concat', () => {
    it('Should concatenate a list of lists into one list', () => {
      const input = [[1, 2], [3], [4, 5]];
      expect(List.concat(input)).to.deep.equal([1, 2, 3, 4, 5]);
    });
  });

  describe('List.concatMap', () => {
    it('Should concatenate a list of lists generated by a function, into one list', () => {
      expect(List.concatMap((x) => [`${x}`, x], [1, 2, 3])).to.deep.equal(['1', 1, '2', 2, '3', 3]);
    });
  });

  describe('List.flatten', () => {
    it('Should flatten a list', () => {
      expect(List.flatten([1, [[2], 3], [4, [[5]]]])).to.deep.equal([1, 2, 3, 4, 5]);
    });
  });

  describe('List.difference', () => {
    it('Should calculate the difference between lists', () => {
      expect(List.difference([1, 2, 3, 4], [1], [4])).to.deep.equal([2, 3]);
      expect(List.difference([1, 2, 3], [2, 1, 3], [3, 1, 2])).to.deep.equal([]);
      expect(List.difference([1, 2, 3], [101, 2, 1, 10], [2, 1], [-1, 0, 1, 2])).to.deep.equal([3]);
      expect(List.difference([1, 2, 3, 4, 5], [5, 2, 10], [9])).to.deep.equal([1, 3, 4]);
    });
  });

  describe('List.intersection', () => {
    it('Should calculate the intersection between lists', () => {
      expect(List.intersection([1, 2, 3], [2, 1, 3], [3, 1, 2])).to.deep.equal([1, 2, 3]);
      expect(List.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1], [-1, 0, 1, 2])).to.deep.equal([1, 2]);
      expect(List.intersection([2, 3], [9, 8], [12, 1], [99])).to.deep.equal([]);
    });
  });

  describe('List.union', () => {
    it('Should calculate the union between lists', () => {
      expect(List.union([1, 2, 3, 4], [2, 4, 5], [9], [])).to.deep.equal([1, 2, 3, 4, 5, 9]);
      expect(List.union([1, 5, 7], [3, 5], [])).to.deep.equal([1, 5, 7, 3]);
    });
  });

  describe('List.countBy', () => {
    it('Should count the occurences by a given predicate', () => {
      expect(List.countBy(Math.floor, [4.2, 4.4, 9.8])).to.deep.equal({ 4: 2, 9: 1 });
      expect(List.countBy((x) => x.length, ['foo', 'bar', 'burp'])).to.deep.equal({ 3: 2, 4: 1 });
      expect(List.countBy((x) => x > 2, [-3, 1, 2, 3, 4, 5])).to.deep.equal({ true: 3, false: 3 });
    });
  });

  describe('List.groupBy', () => {
    it('Should group the matching results by a given predicate', () => {
      expect(List.groupBy(Math.floor, [4.2, 4.4, 9.8])).to.deep.equal({ 4: [4.2, 4.4], 9: [9.8] });
      expect(List.groupBy((x) => x.length, ['one', 'two', 'three'])).to.deep.equal({ 3: ['one', 'two'], 5: ['three'] });
      expect(List.groupBy((x) => x > 2, [-3, 1, 2, 3, 4, 5])).to.deep.equal({ true: [3, 4, 5], false: [-3, 1, 2] });
    });
  });

  describe('List.and', () => {
    it('Should return false if any item in the list is false, otherwise returns true', () => {
      expect(List.and([1, 2, 3])).to.equal(true);
      expect(List.and([3, 2, false])).to.equal(false);
    });
  });

  describe('List.or', () => {
    it('Should return true if any item in the list is true, otherwise returns false', () => {
      expect(List.or([1, 2, 3])).to.deep.equal(true);
      expect(List.or([0, '', null, false])).to.equal(false);
    });
  });

  describe('List.any', () => {
    it('Should return true true on the first item that satisfies the predicate', () => {
      expect(List.any((x) => x > 2, [1, 2, 3])).to.equal(true);
      expect(List.any((x) => x.length > 3, ['foo', 'bar', 'buzz'])).to.deep.equal(true);
      expect(List.any((x) => x.length < 3, ['foo', 'bar', 'buzz'])).to.deep.equal(false);
    });
  });

  describe('List.all', () => {
    it('Should return true true on the first item that does not satisfy the predicate', () => {
      expect(List.all((x) => x, [1, 2, 3])).to.equal(false);
      expect(List.all((x) => x.length > 3, ['foo', 'bar', 'buzz'])).to.equal(false);
    });
  });

});
<|endoftext|>


<commit_before>V.rt("#if", function(handle, index, parentHandle) {
    // console.log(handle)
    var id = handle.id,
        ignoreHandleType = /handle|comment/,
        conditionHandleId = handle.childNodes[0].id,
        parentHandleId = parentHandle.id,

        comment_else_id, //#if inserBefore #else
        comment_endif_id, //#else inserBefore /if

        conditionDOM = handle._controllers,
        conditionStatus = $TRUE, //the #if block scope
        trigger,
        deep = 0;

    $.e(parentHandle.childNodes, function(child_handle, i, childHandles) {
        if (child_handle.handleName === "#if") {
            deep += 1
        } else if (child_handle.handleName === "#else") {
            if (deep === 1) {
                conditionStatus = !conditionStatus;
                comment_else_id = $.lI(child_handle.childNodes).id;
            }
        } else if (child_handle.handleName === "/if") {
            deep -= 1
            if (!deep) {
                comment_endif_id = $.lI(child_handle.childNodes).id;
                return $FALSE;
            }
        } else if (child_handle.type !== "comment") {
            //保存这个节点的控制器，可能有多个if-else嵌套
            $.p(child_handle._controllers, id);
            $.p(conditionDOM[conditionStatus], child_handle.id);
        }
    }, index); // no (index + 1):scan itself:deep === 0 --> conditionStatus = !conditionStatus;

    trigger = {
        // key:"",//default is ""
        event: function(NodeList_of_ViewModel, model, /*triggerBy,*/ isAttr, viewModel_ID) {
            //要显示的类型，true为if-else，false为else-endif
            var conditionVal = !! NodeList_of_ViewModel[conditionHandleId]._data,
                parentNode = NodeList_of_ViewModel[parentHandleId].currentNode,
                markHandleId = comment_else_id, //if(true)
                markHandle; //default is undefined --> insertBefore === appendChild

            if (NodeList_of_ViewModel[this.handleId]._data !== conditionVal /*|| triggerBy*/ ) {
                NodeList_of_ViewModel[this.handleId]._data = conditionVal;
                if (!conditionVal) {
                    markHandleId = comment_endif_id;
                }
                if (markHandleId) {
                    markHandle = NodeList_of_ViewModel[markHandleId].currentNode;
                }

                //显示
                $.e(conditionDOM[conditionVal], function(id) {
                    var currentHandle = NodeList_of_ViewModel[id],
                        node = currentHandle.currentNode,
                        placeholderNode = NodeList_of_ViewModel[id].placeholderNode || (NodeList_of_ViewModel[id].placeholderNode = $.D.C(id)),
                        display = $TRUE;

                    //遍历所有逻辑控制器（if-else语句-ENDIF）来确定每个控制器是否允许显示它。
                    $.e(currentHandle._controllers, function(controller_id) {
                        //Traverse all Logic Controller(if-else-endif) to determine whether each Controller are allowed to display it.
                        var controllerHandle = NodeList_of_ViewModel[controller_id]
                        //控制器中的显示时候包含当前元素
                        return display = display && ($.iO(controllerHandle._controllers[!!controllerHandle._data], currentHandle.id) !== -1);
                        //when display is false,abort traversing
                    });
                    if (display) {
                        if (currentHandle.display) { //Custom Display Function,default is false
                            currentHandle.display($TRUE, NodeList_of_ViewModel, model, /*triggerBy, */ viewModel_ID)
                        } else if (node && placeholderNode.parentNode === parentNode) {
                            //parentNode.replaceChild(node/*new*/, placeholderNode/*old*/)
                            $.D.re(parentNode, node, placeholderNode)
                        }
                    }
                });

                //隐藏
                $.e(conditionDOM[!conditionVal], function(id) {
                    var currentHandle = NodeList_of_ViewModel[id],
                        node = currentHandle.currentNode,
                        placeholderNode = (currentHandle.placeholderNode = currentHandle.placeholderNode || $.D.C(id));

                    if (currentHandle.display) { //Custom Display Function,default is false
                        currentHandle.display($FALSE, NodeList_of_ViewModel, model, /*triggerBy,*/ viewModel_ID)
                    } else if (node && node.parentNode === parentNode) {
                        //parentNode.replaceChild(placeholderNode/*new*/, node/*old*/)
                        $.D.re(parentNode, placeholderNode, node)
                    }
                })
            }
        }
    }

    return trigger;
});
<commit_msg>为if加入PrimitiveValue的获取功能<commit_after>V.rt("#if", function(handle, index, parentHandle) {
    // console.log(handle)
    var id = handle.id,
        ignoreHandleType = /handle|comment/,
        conditionHandleId = handle.childNodes[0].id,
        parentHandleId = parentHandle.id,

        comment_else_id, //#if inserBefore #else
        comment_endif_id, //#else inserBefore /if

        conditionDOM = handle._controllers,
        conditionStatus = $TRUE, //the #if block scope
        trigger,
        deep = 0;

    $.e(parentHandle.childNodes, function(child_handle, i, childHandles) {
        if (child_handle.handleName === "#if") {
            deep += 1
        } else if (child_handle.handleName === "#else") {
            if (deep === 1) {
                conditionStatus = !conditionStatus;
                comment_else_id = $.lI(child_handle.childNodes).id;
            }
        } else if (child_handle.handleName === "/if") {
            deep -= 1
            if (!deep) {
                comment_endif_id = $.lI(child_handle.childNodes).id;
                return $FALSE;
            }
        } else if (child_handle.type !== "comment") {
            //保存这个节点的控制器，可能有多个if-else嵌套
            $.p(child_handle._controllers, id);
            $.p(conditionDOM[conditionStatus], child_handle.id);
        }
    }, index); // no (index + 1):scan itself:deep === 0 --> conditionStatus = !conditionStatus;

    trigger = {
        // key:"",//default is ""
        event: function(NodeList_of_ViewModel, model, /*triggerBy,*/ isAttr, viewModel_ID) {
            //要显示的类型，true为if-else，false为else-endif
            var conditionVal = NodeList_of_ViewModel[conditionHandleId]._data,
                parentNode = NodeList_of_ViewModel[parentHandleId].currentNode,
                markHandleId = comment_else_id, //if(true)
                markHandle; //default is undefined --> insertBefore === appendChild

            //获取PrimitiveValue
            conditionVal && (conditionVal = conditionVal.valueOf());
            //转化为Boolean值
            conditionVal = !! conditionVal;

            if (NodeList_of_ViewModel[this.handleId]._data !== conditionVal /*|| triggerBy*/ ) {
                NodeList_of_ViewModel[this.handleId]._data = conditionVal;
                if (!conditionVal) {
                    markHandleId = comment_endif_id;
                }
                if (markHandleId) {
                    markHandle = NodeList_of_ViewModel[markHandleId].currentNode;
                }

                //显示
                $.e(conditionDOM[conditionVal], function(id) {
                    var currentHandle = NodeList_of_ViewModel[id],
                        node = currentHandle.currentNode,
                        placeholderNode = NodeList_of_ViewModel[id].placeholderNode || (NodeList_of_ViewModel[id].placeholderNode = $.D.C(id)),
                        display = $TRUE;

                    //遍历所有逻辑控制器（if-else语句-ENDIF）来确定每个控制器是否允许显示它。
                    $.e(currentHandle._controllers, function(controller_id) {
                        //Traverse all Logic Controller(if-else-endif) to determine whether each Controller are allowed to display it.
                        var controllerHandle = NodeList_of_ViewModel[controller_id]
                        //控制器中的显示时候包含当前元素
                        return display = display && ($.iO(controllerHandle._controllers[ !! controllerHandle._data], currentHandle.id) !== -1);
                        //when display is false,abort traversing
                    });
                    if (display) {
                        if (currentHandle.display) { //Custom Display Function,default is false
                            currentHandle.display($TRUE, NodeList_of_ViewModel, model, /*triggerBy, */ viewModel_ID)
                        } else if (node && placeholderNode.parentNode === parentNode) {
                            //parentNode.replaceChild(node/*new*/, placeholderNode/*old*/)
                            $.D.re(parentNode, node, placeholderNode)
                        }
                    }
                });

                //隐藏
                $.e(conditionDOM[!conditionVal], function(id) {
                    var currentHandle = NodeList_of_ViewModel[id],
                        node = currentHandle.currentNode,
                        placeholderNode = (currentHandle.placeholderNode = currentHandle.placeholderNode || $.D.C(id));

                    if (currentHandle.display) { //Custom Display Function,default is false
                        currentHandle.display($FALSE, NodeList_of_ViewModel, model, /*triggerBy,*/ viewModel_ID)
                    } else if (node && node.parentNode === parentNode) {
                        //parentNode.replaceChild(placeholderNode/*new*/, node/*old*/)
                        $.D.re(parentNode, placeholderNode, node)
                    }
                })
            }
        }
    }

    return trigger;
});
<|endoftext|>


<commit_before>import {Map} from "immutable";
import moment from "moment";
import {last} from "ramda";
import React, {Component, PropTypes} from "react";
import IPropTypes from "react-immutable-proptypes";
import {Dimensions, View, StyleSheet, Switch} from "react-native";
import shallowCompare from "react-addons-shallow-compare";

import getDailySumConsumption from "../lib/get-daily-sum-consumption";
import Highcharts from "./highcharts";
import Text from "./text-lato";
import * as colors from "../lib/colors";

const styles = StyleSheet.create({
    consumptionContainer: {
        flexDirection: "row",
        justifyContent: "space-around",
        paddingTop: 20
    },
    powerContainer: {
        flexDirection: "column"
    },
    summaryConsumptionContainer: {
        flexDirection: "column"
    },
    summaryConsumption: {
        flexDirection: "row",
        margin: 10
    },
    consumptionNumber: {
        paddingRight: 5,
        fontSize: 30,
        fontWeight: "bold",
        textAlign: "center",
        color: colors.primaryBlue
    },
    consumptionUnitOfMeasurement: {
        marginTop: 10,
        color: colors.primaryBlue
    },
    powerNumber: {
        fontSize: 30,
        textAlign: "center",
        fontWeight: "bold",
        color: colors.powerNumber
    },
    powerUnitOfMeasurement: {
        color: colors.powerNumber,
        textAlign: "center"
    },
    switch: {
        alignSelf: "flex-start",
        marginTop: 3,
        marginLeft: 10
    },
    switchContainer: {
        flexDirection: "row"
    },
    switchTextContainer: {
        flexDirection: "column",
        marginLeft: 10
    },
    switchTextHeader: {
        fontWeight: "bold"
    },
    switchText: {
        fontSize: 12
    }
});

export default class ChartConsumption extends Component {

    static propTypes = {
        charts: PropTypes.arrayOf(PropTypes.shape({
            sensorId: PropTypes.string,
            source: PropTypes.string,
            measurementType: PropTypes.string,
            day: PropTypes.string
        })).isRequired,
        consumptionAggregates:IPropTypes.map,
        dailyAggregates: IPropTypes.map,
        onToggleSwitch: PropTypes.func.isRequired
    }

    shouldComponentUpdate (nextProps) {
        return shallowCompare(this, nextProps);
    }

    getSummaryConsumption () {
        const dayOfYear = moment.utc().dayOfYear();
        const sensorId = this.props.charts[0].sensorId;
        const year = moment.utc().format("YYYY");
        const source = "reading";
        const measurementType = "activeEnergy";
        return getDailySumConsumption(
            this.props.consumptionAggregates,
            {sensorId, year, source, measurementType},
            dayOfYear
        );
    }

    getRealTimePower () {
        const sensorId = this.props.charts[0].sensorId;
        const day = moment.utc().format("YYYY-MM-DD");
        console.log(`${sensorId}-${day}-reading-maxPower`);
        const powerValues = this.props.dailyAggregates.getIn([`${sensorId}-${day}-reading-maxPower`, "measurementValues"]) || "";
        const power = last(powerValues.split(","));
        return parseFloat(power) || 0;
    }

    render () {
        const {height} = Dimensions.get("window");
        return (
            <View>
                <View style={[styles.consumptionContainer, {height: height * 0.2}]}>
                    <View style={styles.summaryConsumptionContainer}>
                        <Text>{"Consumo di oggi"}</Text>
                        <View style={styles.summaryConsumption}>
                            <Text style={styles.consumptionNumber}>{this.getSummaryConsumption().toFixed(1)}</Text>
                            <Text style={styles.consumptionUnitOfMeasurement}>{"kWh"}</Text>
                        </View>
                    </View>
                    <View style={styles.powerContainer}>
                        <Text>{"Potenza attuale"}</Text>
                        <Text style={styles.powerNumber}>{this.getRealTimePower().toFixed(1)}</Text>
                        <Text style={styles.powerUnitOfMeasurement}>{"kW"}</Text>
                    </View>
                </View>
                <Highcharts
                    aggregates={this.props.dailyAggregates}
                    charts={this.props.charts}
                    height={height * 0.2}
                />
                <View style={styles.switchContainer}>
                    <Switch
                        onValueChange={this.props.onToggleSwitch}
                        style={styles.switch}
                        value={this.props.charts.length === 2}
                    />
                    <View style={styles.switchTextContainer}>
                        <Text style={styles.switchTextHeader}>{"Consumi previsti"}</Text>
                        <Text style={styles.switchText}>{"basati sulla tua giornata tipo"}</Text>
                    </View>
                </View>
            </View>
        );
    }

}
<commit_msg>Fixed lint<commit_after>import moment from "moment";
import {last} from "ramda";
import React, {Component, PropTypes} from "react";
import IPropTypes from "react-immutable-proptypes";
import {Dimensions, View, StyleSheet, Switch} from "react-native";
import shallowCompare from "react-addons-shallow-compare";

import getDailySumConsumption from "../lib/get-daily-sum-consumption";
import Highcharts from "./highcharts";
import Text from "./text-lato";
import * as colors from "../lib/colors";

const styles = StyleSheet.create({
    consumptionContainer: {
        flexDirection: "row",
        justifyContent: "space-around",
        paddingTop: 20
    },
    powerContainer: {
        flexDirection: "column"
    },
    summaryConsumptionContainer: {
        flexDirection: "column"
    },
    summaryConsumption: {
        flexDirection: "row",
        margin: 10
    },
    consumptionNumber: {
        paddingRight: 5,
        fontSize: 30,
        fontWeight: "bold",
        textAlign: "center",
        color: colors.primaryBlue
    },
    consumptionUnitOfMeasurement: {
        marginTop: 10,
        color: colors.primaryBlue
    },
    powerNumber: {
        fontSize: 30,
        textAlign: "center",
        fontWeight: "bold",
        color: colors.powerNumber
    },
    powerUnitOfMeasurement: {
        color: colors.powerNumber,
        textAlign: "center"
    },
    switch: {
        alignSelf: "flex-start",
        marginTop: 3,
        marginLeft: 10
    },
    switchContainer: {
        flexDirection: "row"
    },
    switchTextContainer: {
        flexDirection: "column",
        marginLeft: 10
    },
    switchTextHeader: {
        fontWeight: "bold"
    },
    switchText: {
        fontSize: 12
    }
});

export default class ChartConsumption extends Component {

    static propTypes = {
        charts: PropTypes.arrayOf(PropTypes.shape({
            sensorId: PropTypes.string,
            source: PropTypes.string,
            measurementType: PropTypes.string,
            day: PropTypes.string
        })).isRequired,
        consumptionAggregates:IPropTypes.map,
        dailyAggregates: IPropTypes.map,
        onToggleSwitch: PropTypes.func.isRequired
    }

    shouldComponentUpdate (nextProps) {
        return shallowCompare(this, nextProps);
    }

    getSummaryConsumption () {
        const dayOfYear = moment.utc().dayOfYear();
        const sensorId = this.props.charts[0].sensorId;
        const year = moment.utc().format("YYYY");
        const source = "reading";
        const measurementType = "activeEnergy";
        return getDailySumConsumption(
            this.props.consumptionAggregates,
            {sensorId, year, source, measurementType},
            dayOfYear
        );
    }

    getRealTimePower () {
        const sensorId = this.props.charts[0].sensorId;
        const day = moment.utc().format("YYYY-MM-DD");
        console.log(`${sensorId}-${day}-reading-maxPower`);
        const powerValues = this.props.dailyAggregates.getIn([`${sensorId}-${day}-reading-maxPower`, "measurementValues"]) || "";
        const power = last(powerValues.split(","));
        return parseFloat(power) || 0;
    }

    render () {
        const {height} = Dimensions.get("window");
        return (
            <View>
                <View style={[styles.consumptionContainer, {height: height * 0.2}]}>
                    <View style={styles.summaryConsumptionContainer}>
                        <Text>{"Consumo di oggi"}</Text>
                        <View style={styles.summaryConsumption}>
                            <Text style={styles.consumptionNumber}>{this.getSummaryConsumption().toFixed(1)}</Text>
                            <Text style={styles.consumptionUnitOfMeasurement}>{"kWh"}</Text>
                        </View>
                    </View>
                    <View style={styles.powerContainer}>
                        <Text>{"Potenza attuale"}</Text>
                        <Text style={styles.powerNumber}>{this.getRealTimePower().toFixed(1)}</Text>
                        <Text style={styles.powerUnitOfMeasurement}>{"kW"}</Text>
                    </View>
                </View>
                <Highcharts
                    aggregates={this.props.dailyAggregates}
                    charts={this.props.charts}
                    height={height * 0.2}
                />
                <View style={styles.switchContainer}>
                    <Switch
                        onValueChange={this.props.onToggleSwitch}
                        style={styles.switch}
                        value={this.props.charts.length === 2}
                    />
                    <View style={styles.switchTextContainer}>
                        <Text style={styles.switchTextHeader}>{"Consumi previsti"}</Text>
                        <Text style={styles.switchText}>{"basati sulla tua giornata tipo"}</Text>
                    </View>
                </View>
            </View>
        );
    }

}
<|endoftext|>


<commit_before>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk),
                Victor Nakoryakov (victor@amperka.ru)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Wrap whole code in `onInit` function before send and save() it
  after upload. Wrapping is necessary to avoid execution start
  before save() is executed
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  function init() {
    Espruino.Core.Config.add("SAVE_ON_SEND", {
      section : "Communications",
      name : "Save on Send",
      descriptionHTML : 'How should code be uploaded? See espruino.com/Saving for more information.
'+
                        "NOTE: Avoid 'Direct to flash, even after reset()' for normal development - it can make it hard to recover if your code crashes the device.",
      type : {
        0: "To RAM (default) - execute code while uploading. Use 'save()' to save a RAM image to Flash",
        1: "Direct to Flash (execute code at boot)",
        2: "Direct to Flash (execute code at boot, even after 'reset()') - USE WITH CARE",
        3: "To Storage File (see 'File in Storage to send to')",
      },
      defaultValue : 0
    });
    Espruino.Core.Config.add("SAVE_STORAGE_FILE", {
      section : "Communications",
      name : "File in Storage to send to",
      descriptionHTML : "If Save on Send is set to To Storage File, this is the name of the file to write to.",
      type : "string",
      defaultValue : ""
    });
    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      wrap(code, callback);
    });
  }

  function wrap(code, callback) {
    var isFlashPersistent = Espruino.Config.SAVE_ON_SEND == 2;
    var isStorageUpload = Espruino.Config.SAVE_ON_SEND == 3;
    var isFlashUpload = Espruino.Config.SAVE_ON_SEND == 1 || isFlashPersistent || isStorageUpload;
    if (!isFlashUpload) return callback(code);

    // Check environment vars
    var hasStorage = false;
    var ENV = Espruino.Core.Env.getData();
    if (ENV &&
        ENV.VERSION_MAJOR &&
        ENV.VERSION_MINOR!==undefined) {
      if (ENV.VERSION_MAJOR>1 ||
          ENV.VERSION_MINOR>=96) {
        hasStorage = true;
      }
    }

    //
    console.log("Uploading "+code.length+" bytes to flash");
    if (!hasStorage) { // old style
      if (isStorageUpload) {
        Espruino.Core.Notifications.error("You have pre-1v96 firmware - unable to upload to Storage");
        code = "";
      } else {
        Espruino.Core.Notifications.error("You have pre-1v96 firmware. Upload size is limited by available RAM");
        code = "E.setBootCode("+JSON.stringify(code)+(isFlashPersistent?",true":"")+");load()\n";
      }
    } else { // new style
      var filename;
      if (isStorageUpload)
        filename = Espruino.Config.SAVE_STORAGE_FILE;
      else
        filename = isFlashPersistent ? ".bootrst" : ".bootcde";
      if (!filename || filename.length>8) {
        Espruino.Core.Notifications.error("Invalid Storage file name "+JSON.stringify(filename));
        code = "";
      } else {
        var CHUNKSIZE = 1024;
        var newCode = [];
        var len = code.length;
        newCode.push('require("Storage").write("'+filename+'",'+JSON.stringify(code.substr(0,CHUNKSIZE))+',0,'+len+');');
        for (var i=CHUNKSIZE;i<len;i+=CHUNKSIZE)
          newCode.push('require("Storage").write("'+filename+'",'+JSON.stringify(code.substr(i,CHUNKSIZE))+','+i+');');
        code = newCode.join("\n");
        if (isStorageUpload)
          code += "\nload("+JSON.stringify(filename)+")\n";
        else
          code += "\nload()\n";
      }
    }
    callback(code);
  }

  Espruino.Plugins.SaveOnSend = {
    init : init,
  };
}());
<commit_msg>Add option for what happens after send - do we load the file or not?<commit_after>/**
 Copyright 2014 Gordon Williams (gw@pur3.co.uk),
                Victor Nakoryakov (victor@amperka.ru)

 This Source Code is subject to the terms of the Mozilla Public
 License, v2.0. If a copy of the MPL was not distributed with this
 file, You can obtain one at http://mozilla.org/MPL/2.0/.

 ------------------------------------------------------------------
  Wrap whole code in `onInit` function before send and save() it
  after upload. Wrapping is necessary to avoid execution start
  before save() is executed
 ------------------------------------------------------------------
**/
"use strict";
(function(){

  function init() {
    Espruino.Core.Config.add("SAVE_ON_SEND", {
      section : "Communications",
      name : "Save on Send",
      descriptionHTML : 'How should code be uploaded? See espruino.com/Saving for more information.
'+
                        "NOTE: Avoid 'Direct to flash, even after reset()' for normal development - it can make it hard to recover if your code crashes the device.",
      type : {
        0: "To RAM (default) - execute code while uploading. Use 'save()' to save a RAM image to Flash",
        1: "Direct to Flash (execute code at boot)",
        2: "Direct to Flash (execute code at boot, even after 'reset()') - USE WITH CARE",
        3: "To Storage File (see 'File in Storage to send to')",
      },
      defaultValue : 0
    });
    Espruino.Core.Config.add("SAVE_STORAGE_FILE", {
      section : "Communications",
      name : "Send to File in Storage",
      descriptionHTML : "If Save on Send is set to To Storage File, this is the name of the file to write to.",
      type : "string",
      defaultValue : "myapp"
    });
    Espruino.Core.Config.add("LOAD_STORAGE_FILE", {
      section : "Communications",
      name : "Load after saving",
      descriptionHTML : "This applies only if saving to Flash (not RAM)",
      type : {
        0: "Don't load",
        1: "Load default application",
        2: "Load the Storage File just written to"
      },
      defaultValue : 2
    });
    Espruino.addProcessor("transformForEspruino", function(code, callback) {
      wrap(code, callback);
    });
  }

  function wrap(code, callback) {
    var isFlashPersistent = Espruino.Config.SAVE_ON_SEND == 2;
    var isStorageUpload = Espruino.Config.SAVE_ON_SEND == 3;
    var isFlashUpload = Espruino.Config.SAVE_ON_SEND == 1 || isFlashPersistent || isStorageUpload;
    if (!isFlashUpload) return callback(code);

    // Check environment vars
    var hasStorage = false;
    var ENV = Espruino.Core.Env.getData();
    if (ENV &&
        ENV.VERSION_MAJOR &&
        ENV.VERSION_MINOR!==undefined) {
      if (ENV.VERSION_MAJOR>1 ||
          ENV.VERSION_MINOR>=96) {
        hasStorage = true;
      }
    }

    //
    console.log("Uploading "+code.length+" bytes to flash");
    if (!hasStorage) { // old style
      if (isStorageUpload) {
        Espruino.Core.Notifications.error("You have pre-1v96 firmware - unable to upload to Storage");
        code = "";
      } else {
        Espruino.Core.Notifications.error("You have pre-1v96 firmware. Upload size is limited by available RAM");
        code = "E.setBootCode("+JSON.stringify(code)+(isFlashPersistent?",true":"")+");load()\n";
      }
    } else { // new style
      var filename;
      if (isStorageUpload)
        filename = Espruino.Config.SAVE_STORAGE_FILE;
      else
        filename = isFlashPersistent ? ".bootrst" : ".bootcde";
      if (!filename || filename.length>8) {
        Espruino.Core.Notifications.error("Invalid Storage file name "+JSON.stringify(filename));
        code = "";
      } else {
        var CHUNKSIZE = 1024;
        var newCode = [];
        var len = code.length;
        newCode.push('require("Storage").write("'+filename+'",'+JSON.stringify(code.substr(0,CHUNKSIZE))+',0,'+len+');');
        for (var i=CHUNKSIZE;i<len;i+=CHUNKSIZE)
          newCode.push('require("Storage").write("'+filename+'",'+JSON.stringify(code.substr(i,CHUNKSIZE))+','+i+');');
        code = newCode.join("\n");
        if (Espruino.Config.LOAD_STORAGE_FILE==2 && isStorageUpload)
          code += "\nload("+JSON.stringify(filename)+")\n";
        else if (Espruino.Config.LOAD_STORAGE_FILE!=0)
          code += "\nload()\n";
      }
    }
    callback(code);
  }

  Espruino.Plugins.SaveOnSend = {
    init : init,
  };
}());
<|endoftext|>


<commit_before>export const $fixFontSize = document.createElement('div');
$fixFontSize.className = 'ASS-fix-font-size';
$fixFontSize.textContent = 'M';

const cache = Object.create(null);

export function getRealFontSize(fn, fs) {
  const key = `${fn}-${fs}`;
  if (!cache[key]) {
    $fixFontSize.style.cssText = `font-size:${fs}px;font-family:"${fn}",Arial;`;
    cache[key] = fs * fs / $fixFontSize.clientHeight;
  }
  return cache[key];
}
<commit_msg>fix: specify line height when get font size fix #21<commit_after>export const $fixFontSize = document.createElement('div');
$fixFontSize.className = 'ASS-fix-font-size';
$fixFontSize.textContent = 'M';

const cache = Object.create(null);

export function getRealFontSize(fn, fs) {
  const key = `${fn}-${fs}`;
  if (!cache[key]) {
    $fixFontSize.style.cssText = `line-height:normal;font-size:${fs}px;font-family:"${fn}",Arial;`;
    cache[key] = fs * fs / $fixFontSize.clientHeight;
  }
  return cache[key];
}
<|endoftext|>


<commit_before>
import assert from 'assert'
import { describe, it } from 'mocha'

import AffineCipherEncoder from '../src/Encoder/AffineCipher'
import AtbashEncoder from '../src/Encoder/Atbash'
import Pipe from '../src/Pipe'
import ROT13Encoder from '../src/Encoder/ROT13'
import TextViewer from '../src/Viewer/Text'
import VigenereCipherEncoder from '../src/Encoder/VigenereCipher'

const examplePipeData = {
  bricks: [
    { name: 'text' },
    { name: 'affine-cipher', settings: { a: 7, b: 7 } },
    { name: 'text' }
  ],
  content: 'the quick brown fox jumps over 13 lazy dogs.',
  contentBucket: 0
}

/** @test {Pipe} */
describe('Pipe', () => {
  /** @test {Pipe.extract} */
  describe('extract()', () => {
    it('should extract pipe from structured data', () => {
      const pipe = Pipe.extract(examplePipeData)
      // Pipe bricks
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 3)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof AffineCipherEncoder, true)
      assert.strictEqual(pipeBricks[2] instanceof TextViewer, true)
      // Brick settings
      assert.strictEqual(
        pipeBricks[1].getSettingValue('a'),
        examplePipeData.bricks[1].settings.a)
      assert.strictEqual(
        pipeBricks[1].getSettingValue('b'),
        examplePipeData.bricks[1].settings.b)
      // Content applied to the pipe
      assert.strictEqual(
        pipe.getContent(examplePipeData.contentBucket, false).getString(),
        examplePipeData.content)
      // View should only be created lazily
      assert.strictEqual(pipe.hasView(), false)
    })
  })
  /** @test {Pipe.addBrick} */
  describe('addBrick()', () => {
    it('should add first brick to an empty pipe', () => {
      const pipe = new Pipe()
      const viewer = new TextViewer()
      pipe.addBrick(viewer)
      assert.strictEqual(pipe.getBricks()[0], viewer)
      assert.strictEqual(pipe.hasView(), false)
    })
    it('should add brick to the end of a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      const viewer = new TextViewer()
      pipe.addBrick(viewer)
      assert.strictEqual(pipe.getBricks()[3], viewer)
    })
  })
  /** @test {Pipe.removeBrick} */
  describe('removeBrick()', () => {
    it('should remove first brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(0)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof AffineCipherEncoder, true)
      assert.strictEqual(pipeBricks[1] instanceof TextViewer, true)
      assert.strictEqual(pipe.hasView(), false)
    })
    it('should remove middle brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(1)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof TextViewer, true)
    })
    it('should remove last brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(2)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof AffineCipherEncoder, true)
    })
  })
  /** @test {Pipe.spliceBricks} */
  describe('spliceBricks()', () => {
    it('should return removed bricks', () => {
      const pipe = Pipe.extract(examplePipeData)
      const removingBrick = pipe.getBricks()[1]
      const removedBricks = pipe.spliceBricks(1, 1)
      assert.strictEqual(removedBricks[0], removingBrick)
    })
    it('should replace a single encoder whilst maintaining result and direction (case 1 & 2)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'text' }
        ],
        content: 'kej prlvz owbfu qbm srnid byjw 13 ghat cbxd.',
        contentBucket: 1
      })
      // Let content propagate backward
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'the quick brown fox jumps over 13 lazy dogs.')
      // Replace encoder, the first bucket should update
      pipe.spliceBricks(1, 1, 'vigenere-cipher')
      assert.strictEqual(pipe.getBricks()[1] instanceof VigenereCipherEncoder, true)
      const b = await pipe.getContent(0)
      assert.strictEqual(b.getString(), 'inl aydnx xymmm izv ucuav zhlh 13 nzsr ldik.')
      // Change translation direction by changing the first bucket
      pipe.setContent('uryyb jbeyq', 0)
      const c = await pipe.getContent(1)
      assert.strictEqual(c.getString(), 'wiwnu rjgpo')
      // Replace encoder, the second bucket should update
      pipe.spliceBricks(1, 1, 'rot13')
      assert.strictEqual(pipe.getBricks()[1] instanceof ROT13Encoder, true)
      const d = await pipe.getContent(1)
      assert.strictEqual(d.getString(), 'hello world')
    })
    it('should replace the second encoder whilst maintaining result and direction (case 1 & 2)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'the quick brown fox jumps over 13 lazy dogs',
        contentBucket: 0
      })
      // Let content propagate forward through both encoders
      const a = await pipe.getContent(2)
      assert.strictEqual(a.getString(), 'xrw ceyim bjosh doz feavq olwj 13 tung pokq')
      // Replace second encoder, the last bucket should update
      pipe.spliceBricks(2, 1, 'atbash')
      assert.strictEqual(pipe.getBricks()[2] instanceof AtbashEncoder, true)
      const b = await pipe.getContent(2)
      assert.strictEqual(b.getString(), 'pvq kioea ldyuf jyn himrw ybqd 13 tszg xycw')
      // Change translation direction by changing the last bucket
      pipe.setContent('rwtto sojtp', 2)
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'pslli aiflt')
      // Replace second encoder, the first bucket should update
      pipe.spliceBricks(2, 1, 'rot13')
      assert.strictEqual(pipe.getBricks()[2] instanceof ROT13Encoder, true)
      const d = await pipe.getContent(0)
      assert.strictEqual(d.getString(), 'hello world')
    })
    it('should select the first bucket when replacing both encoders (case 3)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'hello world',
        contentBucket: 1
      })
      // Let content propagate in both directions
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'ahiib rbuis')
      const b = await pipe.getContent(2)
      assert.strictEqual(b.getString(), 'uryyb jbeyq')
      // Replace both encoders, only the last bucket should update
      pipe.spliceBricks(0, 2, 'rot13', 'atbash')
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'ahiib rbuis')
      const d = await pipe.getContent(2)
      assert.strictEqual(d.getString(), 'mfeel vlseu')
    })
    it('should keep propagation from last bucket when replacing the first encoder by two new ones (case 4)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'atbash' },
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'jvjah ewtcb',
        contentBucket: 2
      })
      // Let content propagate backwards
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'drdmf iqtkl')
      // Replace first encoder by two new ones, the first bucket should update
      pipe.spliceBricks(1, 1, 'rot13', 'vigenere-cipher')
      const b = await pipe.getContent(3)
      assert.strictEqual(b.getString(), 'jvjah ewtcb')
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'hello world')
    })
  })
})
<commit_msg>Updates pipe propagation tests<commit_after>
import assert from 'assert'
import { describe, it } from 'mocha'

import AffineCipherEncoder from '../src/Encoder/AffineCipher'
import AtbashEncoder from '../src/Encoder/Atbash'
import Pipe from '../src/Pipe'
import ROT13Encoder from '../src/Encoder/ROT13'
import TextViewer from '../src/Viewer/Text'
import VigenereCipherEncoder from '../src/Encoder/VigenereCipher'

const examplePipeData = {
  bricks: [
    { name: 'text' },
    { name: 'affine-cipher', settings: { a: 7, b: 7 } },
    { name: 'text' }
  ],
  content: 'the quick brown fox jumps over 13 lazy dogs.',
  contentBucket: 0
}

/** @test {Pipe} */
describe('Pipe', () => {
  /** @test {Pipe.extract} */
  describe('extract()', () => {
    it('should extract pipe from structured data', () => {
      const pipe = Pipe.extract(examplePipeData)
      // Pipe bricks
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 3)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof AffineCipherEncoder, true)
      assert.strictEqual(pipeBricks[2] instanceof TextViewer, true)
      // Brick settings
      assert.strictEqual(
        pipeBricks[1].getSettingValue('a'),
        examplePipeData.bricks[1].settings.a)
      assert.strictEqual(
        pipeBricks[1].getSettingValue('b'),
        examplePipeData.bricks[1].settings.b)
      // Content applied to the pipe
      assert.strictEqual(
        pipe.getContent(examplePipeData.contentBucket, false).getString(),
        examplePipeData.content)
      // View should only be created lazily
      assert.strictEqual(pipe.hasView(), false)
    })
  })
  /** @test {Pipe.addBrick} */
  describe('addBrick()', () => {
    it('should add first brick to an empty pipe', () => {
      const pipe = new Pipe()
      const viewer = new TextViewer()
      pipe.addBrick(viewer)
      assert.strictEqual(pipe.getBricks()[0], viewer)
      assert.strictEqual(pipe.hasView(), false)
    })
    it('should add brick to the end of a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      const viewer = new TextViewer()
      pipe.addBrick(viewer)
      assert.strictEqual(pipe.getBricks()[3], viewer)
    })
  })
  /** @test {Pipe.removeBrick} */
  describe('removeBrick()', () => {
    it('should remove first brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(0)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof AffineCipherEncoder, true)
      assert.strictEqual(pipeBricks[1] instanceof TextViewer, true)
      assert.strictEqual(pipe.hasView(), false)
    })
    it('should remove middle brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(1)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof TextViewer, true)
    })
    it('should remove last brick from a pipe', () => {
      const pipe = Pipe.extract(examplePipeData)
      pipe.removeBrick(2)
      const pipeBricks = pipe.getBricks()
      assert.strictEqual(pipeBricks.length, 2)
      assert.strictEqual(pipeBricks[0] instanceof TextViewer, true)
      assert.strictEqual(pipeBricks[1] instanceof AffineCipherEncoder, true)
    })
  })
  /** @test {Pipe.spliceBricks} */
  describe('spliceBricks()', () => {
    it('should return removed bricks', () => {
      const pipe = Pipe.extract(examplePipeData)
      const removingBrick = pipe.getBricks()[1]
      const removedBricks = pipe.spliceBricks(1, 1)
      assert.strictEqual(removedBricks[0], removingBrick)
    })
    it('should replace a single encoder whilst maintaining result and direction (case 1 & 2)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'text' }
        ],
        content: 'kej prlvz owbfu qbm srnid byjw 13 ghat cbxd.',
        contentBucket: 1
      })
      // Let content propagate backward
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'the quick brown fox jumps over 13 lazy dogs.')
      // Replace encoder, the first bucket should update
      pipe.spliceBricks(1, 1, 'vigenere-cipher')
      assert.strictEqual(pipe.getBricks()[1] instanceof VigenereCipherEncoder, true)
      const b = await pipe.getContent(0)
      assert.strictEqual(b.getString(), 'inl aydnx xymmm izv ucuav zhlh 13 nzsr ldik.')
      // Change translation direction by changing the first bucket
      pipe.setContent('uryyb jbeyq', 0)
      const c = await pipe.getContent(1)
      assert.strictEqual(c.getString(), 'wiwnu rjgpo')
      // Replace encoder, the second bucket should update
      pipe.spliceBricks(1, 1, 'rot13')
      assert.strictEqual(pipe.getBricks()[1] instanceof ROT13Encoder, true)
      const d = await pipe.getContent(1)
      assert.strictEqual(d.getString(), 'hello world')
    })
    it('should replace the second encoder whilst maintaining result and direction (case 1 & 2)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'the quick brown fox jumps over 13 lazy dogs',
        contentBucket: 0
      })
      // Let content propagate forward through both encoders
      const a = await pipe.getContent(2)
      assert.strictEqual(a.getString(), 'xrw ceyim bjosh doz feavq olwj 13 tung pokq')
      // Replace second encoder, the last bucket should update
      pipe.spliceBricks(2, 1, 'atbash')
      assert.strictEqual(pipe.getBricks()[2] instanceof AtbashEncoder, true)
      const b = await pipe.getContent(2)
      assert.strictEqual(b.getString(), 'pvq kioea ldyuf jyn himrw ybqd 13 tszg xycw')
      // Change translation direction by changing the last bucket
      pipe.setContent('rwtto sojtp', 2)
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'pslli aiflt')
      // Replace second encoder, the first bucket should update
      pipe.spliceBricks(2, 1, 'rot13')
      assert.strictEqual(pipe.getBricks()[2] instanceof ROT13Encoder, true)
      const d = await pipe.getContent(0)
      assert.strictEqual(d.getString(), 'hello world')
    })
    it('should select the first bucket when replacing both encoders (case 3)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'affine-cipher', settings: { a: 7, b: 7 } },
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'hello world',
        contentBucket: 1
      })
      // Let content propagate in both directions
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'ahiib rbuis')
      const b = await pipe.getContent(2)
      assert.strictEqual(b.getString(), 'uryyb jbeyq')
      // Replace both encoders, only the last bucket should update
      pipe.spliceBricks(1, 3, 'rot13', 'text', 'atbash')
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'ahiib rbuis')
      const d = await pipe.getContent(2)
      assert.strictEqual(d.getString(), 'mfeel vlseu')
    })
    it('should keep propagation from last bucket when replacing the first encoder by two new ones (case 4)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'atbash' },
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'jvjah ewtcb',
        contentBucket: 2
      })
      // Let content propagate backwards
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'drdmf iqtkl')
      // Replace first encoder by two new ones, the first bucket should update
      pipe.spliceBricks(1, 1, 'rot13', 'text', 'vigenere-cipher')
      const b = await pipe.getContent(3)
      assert.strictEqual(b.getString(), 'jvjah ewtcb')
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'hello world')
    })
    it('should keep propagation from last bucket when replacing the two first encoders by a single new one (case 4)', async () => {
      const pipe = Pipe.extract({
        bricks: [
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' },
          { name: 'vigenere-cipher' },
          { name: 'text' },
          { name: 'rot13' },
          { name: 'text' }
        ],
        content: 'jvjah ewtcb',
        contentBucket: 3
      })
      // Let content propagate backwards
      const a = await pipe.getContent(0)
      assert.strictEqual(a.getString(), 'hello world')
      // Replace first two encoders by a single new one
      pipe.spliceBricks(1, 3, 'atbash')
      const b = await pipe.getContent(2)
      assert.strictEqual(b.getString(), 'jvjah ewtcb')
      const c = await pipe.getContent(0)
      assert.strictEqual(c.getString(), 'drdmf iqtkl')
    })
  })
})
<|endoftext|>


<commit_before>var React = require('react');
var ReactDOM = require('react-dom');
var StoryTitle = require('./StoryTitle.js');
var StoryBox = require('./StoryBox.js');
var StoryInput = require('./StoryInput.js');
var Fwib = require('./Fwib.js');
var UsersInRoom = require('./UsersInRoom.js');

var io = require('socket.io-client');
var socket = io.connect();

module.exports = React.createClass({

  getInitialState: function() {
    return {users: [], fwibs:[], text: ''};
  },

  componentDidMount: function() {
   socket.on('init', this._initialize);
   socket.on('send:fwib', this._fwibReceive);
   socket.on('user:join', this._userJoined);
   socket.on('user:left', this._userLeft);
   console.log('Current state:', this.props);
   console.log('this.props.user: ', this.props.user)
  },

  _initialize: function(data) {
    var {users, name} = data;
    this.setState({users, user: name});
  },

  _fwibReceive: function(fwib) {
    console.log('fwibReceive fwib:', fwib)
    var {fwibs} = this.state;
    fwibs.push(fwib);
    this.setState({fwibs});
  },

  _userJoined: function(data) {
    var {users, fwibs} = this.state;
    var {name} = data;
    users.push(name);
    fwibs.push({
      user: 'APPLICATION BOT',
      text : name +' Joined'
    });
    this.setState({users, fwibs});
  },

  _userLeft: function(data) {
    var {users, fwibs} = this.state;
    var {name} = data;
    var index = users.indexOf(name);
    users.splice(index, 1);
    fwibs.push({
      user: 'APPLICATION BOT',
      text : name +' Left'
    });
    this.setState({users, fwibs});
  },

  handleFwibSubmit: function(fwib) {
    console.log('gameview fwib:', fwib);
    var {fwibs} = this.state;
    fwibs.push(fwib); // {text: fwib} => {text: fwib.text} => fwib
    this.setState({fwibs});
    socket.emit('send:fwib', fwib);
  },

	render: function() {
		return (

				<StoryTitle />
        <StoryBox
          fwibs={this.state.fwibs}
        />
        <StoryInput
          onFwibSubmit={this.handleFwibSubmit}
          user={this.state.user}
        />
				<UsersInRoom
				  users={this.state.users}
				/>

		);
	}

});<commit_msg>basic prop system<commit_after>var React = require('react');
var ReactDOM = require('react-dom');
var StoryTitle = require('./StoryTitle.js');
var StoryBox = require('./StoryBox.js');
var StoryInput = require('./StoryInput.js');
var Fwib = require('./Fwib.js');
var UsersInRoom = require('./UsersInRoom.js');

var io = require('socket.io-client');
var socket = io.connect();

module.exports = React.createClass({

  getInitialState: function() {
    return {users: [], fwibs:[], text: ''};
  },

  componentDidMount: function() {
   socket.on('init', this._initialize);
   socket.on('send:fwib', this._fwibReceive);
   socket.on('user:join', this._userJoined);
   socket.on('user:left', this._userLeft);
   console.log('Current state:', this.state);
  },

  _initialize: function(data) {
    var {users, name} = data;
    this.setState({users, user: name});
  },

  _fwibReceive: function(fwib) {
    console.log('fwibReceive fwib:', fwib)
    var {fwibs} = this.state;
    fwibs.push(fwib);
    this.setState({fwibs});
  },

  _userJoined: function(data) {
    var {users, fwibs} = this.state;
    var {name} = data;
    users.push(name);
    fwibs.push({
      user: 'APPLICATION BOT',
      text : name +' Joined'
    });
    this.setState({users, fwibs});
  },

  _userLeft: function(data) {
    var {users, fwibs} = this.state;
    var {name} = data;
    var index = users.indexOf(name);
    users.splice(index, 1);
    fwibs.push({
      user: 'APPLICATION BOT',
      text : name +' Left'
    });
    this.setState({users, fwibs});
  },

  handleFwibSubmit: function(fwib) {
    console.log('gameview fwib:', fwib);
    var {fwibs} = this.state;
    fwibs.push(fwib); // {text: fwib} => {text: fwib.text} => fwib
    this.setState({fwibs});
    socket.emit('send:fwib', fwib);
  },

	render: function() {
		return (

				<StoryTitle />
        <StoryBox
          fwibs={this.state.fwibs}
        />
        <StoryInput
          onFwibSubmit={this.handleFwibSubmit}
          user={this.state.user}
        />
				<UsersInRoom
				  users={this.state.users}
				/>

		);
	}

});<|endoftext|>


<commit_before>"use strict";

describe("luga", function() {

	it("Requires jQuery in order to work", function() {
		expect(jQuery).toBeDefined();
	});

	it("Lives inside its own namespace", function() {
		expect(luga).toBeDefined();
	});

	it("Uses jQuery.extend() as simple/crude inheritance solution", function() {

		/* Class Person. */
		function Person(gender) {
			this.gender = gender;
			this.getGender = function() {
				return this.gender;
			};
		}
		/* Class Superstar */
		function Superstar(gender, name) {
			jQuery.extend(this, new Person());
			this.gender = gender;
			this.name = name;
			this.getName = function() {
				return this.name;
			};
		}
		var nicole = new Superstar("female", "Nicole Kidman");

		expect(nicole.getGender()).toEqual("female");
		expect(nicole.getName()).toEqual("Nicole Kidman");
	});

	describe(".namespace()", function() {

		it("Must be defined", function() {
			expect(luga.namespace).toBeDefined();
			expect(jQuery.isFunction(luga.namespace)).toBeTruthy();
		});

		it("Does not override existing namespaces", function() {
			var testRoot = {};
			testRoot.child = {};
			testRoot.child.grandChild = {};
			luga.namespace("child", testRoot);
			expect(testRoot.child.grandChild).toBeDefined();
		});

		it("By default uses window as root object", function() {
			luga.namespace("ciccio");
			expect(ciccio).toBeDefined();
		});

		it("But works on any arbitrary root object", function() {
			var testRoot = {};
			luga.namespace("child", testRoot);
			expect(testRoot.child).toBeDefined();
		});

	});

});

describe("luga.utils stores generic, utilities and static methods", function() {

	it("Lives inside its own namespace", function() {
		expect(luga.utils).toBeDefined();
	});

	describe(".formatString()", function() {
		it("Given a string containing placeholders, assembles a new string", function() {
			expect(luga.utils.formatString("My name is {0} {1}", ["Ciccio", "Pasticcio"])).toEqual("My name is Ciccio Pasticcio");
			expect(luga.utils.formatString("This {0} is just a {0}", ["test"])).toEqual("This test is just a test");
			expect(luga.utils.formatString("My name is {firstName} {lastName}", {firstName: "Ciccio", lastName: "Pasticcio"})).toEqual("My name is Ciccio Pasticcio");
			expect(luga.utils.formatString("This {str} is just a {str}", { str:"test"} )).toEqual("This test is just a test");
		});
	});

	describe(".stringToFunction(). Given the name of a function as a string", function() {

		it("Returns the relevant function if it finds it inside the window/global scope", function() {
			window.myFunc = function(){};
			var result = luga.utils.stringToFunction("myFunc");
			expect(result).not.toBeNull();
			expect(jQuery.isFunction(result)).toBeTruthy();
		});

		it("Returns null if the function does not exist", function() {
			expect(luga.utils.stringToFunction("missing")).toBeNull();
		});

		it("Or if the variable exists, but it's not a function", function() {
			window.str = "ciao";
			expect(luga.utils.stringToFunction("str")).toBeNull();
		});

	});

	describe(".displayMessage()", function() {

		it("Displays a message box above a given node", function() {
			loadFixtures("validator/FormValidator/basic.htm");
			var formNode = jQuery("#basic");
			expect(boxNode).not.toExist();
			luga.utils.displayMessage(formNode, "Ciao");
			var boxNode = formNode.prev();
			expect(boxNode).toExist();
			expect(boxNode).toHaveText("Ciao");
			expect(boxNode).toHaveClass(luga.utils.CONST.CSS_CLASSES.MESSAGE);
		});

	});

	describe(".displayErrorMessage()", function() {

		it("Displays an error box above a given node", function() {
			loadFixtures("validator/FormValidator/basic.htm");
			var formNode = jQuery("#basic");
			expect(boxNode).not.toExist();
			luga.utils.displayErrorMessage(formNode, "Error");
			var boxNode = formNode.prev();
			expect(boxNode).toExist();
			expect(boxNode).toHaveText("Error");
			expect(boxNode).toHaveClass(luga.utils.CONST.CSS_CLASSES.ERROR_MESSAGE);
		});

	});

});<commit_msg>Removed test spec (was too basic to be worth)<commit_after>"use strict";

describe("luga", function() {

	it("Requires jQuery in order to work", function() {
		expect(jQuery).toBeDefined();
	});

	it("Lives inside its own namespace", function() {
		expect(luga).toBeDefined();
	});

	it("Uses jQuery.extend() as simple/crude inheritance solution", function() {

		/* Class Person. */
		function Person(gender) {
			this.gender = gender;
			this.getGender = function() {
				return this.gender;
			};
		}
		/* Class Superstar */
		function Superstar(gender, name) {
			jQuery.extend(this, new Person());
			this.gender = gender;
			this.name = name;
			this.getName = function() {
				return this.name;
			};
		}
		var nicole = new Superstar("female", "Nicole Kidman");

		expect(nicole.getGender()).toEqual("female");
		expect(nicole.getName()).toEqual("Nicole Kidman");
	});

	describe(".namespace()", function() {

		it("Does not override existing namespaces", function() {
			var testRoot = {};
			testRoot.child = {};
			testRoot.child.grandChild = {};
			luga.namespace("child", testRoot);
			expect(testRoot.child.grandChild).toBeDefined();
		});

		it("By default uses window as root object", function() {
			luga.namespace("ciccio");
			expect(ciccio).toBeDefined();
		});

		it("But works on any arbitrary root object", function() {
			var testRoot = {};
			luga.namespace("child", testRoot);
			expect(testRoot.child).toBeDefined();
		});

	});

});

describe("luga.utils stores generic, utilities and static methods", function() {

	it("Lives inside its own namespace", function() {
		expect(luga.utils).toBeDefined();
	});

	describe(".formatString()", function() {
		it("Given a string containing placeholders, assembles a new string", function() {
			expect(luga.utils.formatString("My name is {0} {1}", ["Ciccio", "Pasticcio"])).toEqual("My name is Ciccio Pasticcio");
			expect(luga.utils.formatString("This {0} is just a {0}", ["test"])).toEqual("This test is just a test");
			expect(luga.utils.formatString("My name is {firstName} {lastName}", {firstName: "Ciccio", lastName: "Pasticcio"})).toEqual("My name is Ciccio Pasticcio");
			expect(luga.utils.formatString("This {str} is just a {str}", { str:"test"} )).toEqual("This test is just a test");
		});
	});

	describe(".stringToFunction(). Given the name of a function as a string", function() {

		it("Returns the relevant function if it finds it inside the window/global scope", function() {
			window.myFunc = function(){};
			var result = luga.utils.stringToFunction("myFunc");
			expect(result).not.toBeNull();
			expect(jQuery.isFunction(result)).toBeTruthy();
		});

		it("Returns null if the function does not exist", function() {
			expect(luga.utils.stringToFunction("missing")).toBeNull();
		});

		it("Or if the variable exists, but it's not a function", function() {
			window.str = "ciao";
			expect(luga.utils.stringToFunction("str")).toBeNull();
		});

	});

	describe(".displayMessage()", function() {

		it("Displays a message box above a given node", function() {
			loadFixtures("validator/FormValidator/basic.htm");
			var formNode = jQuery("#basic");
			expect(boxNode).not.toExist();
			luga.utils.displayMessage(formNode, "Ciao");
			var boxNode = formNode.prev();
			expect(boxNode).toExist();
			expect(boxNode).toHaveText("Ciao");
			expect(boxNode).toHaveClass(luga.utils.CONST.CSS_CLASSES.MESSAGE);
		});

	});

	describe(".displayErrorMessage()", function() {

		it("Displays an error box above a given node", function() {
			loadFixtures("validator/FormValidator/basic.htm");
			var formNode = jQuery("#basic");
			expect(boxNode).not.toExist();
			luga.utils.displayErrorMessage(formNode, "Error");
			var boxNode = formNode.prev();
			expect(boxNode).toExist();
			expect(boxNode).toHaveText("Error");
			expect(boxNode).toHaveClass(luga.utils.CONST.CSS_CLASSES.ERROR_MESSAGE);
		});

	});

});<|endoftext|>