<commit_before>import assert from 'node:assert'
import { dirname, resolve } from 'node:path'
import { env } from 'node:process'
import { fileURLToPath } from 'node:url'
import { joinUrl, setup, teardown } from '../_testHelpers/index.js'

const { stringify } = JSON

const __dirname = dirname(fileURLToPath(import.meta.url))

describe('handler payload tests', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      noPrependStageInUrl: false,
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      description: 'when handler is context.done',
      expected: 'foo',
      path: '/dev/context-done-handler',
      status: 200,
    },

    {
      description: 'when handler is context.done which is deferred',
      expected: 'foo',
      path: '/dev/context-done-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is context.succeed',
      expected: 'foo',
      path: '/dev/context-succeed-handler',
      status: 200,
    },

    {
      description: 'when handler is context.succeed which is deferred',
      expected: 'foo',
      path: '/dev/context-succeed-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is a callback',
      expected: 'foo',
      path: '/dev/callback-handler',
      status: 200,
    },
    {
      description: 'when handler is a callback which is deferred',
      expected: 'foo',
      path: '/dev/callback-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler returns a promise',
      expected: 'foo',
      path: '/dev/promise-handler',
      status: 200,
    },

    {
      description: 'when handler a promise which is deferred',
      expected: 'foo',
      path: '/dev/promise-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is an async function',
      expected: 'foo',
      path: '/dev/async-function-handler',
      status: 200,
    },

    // NOTE: mix and matching of callbacks and promises is not recommended,
    // nonetheless, we test some of the behaviour to match AWS execution precedence
    {
      description:
        'when handler returns a callback but defines a callback parameter',
      expected: 'Hello Promise!',
      path: '/dev/promise-with-defined-callback-handler',
      status: 200,
    },

    {
      description:
        'when handler throws an expection in promise should return 502',
      path: '/dev/throw-exception-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler throws an expection before calling callback should return 502',
      path: '/dev/throw-exception-in-callback-handler',
      status: 502,
    },

    {
      description:
        'when handler does not return any answer in promise should return 502',
      path: '/dev/no-answer-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler returns bad answer in promise should return 204',
      path: '/dev/bad-answer-in-promise-handler',
      status: 204,
    },

    {
      description:
        'when handler returns bad answer in callback should return 204',
      path: '/dev/bad-answer-in-callback-handler',
      status: 204,
    },

    {
      description: 'test path variable with Prepend',
      expected: '/test-path-variable-handler',
      path: '/dev/test-path-variable-handler',
      status: 200,
    },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls context.succeed and context.done',
    //   expected: 'Hello Context.succeed!',
    //   path: '/dev/context-succeed-with-context-done-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback and context.done',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-with-context-done-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback and returns Promise',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-with-promise-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback inside returned Promise',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-inside-promise-handler',
    // },
  ].forEach(({ description, expected, path, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url)
      assert.equal(response.status, status)

      if (expected) {
        const json = await response.json()
        assert.deepEqual(json, expected)
      }
    })
  })
})

describe('handler payload tests with prepend off', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      args: ['--noPrependStageInUrl'],
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      description: 'when handler is context.done',
      expected: 'foo',
      path: '/context-done-handler',
      status: 200,
    },

    {
      description: 'when handler is context.done which is deferred',
      expected: 'foo',
      path: '/context-done-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is context.succeed',
      expected: 'foo',
      path: '/context-succeed-handler',
      status: 200,
    },

    {
      description: 'when handler is context.succeed which is deferred',
      expected: 'foo',
      path: '/context-succeed-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is a callback',
      expected: 'foo',
      path: '/callback-handler',
      status: 200,
    },
    {
      description: 'when handler is a callback which is deferred',
      expected: 'foo',
      path: '/callback-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler returns a promise',
      expected: 'foo',
      path: '/promise-handler',
      status: 200,
    },

    {
      description: 'when handler a promise which is deferred',
      expected: 'foo',
      path: '/promise-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is an async function',
      expected: 'foo',
      path: '/async-function-handler',
      status: 200,
    },

    // NOTE: mix and matching of callbacks and promises is not recommended,
    // nonetheless, we test some of the behaviour to match AWS execution precedence
    {
      description:
        'when handler returns a callback but defines a callback parameter',
      expected: 'Hello Promise!',
      path: '/promise-with-defined-callback-handler',
      status: 200,
    },

    {
      description:
        'when handler throws an expection in promise should return 502',
      path: '/throw-exception-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler throws an expection before calling callback should return 502',
      path: '/throw-exception-in-callback-handler',
      status: 502,
    },

    {
      description:
        'when handler does not return any answer in promise should return 502',
      path: '/no-answer-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler returns bad answer in promise should return 204',
      path: '/bad-answer-in-promise-handler',
      status: 204,
    },

    {
      description:
        'when handler returns bad answer in callback should return 204',
      path: '/bad-answer-in-callback-handler',
      status: 204,
    },

    {
      description: 'test path variable with Prepend',
      expected: '/test-path-variable-handler',
      path: '/test-path-variable-handler',
      status: 200,
    },

    {
      description: 'event.resource should not contain wildcards',
      expected: '/{id}/test-resource-variable-handler',
      path: '/1/test-resource-variable-handler',
      status: 200,
    },
  ].forEach(({ description, expected, path, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url)
      assert.equal(response.status, status)

      if (expected) {
        const json = await response.json()
        assert.deepEqual(json, expected)
      }
    })
  })
})

describe.skip('handler payload scehma validation tests', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      args: ['--noPrependStageInUrl'],
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      body: {
        foo: 'bar',
      },
      description: 'test with valid payload',
      expectedBody: `{"foo":"bar"}`,
      path: '/test-payload-schema-validator',
      status: 200,
    },

    {
      body: {},
      description: 'test with invalid payload',
      path: '/test-payload-schema-validator',
      status: 400,
    },
  ].forEach(({ description, expectedBody, path, body, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url, {
        body: stringify(body),
        headers: { 'Content-Type': 'application/json' },
        method: 'post',
      })

      assert.equal(response.status, status)

      if (expectedBody) {
        const json = await response.json()
        assert.deepEqual(json.body, expectedBody)
      }
    })
  })
})
<commit_msg>test: fix description<commit_after>import assert from 'node:assert'
import { dirname, resolve } from 'node:path'
import { env } from 'node:process'
import { fileURLToPath } from 'node:url'
import { joinUrl, setup, teardown } from '../_testHelpers/index.js'

const { stringify } = JSON

const __dirname = dirname(fileURLToPath(import.meta.url))

describe('handler payload tests', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      noPrependStageInUrl: false,
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      description: 'when handler is context.done',
      expected: 'foo',
      path: '/dev/context-done-handler',
      status: 200,
    },

    {
      description: 'when handler is context.done which is deferred',
      expected: 'foo',
      path: '/dev/context-done-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is context.succeed',
      expected: 'foo',
      path: '/dev/context-succeed-handler',
      status: 200,
    },

    {
      description: 'when handler is context.succeed which is deferred',
      expected: 'foo',
      path: '/dev/context-succeed-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is a callback',
      expected: 'foo',
      path: '/dev/callback-handler',
      status: 200,
    },
    {
      description: 'when handler is a callback which is deferred',
      expected: 'foo',
      path: '/dev/callback-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler returns a promise',
      expected: 'foo',
      path: '/dev/promise-handler',
      status: 200,
    },

    {
      description: 'when handler a promise which is deferred',
      expected: 'foo',
      path: '/dev/promise-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is an async function',
      expected: 'foo',
      path: '/dev/async-function-handler',
      status: 200,
    },

    // NOTE: mix and matching of callbacks and promises is not recommended,
    // nonetheless, we test some of the behaviour to match AWS execution precedence
    {
      description:
        'when handler returns a callback but defines a callback parameter',
      expected: 'Hello Promise!',
      path: '/dev/promise-with-defined-callback-handler',
      status: 200,
    },

    {
      description:
        'when handler throws an expection in promise should return 502',
      path: '/dev/throw-exception-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler throws an expection before calling callback should return 502',
      path: '/dev/throw-exception-in-callback-handler',
      status: 502,
    },

    {
      description:
        'when handler does not return any answer in promise should return 502',
      path: '/dev/no-answer-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler returns bad answer in promise should return 204',
      path: '/dev/bad-answer-in-promise-handler',
      status: 204,
    },

    {
      description:
        'when handler returns bad answer in callback should return 204',
      path: '/dev/bad-answer-in-callback-handler',
      status: 204,
    },

    {
      description: 'test path variable with Prepend',
      expected: '/test-path-variable-handler',
      path: '/dev/test-path-variable-handler',
      status: 200,
    },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls context.succeed and context.done',
    //   expected: 'Hello Context.succeed!',
    //   path: '/dev/context-succeed-with-context-done-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback and context.done',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-with-context-done-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback and returns Promise',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-with-promise-handler',
    // },

    // TODO: reactivate!
    // {
    //   description: 'when handler calls callback inside returned Promise',
    //   expected: 'Hello Callback!',
    //   path: '/dev/callback-inside-promise-handler',
    // },
  ].forEach(({ description, expected, path, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url)
      assert.equal(response.status, status)

      if (expected) {
        const json = await response.json()
        assert.deepEqual(json, expected)
      }
    })
  })
})

describe('handler payload tests with prepend off', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      args: ['--noPrependStageInUrl'],
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      description: 'when handler is context.done',
      expected: 'foo',
      path: '/context-done-handler',
      status: 200,
    },

    {
      description: 'when handler is context.done which is deferred',
      expected: 'foo',
      path: '/context-done-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is context.succeed',
      expected: 'foo',
      path: '/context-succeed-handler',
      status: 200,
    },

    {
      description: 'when handler is context.succeed which is deferred',
      expected: 'foo',
      path: '/context-succeed-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is a callback',
      expected: 'foo',
      path: '/callback-handler',
      status: 200,
    },
    {
      description: 'when handler is a callback which is deferred',
      expected: 'foo',
      path: '/callback-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler returns a promise',
      expected: 'foo',
      path: '/promise-handler',
      status: 200,
    },

    {
      description: 'when handler a promise which is deferred',
      expected: 'foo',
      path: '/promise-handler-deferred',
      status: 200,
    },

    {
      description: 'when handler is an async function',
      expected: 'foo',
      path: '/async-function-handler',
      status: 200,
    },

    // NOTE: mix and matching of callbacks and promises is not recommended,
    // nonetheless, we test some of the behaviour to match AWS execution precedence
    {
      description:
        'when handler returns a callback but defines a callback parameter',
      expected: 'Hello Promise!',
      path: '/promise-with-defined-callback-handler',
      status: 200,
    },

    {
      description:
        'when handler throws an expection in promise should return 502',
      path: '/throw-exception-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler throws an expection before calling callback should return 502',
      path: '/throw-exception-in-callback-handler',
      status: 502,
    },

    {
      description:
        'when handler does not return any answer in promise should return 502',
      path: '/no-answer-in-promise-handler',
      status: 502,
    },

    {
      description:
        'when handler returns bad answer in promise should return 204',
      path: '/bad-answer-in-promise-handler',
      status: 204,
    },

    {
      description:
        'when handler returns bad answer in callback should return 204',
      path: '/bad-answer-in-callback-handler',
      status: 204,
    },

    {
      description: 'test path variable with Prepend',
      expected: '/test-path-variable-handler',
      path: '/test-path-variable-handler',
      status: 200,
    },

    {
      description: 'event.resource should not contain wildcards',
      expected: '/{id}/test-resource-variable-handler',
      path: '/1/test-resource-variable-handler',
      status: 200,
    },
  ].forEach(({ description, expected, path, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url)
      assert.equal(response.status, status)

      if (expected) {
        const json = await response.json()
        assert.deepEqual(json, expected)
      }
    })
  })
})

describe.skip('handler payload schema validation tests', function desc() {
  this.timeout(30000)

  beforeEach(() =>
    setup({
      args: ['--noPrependStageInUrl'],
      servicePath: resolve(__dirname),
    }),
  )

  afterEach(() => teardown())

  //
  ;[
    {
      body: {
        foo: 'bar',
      },
      description: 'test with valid payload',
      expectedBody: `{"foo":"bar"}`,
      path: '/test-payload-schema-validator',
      status: 200,
    },

    {
      body: {},
      description: 'test with invalid payload',
      path: '/test-payload-schema-validator',
      status: 400,
    },
  ].forEach(({ description, expectedBody, path, body, status }) => {
    it(description, async () => {
      const url = joinUrl(env.TEST_BASE_URL, path)

      const response = await fetch(url, {
        body: stringify(body),
        headers: { 'Content-Type': 'application/json' },
        method: 'post',
      })

      assert.equal(response.status, status)

      if (expectedBody) {
        const json = await response.json()
        assert.deepEqual(json.body, expectedBody)
      }
    })
  })
})
<|endoftext|>


<commit_before>var cons = require('../src/cons/cons.js');
var car = require('../src/cons/car.js');
var cdr = require('../src/cons/cdr.js');
var print = require('../src/cons/print.js');
var equal = require('../src/cons/equal.js');

var list = require('../src/list/list.js');
var length = require('../src/list/length.js');
var range = require('../src/list/range.js');
var map = require('../src/list/map.js');
var reduce = require('../src/list/reduce.js');
var filter = require('../src/list/filter.js');
var filter = require('../src/list/filter.js');
var peek = require('../src/list/peek.js');
var push = require('../src/list/push.js');
var pop = require('../src/list/pop.js');
var zip = require('../src/list/zip.js');
var enqueue = require('../src/list/enqueue.js');
var dequeue = require('../src/list/dequeue.js');

var assert = require('assert');

suite('list', function(){
    var linkedList, linkedList2, linkedList3, linkedList4, linkedList5,
        filtered, emptyFiltered, addMapped, mulMapped, reduceAdd, reduceMul,
        zipped1, zipped2, linkedListP1, linkedListP2, linkedListE1, linkedListE2,
        consList, filteredCons, emptyFilteredCons, addMappedCons, mulMappedCons,
        zip1, zip2, zip3, enqueue1, enqueue2, dequeue1, dequeue2,
        pushed1, pushed2, popped1, popped2,
        range1, range2, range3, range4, badrange, steprange;
    setup(function(){
        linkedList = list(1,2,3,4,5);
        linkedList2 = list(6,7,8,9,10);
        linkedList3 = list(6,7,8,9,10,11,12,13,14);
        linkedList4 = list(11,22,33,44,55);
        linkedList5 = list(11,22,33,44,55,66,77,88,99);
        range1 = range(1,6);
        range2 = range(6,15);
        range3 = range(1,8);
        range4 = range(30);
        steprange = range(11, 100, 11);
        badrange = range(0, 10, -1);
        zipped1 = list(cons(6,11),cons(7,22),cons(8,33),cons(9,44),cons(10,55));
        zipped2 = list(cons(11,6),cons(22,7),cons(33,8),cons(44,9),cons(55,10),
            cons(66,11),cons(77,12),cons(88,13),cons(99,14));
        linkedListP1 = list(1,2,3,4,5,6);
        linkedListP2 = list(1,2,3,4,5,6,7);
        linkedListE1 = list(8,1,2,3,4,5);
        linkedListE2 = list(9,8,1,2,3,4,5);
        pushed1 = push(linkedList, 6);
        pushed2 = push(pushed1, 7);
        popped1 = pop(pushed2);
        popped2 = pop(popped1);
        enqueue1 = enqueue(linkedList, 8);
        enqueue2 = enqueue(enqueue1, 9);
        dequeue1 = dequeue(enqueue2);
        dequeue2 = dequeue(dequeue1);
        zip1 = zip(linkedList2, linkedList5);
        zip2 = zip(linkedList3, linkedList4);
        zip3 = zip(linkedList5,linkedList3);
        popped1 = pop(pushed2);
        popped2 = pop(popped1);
        filtered = filter(linkedList, function(n){return n % 2 === 0;});
        emptyFiltered = filter(linkedList, function(){return false;});
        addMapped = map(linkedList, function(n){return n + 10;});
        mulMapped = map(linkedList, function(n){return n * 10;});
        reduceAdd = reduce(linkedList, function(a, b){return a + b;}, 0);
        reduceMul = reduce(linkedList, function(a, b){return a * b;}, 1);
        consList = cons(1,
            cons(2,
                cons(3,
                    cons(4,
                        cons(5, null)))));
        addMappedCons = cons(11,
            cons(12,
                cons(13,
                    cons(14,
                        cons(15, null)))));
        mulMappedCons = cons(10,
            cons(20,
                cons(30,
                    cons(40,
                        cons(50, null)))));
        filteredCons = cons(2,
            cons(4, null));
        emptyFilteredCons = cons(null, null);
    });
    suite('list', function(){
        test('list', function(){
            assert.ok(equal(consList, linkedList));
        });
        test('length', function(){
            assert.equal(length(linkedList), 5);
            assert.equal(length(linkedList2), 5);
            assert.equal(length(linkedList3), 9);
            assert.equal(length(linkedList4), 5);
            assert.equal(length(linkedList5), 9);
            assert.equal(length(zipped1), 5);
            assert.equal(length(zipped2), 9);
            assert.equal(length(linkedListP1), 6);
            assert.equal(length(linkedListP2), 7);
            assert.equal(length(linkedListE1), 6);
            assert.equal(length(linkedListE2), 7);
        });
        test('range', function(){
            assert.ok(equal(range1, linkedList));
            assert.ok(equal(range2, linkedList3));
            assert.ok(equal(range3, linkedListP2));
            assert.ok(equal(steprange, linkedList5));

            assert.equal(badrange, null);
            assert.equal(length(range1), 5);
            assert.equal(length(range2), 9);
            assert.equal(length(range3), 7);
            assert.equal(length(range4), 30);
            assert.equal(length(steprange), 9);
        });

        test('map', function(){
            assert.ok(equal(addMapped, addMappedCons));
            assert.ok(equal(mulMapped, mulMappedCons));
        });
        test('filter', function(){
            assert.ok(equal(filtered, filteredCons));
            assert.equal(emptyFiltered, null);
        });
        test('reduce', function(){
            assert.equal(reduceAdd, 15);
            assert.equal(reduceMul, 120);
        });
        test('peek', function(){
            assert.equal(peek(linkedList), 5);
            assert.equal(peek(linkedListP1), 6);
            assert.equal(peek(linkedListP2), 7);
        });
        test('push', function(){
            assert.ok(equal(linkedListP1, pushed1));
            assert.ok(equal(linkedListP2, pushed2));
        });
        test('pop', function(){
            assert.ok(equal(linkedListP1, popped1));
            assert.ok(equal(linkedList, popped2));
        });
        test('enqueue', function(){
            assert.ok(equal(linkedListE1, enqueue1));
            assert.ok(equal(linkedListE2, enqueue2));
        });
        test('dequeue', function(){
            assert.ok(equal(linkedListE1, dequeue1));
            assert.ok(equal(linkedList, dequeue2));
        });
    });
});<commit_msg>Add list reverse tests<commit_after>var cons = require('../src/cons/cons.js');
var car = require('../src/cons/car.js');
var cdr = require('../src/cons/cdr.js');
var print = require('../src/cons/print.js');
var equal = require('../src/cons/equal.js');

var list = require('../src/list/list.js');
var length = require('../src/list/length.js');
var range = require('../src/list/range.js');
var map = require('../src/list/map.js');
var reduce = require('../src/list/reduce.js');
var filter = require('../src/list/filter.js');
var filter = require('../src/list/filter.js');
var peek = require('../src/list/peek.js');
var push = require('../src/list/push.js');
var pop = require('../src/list/pop.js');
var zip = require('../src/list/zip.js');
var reverse = require('../src/list/reverse.js');
var enqueue = require('../src/list/enqueue.js');
var dequeue = require('../src/list/dequeue.js');

var assert = require('assert');

suite('list', function(){
    var linkedList, linkedList2, linkedList3, linkedList4, linkedList5,
        filtered, emptyFiltered, addMapped, mulMapped, reduceAdd, reduceMul,
        zipped1, zipped2, linkedListP1, linkedListP2, linkedListE1, linkedListE2,
        consList, filteredCons, emptyFilteredCons, addMappedCons, mulMappedCons,
        zip1, zip2, zip3, enqueue1, enqueue2, dequeue1, dequeue2,
        pushed1, pushed2, popped1, popped2,
        range1, range2, range3, range4, badrange, steprange;
    setup(function(){
        linkedList = list(1,2,3,4,5);
        linkedList2 = list(6,7,8,9,10);
        linkedList3 = list(6,7,8,9,10,11,12,13,14);
        linkedList4 = list(11,22,33,44,55);
        linkedList5 = list(11,22,33,44,55,66,77,88,99);
        range1 = range(1,6);
        range2 = range(6,15);
        range3 = range(1,8);
        range4 = range(30);
        steprange = range(11, 100, 11);
        badrange = range(0, 10, -1);
        zipped1 = list(cons(6,11),cons(7,22),cons(8,33),cons(9,44),cons(10,55));
        zipped2 = list(cons(11,6),cons(22,7),cons(33,8),cons(44,9),cons(55,10),
            cons(66,11),cons(77,12),cons(88,13),cons(99,14));
        linkedListP1 = list(1,2,3,4,5,6);
        linkedListP2 = list(1,2,3,4,5,6,7);
        linkedListE1 = list(8,1,2,3,4,5);
        linkedListE2 = list(9,8,1,2,3,4,5);
        pushed1 = push(linkedList, 6);
        pushed2 = push(pushed1, 7);
        popped1 = pop(pushed2);
        popped2 = pop(popped1);
        enqueue1 = enqueue(linkedList, 8);
        enqueue2 = enqueue(enqueue1, 9);
        dequeue1 = dequeue(enqueue2);
        dequeue2 = dequeue(dequeue1);
        zip1 = zip(linkedList2, linkedList5);
        zip2 = zip(linkedList3, linkedList4);
        zip3 = zip(linkedList5,linkedList3);
        popped1 = pop(pushed2);
        popped2 = pop(popped1);
        filtered = filter(linkedList, function(n){return n % 2 === 0;});
        emptyFiltered = filter(linkedList, function(){return false;});
        addMapped = map(linkedList, function(n){return n + 10;});
        mulMapped = map(linkedList, function(n){return n * 10;});
        reduceAdd = reduce(linkedList, function(a, b){return a + b;}, 0);
        reduceMul = reduce(linkedList, function(a, b){return a * b;}, 1);
        consList = cons(1,
            cons(2,
                cons(3,
                    cons(4,
                        cons(5, null)))));
        addMappedCons = cons(11,
            cons(12,
                cons(13,
                    cons(14,
                        cons(15, null)))));
        mulMappedCons = cons(10,
            cons(20,
                cons(30,
                    cons(40,
                        cons(50, null)))));
        filteredCons = cons(2,
            cons(4, null));
        emptyFilteredCons = cons(null, null);
    });
    suite('list', function(){
        test('list', function(){
            assert.ok(equal(consList, linkedList));
        });
        test('length', function(){
            assert.equal(length(linkedList), 5);
            assert.equal(length(linkedList2), 5);
            assert.equal(length(linkedList3), 9);
            assert.equal(length(linkedList4), 5);
            assert.equal(length(linkedList5), 9);
            assert.equal(length(zipped1), 5);
            assert.equal(length(zipped2), 9);
            assert.equal(length(linkedListP1), 6);
            assert.equal(length(linkedListP2), 7);
            assert.equal(length(linkedListE1), 6);
            assert.equal(length(linkedListE2), 7);
        });
        test('range', function(){
            assert.ok(equal(range1, linkedList));
            assert.ok(equal(range2, linkedList3));
            assert.ok(equal(range3, linkedListP2));
            assert.ok(equal(steprange, linkedList5));

            assert.equal(badrange, null);
            assert.equal(length(range1), 5);
            assert.equal(length(range2), 9);
            assert.equal(length(range3), 7);
            assert.equal(length(range4), 30);
            assert.equal(length(steprange), 9);
        });
        test('reverse', function(){
            assert.ok(equal(reverse(linkedList), range(5,0,-1)));
            assert.ok(equal(reverse(linkedList2), range(10,5,-1)));
            assert.ok(equal(reverse(linkedList3), range(14,5,-1)));
            assert.ok(equal(reverse(linkedList4), range(55,10,-11)));
            assert.ok(equal(reverse(linkedList5), range(99,10,-11)));
            assert.ok(equal(reverse(linkedList), list(5,4,3,2,1)));
            assert.ok(equal(reverse(linkedList2), list(10,9,8,7,6)));
            assert.ok(equal(reverse(linkedList3), list(14,13,12,11,10,9,8,7,6)));
            assert.ok(equal(reverse(linkedList4), list(55,44,33,22,11)));
            assert.ok(equal(reverse(linkedList5), list(99,88,77,66,55,44,33,22,11)));

            assert.ok(equal(reverse(zipped1),list(cons(10,55),cons(9,44),cons(8,33),cons(7,22), cons(6,11))));
            assert.ok(equal(reverse(zipped2),list(
                cons(99,14),cons(88,13),cons(77,12),cons(66,11),
                cons(55,10),cons(44,9),cons(33,8),cons(22,7),cons(11,6)
                )
            ));
        });
        test('map', function(){
            assert.ok(equal(addMapped, addMappedCons));
            assert.ok(equal(mulMapped, mulMappedCons));
        });
        test('filter', function(){
            assert.ok(equal(filtered, filteredCons));
            assert.equal(emptyFiltered, null);
        });
        test('reduce', function(){
            assert.equal(reduceAdd, 15);
            assert.equal(reduceMul, 120);
        });
        test('peek', function(){
            assert.equal(peek(linkedList), 5);
            assert.equal(peek(linkedListP1), 6);
            assert.equal(peek(linkedListP2), 7);
        });
        test('push', function(){
            assert.ok(equal(linkedListP1, pushed1));
            assert.ok(equal(linkedListP2, pushed2));
        });
        test('pop', function(){
            assert.ok(equal(linkedListP1, popped1));
            assert.ok(equal(linkedList, popped2));
        });
        test('reverse', function(){
            assert.ok(equal(reverse(linkedList), range(5,0,-1)));
            assert.ok(equal(reverse(linkedList2), range(10,5,-1)));
            assert.ok(equal(reverse(linkedList3), range(14,5,-1)));
            assert.ok(equal(reverse(linkedList4), range(55,10,-11)));
            assert.ok(equal(reverse(linkedList5), range(99,10,-11)));
            assert.ok(equal(reverse(linkedList), list(5,4,3,2,1)));
            assert.ok(equal(reverse(linkedList2), list(10,9,8,7,6)));
            assert.ok(equal(reverse(linkedList3), list(14,13,12,11,10,9,8,7,6)));
            assert.ok(equal(reverse(linkedList4), list(55,44,33,22,11)));
            assert.ok(equal(reverse(linkedList5), list(99,88,77,66,55,44,33,22,11)));
        });
        test('enqueue', function(){
            assert.ok(equal(linkedListE1, enqueue1));
            assert.ok(equal(linkedListE2, enqueue2));
        });
        test('dequeue', function(){
            assert.ok(equal(linkedListE1, dequeue1));
            assert.ok(equal(linkedList, dequeue2));
        });
    });
});<|endoftext|>


<commit_before>/**
 * Copyright 2015 CANAL+ Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { expect } from "chai";
import sinon from "sinon";

import RxPlayer from "../../../src";

import {
  manifestInfos,
  URLs,
} from "../contents/DASH_static_SegmentTimeline";
import sleep from "../utils/sleep.js";
import mockRequests from "../utils/mock_requests";
import /* waitForState, */ {
  waitForLoadedStateAfterLoadVideo,
} from "../utils/waitForPlayerState";

describe("loadVideo Options", () => {
  let player;
  let fakeServer;

  beforeEach(() => {
    player = new RxPlayer();
    fakeServer = sinon.fakeServer.create();
    fakeServer.autoRespond = true;
    mockRequests(fakeServer, URLs);
  });

  afterEach(() => {
    player.dispose();
    fakeServer.restore();
  });

  describe("url", () => {
    it("should throw if no url is given", () => {
      expect(() => {
        player.loadVideo();
      }).to.throw();
      expect(() => {
        player.loadVideo({ transport: "dash", autoPlay: true });
      }).to.throw();
    });

    it("should request the URL if one is given", async () => {
      player.loadVideo({
        url: manifestInfos.url,
        transport: "dash",
        autoPlay: true,
      });

      await sleep(0);

      expect(fakeServer.requests.length).to.equal(1);
      expect(fakeServer.requests[0].url).to.equal(manifestInfos.url);
    });
  });

  describe("transport", () => {
    it("should throw if no transport is given", () => {
      expect(() => {
        player.loadVideo();
      }).to.throw();
      expect(() => {
        player.loadVideo({ url: manifestInfos.url });
      }).to.throw();
      expect(() => {
        player.loadVideo({ url: manifestInfos.url, autoPlay: true });
      }).to.throw();
    });
  });

  describe("autoPlay", () => {
    it("should keep state as LOADED (and not play) if autoPlay is not set", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
      await sleep(200);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
    });

    it("should keep state as LOADED (and not play) if autoPlay is false", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
        autoPlay: false,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
      await sleep(200);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
    });

    it("should set state as LOADED then to PLAYING (and play) if autoPlay is true", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
        autoPlay: true,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("PLAYING");
      expect(player.getPosition()).to.equal(0);
      await sleep(200);
      expect(player.getPosition()).to.be.above(0.100);
    });
  });

  describe("startAt", () => {
    describe("non-linear", () => {
      it("should seek at the right position if startAt.position is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { position: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.wallClockTime is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { wallClockTime: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.fromFirstPosition is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { fromFirstPosition: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMinimumPosition() + startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.fromLastPosition is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { fromLastPosition: - startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() - startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.percentage is set", async function () {
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { percentage: 30 },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() * 0.3, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position then play if startAt.position and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { position: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.wallClockTime and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { wallClockTime: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.fromFirstPosition and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { fromFirstPosition: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMinimumPosition() + startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.fromLastPosition and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { fromLastPosition: - startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() - startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.percentage and autoPlay is set", async function () {
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { percentage: 30 },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() * 0.3, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });
    });
  });
});
<commit_msg>tests: add more tolerance to "should set state as LOADED then to PLAYING (and play) if autoPlay is true"<commit_after>/**
 * Copyright 2015 CANAL+ Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { expect } from "chai";
import sinon from "sinon";

import RxPlayer from "../../../src";

import {
  manifestInfos,
  URLs,
} from "../contents/DASH_static_SegmentTimeline";
import sleep from "../utils/sleep.js";
import mockRequests from "../utils/mock_requests";
import /* waitForState, */ {
  waitForLoadedStateAfterLoadVideo,
} from "../utils/waitForPlayerState";

describe("loadVideo Options", () => {
  let player;
  let fakeServer;

  beforeEach(() => {
    player = new RxPlayer();
    fakeServer = sinon.fakeServer.create();
    fakeServer.autoRespond = true;
    mockRequests(fakeServer, URLs);
  });

  afterEach(() => {
    player.dispose();
    fakeServer.restore();
  });

  describe("url", () => {
    it("should throw if no url is given", () => {
      expect(() => {
        player.loadVideo();
      }).to.throw();
      expect(() => {
        player.loadVideo({ transport: "dash", autoPlay: true });
      }).to.throw();
    });

    it("should request the URL if one is given", async () => {
      player.loadVideo({
        url: manifestInfos.url,
        transport: "dash",
        autoPlay: true,
      });

      await sleep(0);

      expect(fakeServer.requests.length).to.equal(1);
      expect(fakeServer.requests[0].url).to.equal(manifestInfos.url);
    });
  });

  describe("transport", () => {
    it("should throw if no transport is given", () => {
      expect(() => {
        player.loadVideo();
      }).to.throw();
      expect(() => {
        player.loadVideo({ url: manifestInfos.url });
      }).to.throw();
      expect(() => {
        player.loadVideo({ url: manifestInfos.url, autoPlay: true });
      }).to.throw();
    });
  });

  describe("autoPlay", () => {
    it("should keep state as LOADED (and not play) if autoPlay is not set", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
      await sleep(200);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
    });

    it("should keep state as LOADED (and not play) if autoPlay is false", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
        autoPlay: false,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
      await sleep(200);
      expect(player.getPlayerState()).to.equal("LOADED");
      expect(player.getPosition()).to.equal(0);
    });

    it("should set state as LOADED then to PLAYING (and play) if autoPlay is true", async () => {
      player.loadVideo({
        transport: manifestInfos.transport,
        url: manifestInfos.url,
        autoPlay: true,
      });
      await waitForLoadedStateAfterLoadVideo(player);
      expect(player.getPlayerState()).to.equal("PLAYING");
      expect(player.getPosition()).to.equal(0);
      await sleep(300);
      expect(player.getPosition()).to.be.above(0.100);
    });
  });

  describe("startAt", () => {
    describe("non-linear", () => {
      it("should seek at the right position if startAt.position is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { position: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.wallClockTime is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { wallClockTime: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.fromFirstPosition is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { fromFirstPosition: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMinimumPosition() + startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.fromLastPosition is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { fromLastPosition: - startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() - startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position if startAt.percentage is set", async function () {
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: false,
          startAt: { percentage: 30 },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("LOADED");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() * 0.3, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.equal(initialPosition);
      });

      it("should seek at the right position then play if startAt.position and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { position: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.wallClockTime and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { wallClockTime: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be.closeTo(startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.fromFirstPosition and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { fromFirstPosition: startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMinimumPosition() + startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.fromLastPosition and autoPlay is set", async function () {
        const startAt = 10;
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { fromLastPosition: - startAt },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() - startAt, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });

      it("should seek at the right position then play if startAt.percentage and autoPlay is set", async function () {
        player.loadVideo({
          transport: manifestInfos.transport,
          url: manifestInfos.url,
          autoPlay: true,
          startAt: { percentage: 30 },
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getPlayerState()).to.equal("PLAYING");
        const initialPosition = player.getPosition();
        expect(initialPosition).to.be
          .closeTo(player.getMaximumPosition() * 0.3, 0.5);
        await sleep(500);
        expect(player.getPosition()).to.be.above(initialPosition);
      });
    });
  });
});
<|endoftext|>


<commit_before>
var os = require('os');
var child_process = require('child_process');

var kaltura = module.exports = require('../KalturaManager');

var KalturaSegmentManager = function(config){
	if(config)
		this.init(config);
};
util.inherits(KalturaSegmentManager, kaltura.KalturaManager);

KalturaSegmentManager.prototype.execCut = function(segmentId, offset, portion, paths){
	var outputPath = os.tmpdir() + '/' + segmentId;

	var ffmpegPath = 'ffmpeg';
	var ffprobePath = 'ffprobe';
	if(this.config.segment.ffmpegPath){
		ffmpegPath = this.config.segment.ffmpegPath;
	}
	if(this.config.segment.ffprobePath){
		ffprobePath = this.config.segment.ffprobePath;
	}

	var cmd = [
		'bin/ts_cutter',
		outputPath,
		ffmpegPath,
		ffprobePath,
		offset,
		portion
	];
	cmd = cmd.concat(paths).join(' ');

	var childProcess = child_process.exec(cmd, function (error, stdout, stderr) {
		KalturaLogger.log('cmd: ' + cmd);
		KalturaLogger.log('stdout: ' + stdout);

		if(stderr.length){
			KalturaLogger.error('cmd: ' + cmd);
			KalturaLogger.error('stderr: ' + stderr);
		}

	    if (error !== null) {
	    	KalturaLogger.error('exec error: ' + error);
	    }
	});

	KalturaLogger.log('Started ts cutter process [' + childProcess.process.pid + ']');
};

KalturaSegmentManager.prototype.cut = function(request, response, params){
	params = this.parsePlayServerParams(response, params, ['segmentId', 'url1', 'url2', 'url3', 'offset', 'portion']);
	if(!params)
		return;

	KalturaLogger.dir(params);

	var This = this;
	var urls = [params.url1, params.url2, params.url3];
	this.downloadMultiHttpUrls(urls, null, function(localPaths){
		KalturaLogger.log('Request [' + response.requestId + '] handled');
		response.writeHead(200);
		response.end('OK');

		This.execCut(params.segmentId, params.offset, params.portion);
	},
	function(err){
		This.errorResponse(response, 500, err);
	});
};

module.exports.KalturaSegmentManager = KalturaSegmentManager;
<commit_msg>Use bin config section<commit_after>
var os = require('os');
var child_process = require('child_process');

var kaltura = module.exports = require('../KalturaManager');

var KalturaSegmentManager = function(config){
	if(config)
		this.init(config);
};
util.inherits(KalturaSegmentManager, kaltura.KalturaManager);

KalturaSegmentManager.prototype.execCut = function(segmentId, offset, portion, paths){
	var outputPath = os.tmpdir() + '/' + segmentId;

	var ffmpegPath = 'ffmpeg';
	var ffprobePath = 'ffprobe';
	if(this.config.bin.ffmpegPath){
		ffmpegPath = this.config.bin.ffmpegPath;
	}
	if(this.config.segment.ffprobePath){
		ffprobePath = this.config.bin.ffprobePath;
	}

	var cmd = [
		'bin/ts_cutter',
		outputPath,
		ffmpegPath,
		ffprobePath,
		offset,
		portion
	];
	cmd = cmd.concat(paths).join(' ');

	var childProcess = child_process.exec(cmd, function (error, stdout, stderr) {
		KalturaLogger.log('cmd: ' + cmd);
		KalturaLogger.log('stdout: ' + stdout);

		if(stderr.length){
			KalturaLogger.error('cmd: ' + cmd);
			KalturaLogger.error('stderr: ' + stderr);
		}

	    if (error !== null) {
	    	KalturaLogger.error('exec error: ' + error);
	    }
	});

	KalturaLogger.log('Started ts cutter process [' + childProcess.process.pid + ']');
};

KalturaSegmentManager.prototype.cut = function(request, response, params){
	params = this.parsePlayServerParams(response, params, ['segmentId', 'url1', 'url2', 'url3', 'offset', 'portion']);
	if(!params)
		return;

	KalturaLogger.dir(params);

	var This = this;
	var urls = [params.url1, params.url2, params.url3];
	this.downloadMultiHttpUrls(urls, null, function(localPaths){
		KalturaLogger.log('Request [' + response.requestId + '] handled');
		response.writeHead(200);
		response.end('OK');

		This.execCut(params.segmentId, params.offset, params.portion);
	},
	function(err){
		This.errorResponse(response, 500, err);
	});
};

module.exports.KalturaSegmentManager = KalturaSegmentManager;
<|endoftext|>


<commit_before>/*
 *  `config` module
 *  ===============
 *
 *  The game instance settings.
 */

//  Import created game scenes.
import * as scenes from '@/scenes';

/**
 *  Game canvas width.
 */
export const width = 640;

/**
 *  Game canvas height.
 */
export const height = 360;

/**
 *  Adjust zoom factor.
 */
export const zoom = 1;

/**
 *  Adjust pixel density of game graphics.
 */
export const resolution = 1;

/**
 *  Choose a rendering method.
 *
 *  Available options are:
 *
 *    - `WEBGL`: Use WebGL rendering;
 *    - `CANVAS`: Use 'context2D' API rendering method;
 *    - `AUTO`: Phaser will choose, based on device capabilities, the best
 *      rendering method to be used.
 */
export const type = Phaser.AUTO;

/**
 *  Whether to disable antialiasing or not. Great for pixel art.
 */
export const pixelArt = false;

/**
 *  Whether to enable canvas transparency or not.
 */
export const transparent = false;

/**
 *  Apply some style to the canvas element.
 */
export const canvasStyle = 'display: block; margin: 0 auto;';

/**
 *  Define a default a background color.
 */
export const backgroundColor = '#bfcc00';

/**
 *  Configure physics engines global parameters.
 *
 *  Available systems are:
 *
 *    - `arcade`: Phaser Arcade Physics 2;
 *    - `matter`: Liam Brummitt's (@liabru) Matter.js;
 *    - `impact`: ImpactJS Physics Engine.
 */
export const physics = {
  /**
   *  Enable a physics engine by default on all game scenes.
   */
  default: false,

  /**
   *  Phaser Arcade Physics 2 parameters.
   *
   *  This engine becomes available under a `physics` property on game scenes.
   */
  // arcade: {
  // },

  /**
   *  Matter.js parameters.
   *
   *  This engine becomes available under a `matter` property on game scenes.
   */
  // matter: {
  // },

  /**
   *  Impact Physics Engine parameters.
   *
   *  This engine becomes available under a `impact` property on game scenes.
   */
  // impact: {
  // }
};

/**
 *  Global parameters of the asset manager.
 */
export const loader = {
  //  HINT: Put all your game assets in the `app/static/assets/` directory.
  path: 'assets/'
};

/**
 *  Export the game title, version and Web address, as defined in the
 *  project package metadata file (`package.json`).
 *
 *  These properties can be accessed in the game configuration object
 *  (`scene.sys.game.config`), under the keys `gameTitle`, `gameVersion` and
 *  `gameURL`, respectively.
 */
export {title, version, url} from '@/../../package.json';

/**
 *  Export created game scenes.
 */
export const scene = Object.values(scenes);
<commit_msg>Fixed a lint issue and removed annotated blocks.<commit_after>/*
 *  `config` module
 *  ===============
 *
 *  The game instance settings.
 */

//  Import created game scenes.
import * as scenes from '@/scenes';

/**
 *  Game canvas width.
 */
export const width = 640;

/**
 *  Game canvas height.
 */
export const height = 360;

/**
 *  Adjust zoom factor.
 */
export const zoom = 1;

/**
 *  Adjust pixel density of game graphics.
 */
export const resolution = 1;

/**
 *  Choose a rendering method.
 *
 *  Available options are:
 *
 *    - `WEBGL`: Use WebGL rendering;
 *    - `CANVAS`: Use 'context2D' API rendering method;
 *    - `AUTO`: Phaser will choose, based on device capabilities, the best
 *      rendering method to be used.
 */
export const type = Phaser.AUTO;

/**
 *  Whether to disable antialiasing or not. Great for pixel art.
 */
export const pixelArt = false;

/**
 *  Whether to enable canvas transparency or not.
 */
export const transparent = false;

/**
 *  Apply some style to the canvas element.
 */
export const canvasStyle = 'display: block; margin: 0 auto;';

/**
 *  Define a default a background color.
 */
export const backgroundColor = '#bfcc00';

/**
 *  Configure physics engines global parameters.
 *
 *  Available systems are:
 *
 *    - `arcade`: Phaser Arcade Physics 2;
 *    - `matter`: Liam Brummitt's (@liabru) Matter.js;
 *    - `impact`: ImpactJS Physics Engine.
 */
export const physics = {
  /**
   *  Enable a physics engine by default on all game scenes.
   */
  default: false
};

/**
 *  Global parameters of the asset manager.
 */
export const loader = {
  //  HINT: Put all your game assets in the `app/static/assets/` directory.
  path: 'assets/'
};

/**
 *  Export the game title, version and Web address, as defined in the
 *  project package metadata file (`package.json`).
 *
 *  These properties can be accessed in the game configuration object
 *  (`scene.sys.game.config`), under the keys `gameTitle`, `gameVersion` and
 *  `gameURL`, respectively.
 */
export {title, version, url} from '@/../../package.json';

/**
 *  Export created game scenes.
 */
export const scene = Object.values(scenes);
<|endoftext|>


<commit_before>/*
 * loop.js
 *
 * Promise & setTimeout not run when inside signal callback
 * https://github.com/romgrk/node-gtk/issues/121
 */

const gi = require('..')
const GLib = gi.require('GLib', '2.0')
const Gtk = gi.require('Gtk', '4.0')
const { expect, assert } = require('./__common__')

const events = []
const expectedEvents = [
  'realize',
  'clicked',
  'promise:start-before',
  'clicked:settimeout',
  'clicked:promise-settimeout',
  'clicked:promise-resolved',
]

const loop = GLib.MainLoop.new(null, false)
const app = new Gtk.Application('com.github.romgrk.node-gtk.demo', 0)
app.on('activate', onActivate)

let window
let actionButton

let resolve
const action = new Promise(r => { resolve = r })
action.then(() => {
  events.push('promise:start-before')
})

setTimeout(() => {
  if (window) window.close()
  assert(false, 'Timeout should not be reached')
}, 2000).unref()

const status = app.run([])

console.log('Finished with status:', status)
console.log(events)
assert(
  events.every((e, i) => e === expectedEvents[i]),
  `Wrong events: ${JSON.stringify(events)}`
)

function onActivate() {
  window = new Gtk.ApplicationWindow(app)
  window.setTitle('Window')
  window.setDefaultSize(200, 200)
  window.on('close-request', onQuit)
  window.on('realize', onRealize)

  const ui = `
    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <requires lib="gtk" version="4.0"/>
      <object class="GtkBox" id="root">
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="actionButton">
            <property name="label" translatable="yes">Action</property>
            <property name="receives_default">1</property>
          </object>
        </child>
      </object>
    </interface>
  `

  const builder = Gtk.Builder.newFromString(ui, ui.length)
  const root = builder.getObject('root')

  actionButton = builder.getObject('actionButton')
  actionButton.on('clicked', () => {
    events.push('clicked')

    // this runs, and promise is resolved
    let action = new Promise(resolve => {
      setTimeout(
        () => {
          events.push('clicked:promise-settimeout')
          resolve()
        },
        100
      )
    })

    setTimeout(() => {
      events.push('clicked:settimeout')
    }, 50)

    action.then(() => {
      events.push('clicked:promise-resolved')
      window.close()
    })
  })

  window.setChild(root)
  window.present()

  resolve()
  gi.startLoop()
  loop.run()
}

function onRealize() {
  events.push('realize')
  actionButton.emit('clicked')
}

function onQuit() {
  loop.quit()
  return false
}
<commit_msg>tests: use gtk3 only<commit_after>/*
 * loop.js
 *
 * Promise & setTimeout not run when inside signal callback
 * https://github.com/romgrk/node-gtk/issues/121
 */

const gi = require('..')
const GLib = gi.require('GLib', '2.0')
const Gtk = gi.require('Gtk', '3.0')
const { expect, assert } = require('./__common__')

Gtk.init([])

const events = []
const expectedEvents = [
  'realize',
  'clicked',
  'promise:start-before',
  'clicked:settimeout',
  'clicked:promise-settimeout',
  'clicked:promise-resolved',
]

const loop = GLib.MainLoop.new(null, false)
const app = new Gtk.Application('com.github.romgrk.node-gtk.demo', 0)
app.on('activate', onActivate)

let window
let actionButton

let resolve
const action = new Promise(r => { resolve = r })
action.then(() => {
  events.push('promise:start-before')
})

setTimeout(() => {
  if (window) window.close()
  assert(false, 'Timeout should not be reached')
}, 2000).unref()

const status = app.run([])

console.log('Finished with status:', status)
console.log(events)
assert(
  events.every((e, i) => e === expectedEvents[i]),
  `Wrong events: ${JSON.stringify(events)}`
)

function onActivate() {
  window = new Gtk.ApplicationWindow(app)
  window.setTitle('Window')
  window.setDefaultSize(200, 200)
  window.on('delete-event', onQuit)
  window.on('realize', onRealize)

  const ui = `
    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <requires lib="gtk" version="4.0"/>
      <object class="GtkBox" id="root">
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="actionButton">
            <property name="label" translatable="yes">Action</property>
            <property name="receives_default">1</property>
          </object>
        </child>
      </object>
    </interface>
  `

  const builder = Gtk.Builder.newFromString(ui, ui.length)
  const root = builder.getObject('root')

  actionButton = builder.getObject('actionButton')
  actionButton.on('clicked', () => {
    events.push('clicked')

    // this runs, and promise is resolved
    let action = new Promise(resolve => {
      setTimeout(
        () => {
          events.push('clicked:promise-settimeout')
          resolve()
        },
        100
      )
    })

    setTimeout(() => {
      events.push('clicked:settimeout')
    }, 50)

    action.then(() => {
      events.push('clicked:promise-resolved')
      window.close()
    })
  })

  window.add(root)
  window.present()

  resolve()
  gi.startLoop()
  loop.run()
}

function onRealize() {
  events.push('realize')
  actionButton.emit('clicked')
}

function onQuit() {
  loop.quit()
  return false
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
'use strict';

var API = (function() {
    var _self;

    _self = {
        SW : {
            Contacts : require('lib/API.Contacts'),
            Calendar : '',
            FileSystem : '',
            DataBase : '',
            Log : '',
            Map : '',
            Notification : '',
            Social : ''
        },
        HW : {
            //Acceloremeter : require('lib/API.Accelerometer'),
            Battery : require('lib/API.Battery'),
            Camera : '',
            GeoLocation : '',
            Gesture : '',
            Media : '',
            //Network : require('lib/API.Network'),
            System : require('lib/API.System')
        }
    };

    _self.events = {
        activeHandlers: {},
        availableEvents: {}
    };

    var _initEvents = function _initEvents() {
        var key, eventId, publicName, eventData, enventId;

        /* TODO new class eventData
         * API.Example.events = {
         *      'publicEventName': {
         *          event: 'titaniumeventname',
         *          listener: Ti.thePathToMethod.addEventListener
         *      }
         * };
         */

        for (key in _self.SW) {
            if (_self.SW[key].events) {
                for (eventId in _self.SW[key].events) {
                    publicName = enventId;
                    eventData = _self.SW[key].events[eventId];
                    _self.events.availableEvents[publicName] = eventData;
                }
            }
        }
        for (key in _self.HW) {
            if (_self.HW[key].events) {
                for (eventId in _self.HW[key].events) {
                    publicName = enventId;
                    eventData = _self.HW[key].events[eventId];
                    _self.events.availableEvents[publicName] = eventData;
                }
            }
        }
    };

    /** Transport to html a internal event
     * @param: {eventName} the name of the Titanium event.
     * @param: {data} event data.
     * @return : Bool true if success or false if error*/
    var _fireHTMLEvents = function _fireHTMLEvents(eventName, data) {
        var key, viewId, result;

        if (_self.events.activeHandlers[eventName]) {
            for (key in _self.events.activeHandlers[eventName].views) {
                viewId = _self.events.activeHandlers[eventName].views[key];
                // This event will be received by all listeners API.Commons
                Ti.App.fireEvent(eventName, data);
            }
            result = true;
        } else {
            result = false;
        }
        return result;
    };

    /** AddEventListener from a HTML view (througth APICommons.js TODO)
     * @param: {publicEvent} the public html name for the event.
     * @param: {viewId} the id of the interested html view.
     * @return : Bool true if success or false if error*/
    _self.events.addEventListener = function addEventListener(publicEvent, viewId) {
        var eventData, eventHandler;

        eventData = _self.events.availableEvents[publicEvent];
        if (!eventData) {
            // Public event doesn't exist
            return false;
        }
        if (_self.events.activeHandlers[publicEvent]) {
            // Main listener active yet
            _self.events.activeHandlers[publicEvent].nlisteners += 1;
            if (!_self.events.activeHandlers[publicEvent].views[viewId]) {
                _self.events.activeHandlers[publicEvent].views[viewId] = 0;
            }
            _self.events.activeHandlers[publicEvent].views[viewId] += 1 ;
        } else {
            // Create new handler
            eventHandler = function(theEvent, e) {
                _fireHTMLEvents.call(_self, theEvent, {
                        'level': e.level,
                        'state': e.state,
                        'type': e.type
                    }
                );
            }.bind(_self, publicEvent);

            // Inicialize handler for this event
            _self.events.availableEvents[publicEvent].listener.addEventListener(_self.events.availableEvents[publicEvent].event, eventHandler);
            _self.events.activeHandlers[publicEvent].handler = eventHandler;
            _self.events.activeHandlers[publicEvent].nlisteners = 1;
            _self.events.activeHandlers[publicEvent].views = {};
            _self.events.activeHandlers[publicEvent].views[viewId] = 1;
        }
    };

    /** RemoveEventListener from a HTML view (througth APICommons.js TODO)
     * @param: {publicEvent} the public html name for the event.
     * @param: {viewId} the id of the interested html view.
     * @return : Bool true if success or false if error*/
    _self.events.RemoveEventListener = function RemoveEventListener(publicEvent, viewId) {
        var eventData, eventHandler;

        eventData = _self.events.availableEvents[publicEvent];
        if (!eventData || !_self.events.activeHandlers[publicEvent]) {
            // Public event doesn't exist
            return false;
        }

        _self.events.activeHandlers[publicEvent].nlisteners -= 1;
        _self.events.activeHandlers[publicEvent].views[viewId] -= 1 ;
        _self.events.availableEvents[publicEvent].listener.removeEventListener(_self.events.availableEvents[publicEvent].event, _self.events.activeHandlers[publicEvent].handler);
    };

    /** Handler for the events from a HTML view througth APICommons.js
     * @param: {data} data = {
     *     'action': 'addEventListener'/'removeEventListener',
     *     'viewId': viewId
     * }
     **/
    _self.events.APIEventHandler = function APIEventHandler(data) {

        if (data.action === 'addEventListener') {
            _self.events.addEventListener(data.event, data.viewId);
        } else if (data.action === 'removeEventListener') {
            _self.events.removeEventListener(data.event, data.viewId);
        }
    };

    /** Handler for the API methods invocations from a HTML view througth APICommons.js
     * @param: {data} data = {
     *     'method': 'API.Example.getBlabla',
     *     'params': [param],
     *     'eventName': eventName
     * }
     **/
    _self.events.APIMethodHandler = function APIMethodHandler(data) {
        var result;

        if (data.method !== null && data.params == null) {
            result = _self[data.method.type][data.method.subapi][data.method.name]();
        } else if (data.method !== null && data.params !== null) {
            result = _self[data.method.type][data.method.subapi][data.method.name](data.params);
        } else {
            // Error. Method doesn't exist
            result = "Error. Unknown API method";
        }
        Ti.API.info('Evento de vuelta  deste API: ' + data.method.eventName + '_' + data.viewId + '_' + data.callId);
        Ti.API.info('con los datos: ' + result);
        var resultStringi = JSON.stringify(result);
        Ti.API.info('stringificados: ' + resultStringi);
        Ti.App.fireEvent(data.method.eventName + '_' + data.viewId + '_' + data.callId, {'returnedData': result});
    };

    _self.events.APIMethodAsyncHandler = function APIMethodAsyncHandler(data) {
        var result;

        var genericHandler = function(initialData, result) {
            Ti.App.fireEvent(data.method.eventName + '_' + data.viewId + '_' + data.callId, result);
        };

        if (data.method !== null && data.params == null) {
            _self[data.method.type][data.method.subapi][data.method.name](genericHandler.bind(_self, data));
        } else if (data.method !== null && data.params !== null) {
            result = _self[data.method.type][data.method.subapi][data.method.name](genericHandler.bind(_self, data), data.params);
        } else {
            // Error. Method doesn't exist
            result = "Error. Unknown API method";
        }
    };

    _self.init = function init() {
        _initEvents(_self);
        Ti.App.addEventListener('APIEvent', _self.events.APIEventHandler);
        Ti.App.addEventListener('APIMethod', _self.events.APIMethodHandler);
        Ti.App.addEventListener('APIMethodAsync', _self.events.APIMethodAsyncHandler);
    };

    _self.init();

    return _self;

}());

module.exports = API;<commit_msg>[API] Lost 'require's restored<commit_after>/**
 * Copyright (c) 2014 by Center Open Middleware. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
'use strict';

var API = (function() {
    var _self;

    _self = {
        SW : {
            Contacts : require('lib/API.Contacts'),
            Calendar : '',
            FileSystem : require('lib/API.FileSystem'),
            DataBase : '',
            Log : '',
            Map : '',
            Notification : require('lib/API.Notification'),
            Social : ''
        },
        HW : {
            //Acceloremeter : require('lib/API.Accelerometer'),
            Battery : require('lib/API.Battery'),
            Camera : require('lib/API.Camera'),
            GeoLocation : '',
            Gesture : '',
            Media : '',
            //Network : require('lib/API.Network'),
            System : require('lib/API.System')
        }
    };

    _self.events = {
        activeHandlers: {},
        availableEvents: {}
    };

    var _initEvents = function _initEvents() {
        var key, eventId, publicName, eventData, enventId;

        /* TODO new class eventData
         * API.Example.events = {
         *      'publicEventName': {
         *          event: 'titaniumeventname',
         *          listener: Ti.thePathToMethod.addEventListener
         *      }
         * };
         */

        for (key in _self.SW) {
            if (_self.SW[key].events) {
                for (eventId in _self.SW[key].events) {
                    publicName = enventId;
                    eventData = _self.SW[key].events[eventId];
                    _self.events.availableEvents[publicName] = eventData;
                }
            }
        }
        for (key in _self.HW) {
            if (_self.HW[key].events) {
                for (eventId in _self.HW[key].events) {
                    publicName = enventId;
                    eventData = _self.HW[key].events[eventId];
                    _self.events.availableEvents[publicName] = eventData;
                }
            }
        }
    };

    /** Transport to html a internal event
     * @param: {eventName} the name of the Titanium event.
     * @param: {data} event data.
     * @return : Bool true if success or false if error*/
    var _fireHTMLEvents = function _fireHTMLEvents(eventName, data) {
        var key, viewId, result;

        if (_self.events.activeHandlers[eventName]) {
            for (key in _self.events.activeHandlers[eventName].views) {
                viewId = _self.events.activeHandlers[eventName].views[key];
                // This event will be received by all listeners API.Commons
                Ti.App.fireEvent(eventName, data);
            }
            result = true;
        } else {
            result = false;
        }
        return result;
    };

    /** AddEventListener from a HTML view (througth APICommons.js TODO)
     * @param: {publicEvent} the public html name for the event.
     * @param: {viewId} the id of the interested html view.
     * @return : Bool true if success or false if error*/
    _self.events.addEventListener = function addEventListener(publicEvent, viewId) {
        var eventData, eventHandler;

        eventData = _self.events.availableEvents[publicEvent];
        if (!eventData) {
            // Public event doesn't exist
            return false;
        }
        if (_self.events.activeHandlers[publicEvent]) {
            // Main listener active yet
            _self.events.activeHandlers[publicEvent].nlisteners += 1;
            if (!_self.events.activeHandlers[publicEvent].views[viewId]) {
                _self.events.activeHandlers[publicEvent].views[viewId] = 0;
            }
            _self.events.activeHandlers[publicEvent].views[viewId] += 1 ;
        } else {
            // Create new handler
            eventHandler = function(theEvent, e) {
                _fireHTMLEvents.call(_self, theEvent, {
                        'level': e.level,
                        'state': e.state,
                        'type': e.type
                    }
                );
            }.bind(_self, publicEvent);

            // Inicialize handler for this event
            _self.events.availableEvents[publicEvent].listener.addEventListener(_self.events.availableEvents[publicEvent].event, eventHandler);
            _self.events.activeHandlers[publicEvent].handler = eventHandler;
            _self.events.activeHandlers[publicEvent].nlisteners = 1;
            _self.events.activeHandlers[publicEvent].views = {};
            _self.events.activeHandlers[publicEvent].views[viewId] = 1;
        }
    };

    /** RemoveEventListener from a HTML view (througth APICommons.js TODO)
     * @param: {publicEvent} the public html name for the event.
     * @param: {viewId} the id of the interested html view.
     * @return : Bool true if success or false if error*/
    _self.events.RemoveEventListener = function RemoveEventListener(publicEvent, viewId) {
        var eventData, eventHandler;

        eventData = _self.events.availableEvents[publicEvent];
        if (!eventData || !_self.events.activeHandlers[publicEvent]) {
            // Public event doesn't exist
            return false;
        }

        _self.events.activeHandlers[publicEvent].nlisteners -= 1;
        _self.events.activeHandlers[publicEvent].views[viewId] -= 1 ;
        _self.events.availableEvents[publicEvent].listener.removeEventListener(_self.events.availableEvents[publicEvent].event, _self.events.activeHandlers[publicEvent].handler);
    };

    /** Handler for the events from a HTML view througth APICommons.js
     * @param: {data} data = {
     *     'action': 'addEventListener'/'removeEventListener',
     *     'viewId': viewId
     * }
     **/
    _self.events.APIEventHandler = function APIEventHandler(data) {

        if (data.action === 'addEventListener') {
            _self.events.addEventListener(data.event, data.viewId);
        } else if (data.action === 'removeEventListener') {
            _self.events.removeEventListener(data.event, data.viewId);
        }
    };

    /** Handler for the API methods invocations from a HTML view througth APICommons.js
     * @param: {data} data = {
     *     'method': 'API.Example.getBlabla',
     *     'params': [param],
     *     'eventName': eventName
     * }
     **/
    _self.events.APIMethodHandler = function APIMethodHandler(data) {
        var result;

        if (data.method !== null && data.params == null) {
            result = _self[data.method.type][data.method.subapi][data.method.name]();
        } else if (data.method !== null && data.params !== null) {
            result = _self[data.method.type][data.method.subapi][data.method.name](data.params);
        } else {
            // Error. Method doesn't exist
            result = "Error. Unknown API method";
        }
        Ti.API.info('Evento de vuelta  deste API: ' + data.method.eventName + '_' + data.viewId + '_' + data.callId);
        Ti.API.info('con los datos: ' + result);
        var resultStringi = JSON.stringify(result);
        Ti.API.info('stringificados: ' + resultStringi);
        Ti.App.fireEvent(data.method.eventName + '_' + data.viewId + '_' + data.callId, {'returnedData': result});
    };

    _self.events.APIMethodAsyncHandler = function APIMethodAsyncHandler(data) {
        var result;

        var genericHandler = function(initialData, result) {
            Ti.App.fireEvent(data.method.eventName + '_' + data.viewId + '_' + data.callId, result);
        };

        if (data.method !== null && data.params == null) {
            _self[data.method.type][data.method.subapi][data.method.name](genericHandler.bind(_self, data));
        } else if (data.method !== null && data.params !== null) {
            result = _self[data.method.type][data.method.subapi][data.method.name](genericHandler.bind(_self, data), data.params);
        } else {
            // Error. Method doesn't exist
            result = "Error. Unknown API method";
        }
    };

    _self.init = function init() {
        _initEvents(_self);
        Ti.App.addEventListener('APIEvent', _self.events.APIEventHandler);
        Ti.App.addEventListener('APIMethod', _self.events.APIMethodHandler);
        Ti.App.addEventListener('APIMethodAsync', _self.events.APIMethodAsyncHandler);
    };

    _self.init();

    return _self;

}());

module.exports = API;<|endoftext|>