<commit_before>import _ from 'lodash';
import { UPDATE_PAGE, REVERT_PAGE, PAGE_PUBLISH, PAGE_SCHEDULE, PAGE_UNPUBLISH, PAGE_UNSCHEDULE } from './mutationTypes';
import { save, create, getObject, removeText, remove, getHTML } from '../core-data/api';
import { add as addToQueue } from '../core-data/queue';
import { replaceVersion, pagesRoute, refProp, htmlExt, editExt, urisRoute, scheduleRoute } from '../utils/references';
import { uriToUrl, urlToUri } from '../utils/urls';
import logger from '../utils/log';

/**
 * @module page-data
 */

// saving these paths should NOT trigger a re-render of the page
const log = logger(__filename),
  internalPageProps = [
    'layout',
    'customUrl',
    'url',
    'urlHistory'
  ];

/**
 * iterate through the paths we're saving
 * if one of them ISN'T in the internalPageProps, we should re-render
 * @param  {array} paths
 * @return {boolean}
 */
function shouldRender(paths) {
  return !!_.find(paths, (path) => !_.includes(internalPageProps, path));
}

function logSaveError(uri, e, data, snapshot, store) { // eslint-disable-line
  log.error(`Error saving page: ${e.message}`, { action: 'savePage', uri });
  store.dispatch('showSnackbar', { type: 'error', message: 'Changes made to current page were not saved!' });
  store.dispatch('showSnackbar', {
    message: 'Error saving page',
    action: 'Retry',
    onActionClick: () => store.dispatch('savePage', data, snapshot)
  });
}

function queuePageSave(uri, data, oldData, store, {snapshot, paths}) { // eslint-disable-line
  return addToQueue(save, [uri, data, true], 'save')
    .then(() => getHTML(uri))
    .then((html) => {
      // note: we don't care about the data we got back from the api
      store.commit(UPDATE_PAGE, data);
      if (shouldRender(paths)) {
        return store.dispatch('render', { uri, html, snapshot, paths });
      }
    })
    .catch((e) => {
      store.commit(REVERT_PAGE, oldData);
      logSaveError(uri, e, data, snapshot, store);
      if (shouldRender(paths)) {
        return store.dispatch('render', { uri, html: document, snapshot, paths });
      }
    });
}

/**
 * save a page's data, but do not re-render
 * because, uh, that would just be reloading the page
 * @param  {object} store
 * @param  {*} data  to save
 * @param {boolean} [snapshot] false if we're undoing/redoing
 * @return {Promise}
 */
export function savePage(store, data, snapshot) {
  const oldData = _.get(store, 'state.page.data'),
    dataToSave = _.assign({}, oldData, data),
    uri = _.get(store, 'state.page.uri'),
    // figure out what properties we've changed
    // (note: this does a shallow comparison, not deep)
    paths = _.reduce(data, (result, val, key) => _.isEqual(val, oldData[key]) ? result : result.concat(key), []);

  store.dispatch('startProgress', 'save');

  return queuePageSave(uri, dataToSave, oldData, store, {snapshot, paths});
}

/**
 * create a new page, then return its editable link
 * @param  {object} store
 * @param  {string} id
 * @return {Promise}
 */
export function createPage(store, id) {
  const prefix = _.get(store, 'state.site.prefix');

  store.dispatch('startProgress', 'save');

  return getObject(`${prefix}${pagesRoute}${id}`)
    .then((data) => create(`${prefix}${pagesRoute}`, data))
    .then((newPage) => {
      store.dispatch('finishProgress', 'save');
      return `${uriToUrl(newPage[refProp])}${htmlExt}${editExt}`;
    })
    .catch((e) => {
      log.error(`Error creating page: ${e.message}`, { action: 'createPage', uri: `${prefix}${pagesRoute}${id}` });
      store.dispatch('finishProgress', 'error');
      store.dispatch('showSnackbar', 'Error creating page');
      throw e;
    });
}

/**
 * manually publish the page
 * @param  {object} store
 * @param  {string} uri
 * @return {Promise}
 */
export function publishPage(store, uri) {
  const scheduledPageUri = `${uri}@scheduled`,
    isScheduled = _.get(store, 'state.page.state.scheduled');

  let promise;

  store.dispatch('startProgress', 'published');

  // unschedule, then publish the page
  if (isScheduled) {
    promise = unschedule(scheduledPageUri).then(() => store.commit(PAGE_UNSCHEDULE));
  } else {
    promise = Promise.resolve(); // do nothing
  }

  return promise.then(() => {
    return addToQueue(save, [`${replaceVersion(uri, 'published')}`], 'published')
      .then((promises) => {
        const url = promises.page.url;

        store.commit(PAGE_PUBLISH, { url, date: new Date() });
        return url;
      });
  });
}

/**
 * remove uri from /uris/
 * @param  {String} uri
 * @param  {Object} store
 * @return {Promise}
 */
function removeURI(uri, store) {
  const prefix = _.get(store, 'state.site.prefix');

  return removeText(`${prefix}${urisRoute}${btoa(uri)}`);
}

/**
 * remove uri from /uris/
 * @param  {object} store
 * @param  {string} uri
 * @return {Promise}
 */
export function unpublishPage(store, uri) {
  store.dispatch('startProgress', 'published');
  return getObject(replaceVersion(uri, 'published'))
    .then((publishedData) => urlToUri(publishedData.url))
    .then((publishedURI) => removeURI(publishedURI, store))
    .then(() => store.commit(PAGE_UNPUBLISH))
    .then(() => store.dispatch('finishProgress', 'draft'));
}

/**
 * schedule the page to publish
 * @param  {object} store
 * @param  {string} uri
 * @param  {Date} timestamp
 * @return {Promise}
 */
export function schedulePage(store, { uri, timestamp }) {
  const prefix = _.get(store, 'state.site.prefix'),
    scheduleUri = `${prefix}${scheduleRoute}`;

  store.dispatch('startProgress', 'scheduled');
  return create(scheduleUri, {
    at: timestamp,
    publish: uriToUrl(uri)
  }).then(() => store.commit(PAGE_SCHEDULE, { date: timestamp }))
    .then(() => store.dispatch('finishProgress', 'scheduled'));
}

/**
 * unschedule the page
 * @param  {object} store
 * @return {Promise}
 */
export function unschedulePage(store) {
  const pageUri = `${_.get(store, 'state.page.uri')}@scheduled`;

  store.dispatch('startProgress', 'scheduled');
  return remove(pageUri)
    .then((res) => res[refProp])
    .then((scheduleEntry) => remove(scheduleEntry))
    .catch(_.noop)
    .then(() => store.commit(PAGE_UNSCHEDULE))
    .then(() => store.dispatch('finishProgress', 'scheduled'));
}
<commit_msg>hotfix syntax error in page publish<commit_after>import _ from 'lodash';
import { UPDATE_PAGE, REVERT_PAGE, PAGE_PUBLISH, PAGE_SCHEDULE, PAGE_UNPUBLISH, PAGE_UNSCHEDULE } from './mutationTypes';
import { save, create, getObject, removeText, remove, getHTML } from '../core-data/api';
import { add as addToQueue } from '../core-data/queue';
import { replaceVersion, pagesRoute, refProp, htmlExt, editExt, urisRoute, scheduleRoute } from '../utils/references';
import { uriToUrl, urlToUri } from '../utils/urls';
import logger from '../utils/log';

/**
 * @module page-data
 */

// saving these paths should NOT trigger a re-render of the page
const log = logger(__filename),
  internalPageProps = [
    'layout',
    'customUrl',
    'url',
    'urlHistory'
  ];

/**
 * iterate through the paths we're saving
 * if one of them ISN'T in the internalPageProps, we should re-render
 * @param  {array} paths
 * @return {boolean}
 */
function shouldRender(paths) {
  return !!_.find(paths, (path) => !_.includes(internalPageProps, path));
}

function logSaveError(uri, e, data, snapshot, store) { // eslint-disable-line
  log.error(`Error saving page: ${e.message}`, { action: 'savePage', uri });
  store.dispatch('showSnackbar', { type: 'error', message: 'Changes made to current page were not saved!' });
  store.dispatch('showSnackbar', {
    message: 'Error saving page',
    action: 'Retry',
    onActionClick: () => store.dispatch('savePage', data, snapshot)
  });
}

function queuePageSave(uri, data, oldData, store, {snapshot, paths}) { // eslint-disable-line
  return addToQueue(save, [uri, data, true], 'save')
    .then(() => getHTML(uri))
    .then((html) => {
      // note: we don't care about the data we got back from the api
      store.commit(UPDATE_PAGE, data);
      if (shouldRender(paths)) {
        return store.dispatch('render', { uri, html, snapshot, paths });
      }
    })
    .catch((e) => {
      store.commit(REVERT_PAGE, oldData);
      logSaveError(uri, e, data, snapshot, store);
      if (shouldRender(paths)) {
        return store.dispatch('render', { uri, html: document, snapshot, paths });
      }
    });
}

/**
 * save a page's data, but do not re-render
 * because, uh, that would just be reloading the page
 * @param  {object} store
 * @param  {*} data  to save
 * @param {boolean} [snapshot] false if we're undoing/redoing
 * @return {Promise}
 */
export function savePage(store, data, snapshot) {
  const oldData = _.get(store, 'state.page.data'),
    dataToSave = _.assign({}, oldData, data),
    uri = _.get(store, 'state.page.uri'),
    // figure out what properties we've changed
    // (note: this does a shallow comparison, not deep)
    paths = _.reduce(data, (result, val, key) => _.isEqual(val, oldData[key]) ? result : result.concat(key), []);

  store.dispatch('startProgress', 'save');

  return queuePageSave(uri, dataToSave, oldData, store, {snapshot, paths});
}

/**
 * create a new page, then return its editable link
 * @param  {object} store
 * @param  {string} id
 * @return {Promise}
 */
export function createPage(store, id) {
  const prefix = _.get(store, 'state.site.prefix');

  store.dispatch('startProgress', 'save');

  return getObject(`${prefix}${pagesRoute}${id}`)
    .then((data) => create(`${prefix}${pagesRoute}`, data))
    .then((newPage) => {
      store.dispatch('finishProgress', 'save');
      return `${uriToUrl(newPage[refProp])}${htmlExt}${editExt}`;
    })
    .catch((e) => {
      log.error(`Error creating page: ${e.message}`, { action: 'createPage', uri: `${prefix}${pagesRoute}${id}` });
      store.dispatch('finishProgress', 'error');
      store.dispatch('showSnackbar', 'Error creating page');
      throw e;
    });
}

/**
 * manually publish the page
 * @param  {object} store
 * @param  {string} uri
 * @return {Promise}
 */
export function publishPage(store, uri) {
  const scheduledPageUri = `${uri}@scheduled`,
    isScheduled = _.get(store, 'state.page.state.scheduled');

  let promise;

  store.dispatch('startProgress', 'published');

  // unschedule, then publish the page
  if (isScheduled) {
    promise = unschedule(scheduledPageUri).then(() => store.commit(PAGE_UNSCHEDULE));
  } else {
    promise = Promise.resolve(); // do nothing
  }

  return promise.then(() => {
    return addToQueue(save, [`${replaceVersion(uri, 'published')}`], 'published')
      .then((page) => {
        const url = page.url;

        store.commit(PAGE_PUBLISH, { url, date: new Date() });
        return url;
      });
  });
}

/**
 * remove uri from /uris/
 * @param  {String} uri
 * @param  {Object} store
 * @return {Promise}
 */
function removeURI(uri, store) {
  const prefix = _.get(store, 'state.site.prefix');

  return removeText(`${prefix}${urisRoute}${btoa(uri)}`);
}

/**
 * remove uri from /uris/
 * @param  {object} store
 * @param  {string} uri
 * @return {Promise}
 */
export function unpublishPage(store, uri) {
  store.dispatch('startProgress', 'published');
  return getObject(replaceVersion(uri, 'published'))
    .then((publishedData) => urlToUri(publishedData.url))
    .then((publishedURI) => removeURI(publishedURI, store))
    .then(() => store.commit(PAGE_UNPUBLISH))
    .then(() => store.dispatch('finishProgress', 'draft'));
}

/**
 * schedule the page to publish
 * @param  {object} store
 * @param  {string} uri
 * @param  {Date} timestamp
 * @return {Promise}
 */
export function schedulePage(store, { uri, timestamp }) {
  const prefix = _.get(store, 'state.site.prefix'),
    scheduleUri = `${prefix}${scheduleRoute}`;

  store.dispatch('startProgress', 'scheduled');
  return create(scheduleUri, {
    at: timestamp,
    publish: uriToUrl(uri)
  }).then(() => store.commit(PAGE_SCHEDULE, { date: timestamp }))
    .then(() => store.dispatch('finishProgress', 'scheduled'));
}

/**
 * unschedule the page
 * @param  {object} store
 * @return {Promise}
 */
export function unschedulePage(store) {
  const pageUri = `${_.get(store, 'state.page.uri')}@scheduled`;

  store.dispatch('startProgress', 'scheduled');
  return remove(pageUri)
    .then((res) => res[refProp])
    .then((scheduleEntry) => remove(scheduleEntry))
    .catch(_.noop)
    .then(() => store.commit(PAGE_UNSCHEDULE))
    .then(() => store.dispatch('finishProgress', 'scheduled'));
}
<|endoftext|>


<commit_before>var is = require('is');

var Promise = require('../utils/promise');
var Config = require('../models/config');

var File = require('../models/file');
var validateConfig = require('./validateConfig');
var CONFIG_FILES = require('../constants/configFiles');

/**
    Parse configuration from "book.json" or "book.js"

    @param {Book} book
    @return {Promise<Book>}
*/
function parseConfig(book) {
    var fs = book.getFS();

    return Promise.some(CONFIG_FILES, function(filename) {
        // Is this file ignored?
        if (book.isFileIgnored(filename)) {
            return;
        }

        // Try loading it
        return Promise.all([
            fs.loadAsObject(filename),
            fs.statFile(filename)
        ])
        .spread(function(cfg, file) {
            return {
                file: file,
                values: cfg
            };
        })
        .fail(function(err) {
            if (err.code != 'MODULE_NOT_FOUND') throw(err);
            else return Promise(false);
        });
    })

    .then(function(result) {
        var file = result? result.file : File();
        var values = result? result.values : {};

        values = validateConfig(values);

        var config = Config.create(file, values);
        return book.set('config', config);
    });
}

module.exports = parseConfig;
<commit_msg>lib/parse/parseConfig.js: Remove unused require<commit_after>var Promise = require('../utils/promise');
var Config = require('../models/config');

var File = require('../models/file');
var validateConfig = require('./validateConfig');
var CONFIG_FILES = require('../constants/configFiles');

/**
    Parse configuration from "book.json" or "book.js"

    @param {Book} book
    @return {Promise<Book>}
*/
function parseConfig(book) {
    var fs = book.getFS();

    return Promise.some(CONFIG_FILES, function(filename) {
        // Is this file ignored?
        if (book.isFileIgnored(filename)) {
            return;
        }

        // Try loading it
        return Promise.all([
            fs.loadAsObject(filename),
            fs.statFile(filename)
        ])
        .spread(function(cfg, file) {
            return {
                file: file,
                values: cfg
            };
        })
        .fail(function(err) {
            if (err.code != 'MODULE_NOT_FOUND') throw(err);
            else return Promise(false);
        });
    })

    .then(function(result) {
        var file = result? result.file : File();
        var values = result? result.values : {};

        values = validateConfig(values);

        var config = Config.create(file, values);
        return book.set('config', config);
    });
}

module.exports = parseConfig;
<|endoftext|>


<commit_before>"use strict";
/*global suite: false, test: false, setup: false*/

var assert = require('assert'),
    expector = require('../lib/expector'),
    cje = expector.test.checkJSONExpression;

suite('checkJSONExpresion', function() {
  test('$length', function(done) {
    assert(  cje({$length: 1}, [2]) );
    assert( !cje({$length: 1}, []) );
    assert( !cje({$length: 1}, [2, 3]) );
    assert(  cje({$length: 4}, [1, 2, 3, 4]) );

    done();
  });

  test('$unordered', function(done) {
    assert( cje({$unordered: [1, 2]}, [1, 2]) );
    assert( cje({$unordered: [1, 2]}, [2, 1]) );

    // FIXME: this seems like it should fail
    //assert(!cje({$unordered: [1, 2]}, [1, 2, 3]));

    assert( !cje({$unordered: [1, 2, 3]}, [1, 2]) );

    done();
  });

  test('comparisons', function(done) {
    assert(  cje({a: {$gt:  10}}, {a: 11}) );
    assert( !cje({a: {$gt:  10}}, {a: 10}) );
    assert( !cje({a: {$gt:  10}}, {a: 9})) ;

    assert(  cje({a: {$gte: 10}}, {a: 11}) );
    assert(  cje({a: {$gte: 10}}, {a: 10}) );
    assert( !cje({a: {$gte: 10}}, {a: 9})) ;

    assert( !cje({a: {$lt:  10}}, {a: 11}) );
    assert( !cje({a: {$lt:  10}}, {a: 10}) );
    assert(  cje({a: {$lt:  10}}, {a: 9})) ;

    assert( !cje({a: {$lte: 10}}, {a: 11}) );
    assert(  cje({a: {$lte: 10}}, {a: 10}) );
    assert(  cje({a: {$lte: 10}}, {a: 9})) ;
    done();
  });
});
<commit_msg>add combo and $int tests<commit_after>"use strict";
/*global suite: false, test: false, setup: false*/

var assert = require('assert'),
    expector = require('../lib/expector'),
    cje = expector.test.checkJSONExpression;

suite('checkJSONExpresion', function() {
  test('$length', function(done) {
    assert(  cje({$length: 1}, [2]) );
    assert( !cje({$length: 1}, []) );
    assert( !cje({$length: 1}, [2, 3]) );
    assert(  cje({$length: 4}, [1, 2, 3, 4]) );

    done();
  });

  test('$int', function(done) {
    assert(  cje({a: "$int"}, {a: 2}) );
    assert( !cje({a: "$int"}, {a: 1.5}) );
    done();
  });

  test('$unordered', function(done) {
    assert(  cje({$unordered: [1, 2]}, [1, 2]) );
    assert(  cje({$unordered: [1, 2]}, [2, 1]) );
    assert( !cje({$unordered: [1, 2, 3]}, [1, 2]) );

    done();
  });

  test('combos', function(done) {
    assert(  cje({$unordered: [1, 2], $length: 2}, [2, 1]) );
    assert( !cje({$unordered: [1, 2], $length: 3}, [2, 1]) );
    assert( !cje({$length: 2, $unordered: [1, 3]}, [2, 1]) );

    done();
  });

  test('comparisons', function(done) {
    assert(  cje({a: {$gt:  10}}, {a: 11}) );
    assert( !cje({a: {$gt:  10}}, {a: 10}) );
    assert( !cje({a: {$gt:  10}}, {a: 9})) ;

    assert(  cje({a: {$gte: 10}}, {a: 11}) );
    assert(  cje({a: {$gte: 10}}, {a: 10}) );
    assert( !cje({a: {$gte: 10}}, {a: 9})) ;

    assert( !cje({a: {$lt:  10}}, {a: 11}) );
    assert( !cje({a: {$lt:  10}}, {a: 10}) );
    assert(  cje({a: {$lt:  10}}, {a: 9})) ;

    assert( !cje({a: {$lte: 10}}, {a: 11}) );
    assert(  cje({a: {$lte: 10}}, {a: 10}) );
    assert(  cje({a: {$lte: 10}}, {a: 9})) ;
    done();
  });
});
<|endoftext|>


<commit_before>'use strict'
var currentState = require('../util/currentstate')
var Event = require('vigour-js/lib/event')
var Property = require('../property')
var scriptLoaded
var test = /\$vp/
var cnt = 0

Property = new Property({
  define: {
    compare (property, data, props, children, current, prev) {
      let key = property.key
      if (prev && prev.state.stamp === current.state.stamp) {
        currentState(key, current, prev)
        return true
      }
      let stamp = property.getStamp(data)
      if (prev) {
        if (prev.state.props[key] === stamp) {
          currentState(key, current, prev)
          return true
        }
      }
      currentState(key, current, prev)
      console.log(' ------> ', stamp, current.state.data)
      current.state.props[key] = stamp
    }
  }
}).Constructor

exports.Child = new Property({
  properties: {
    render (fn) {
      this.define({
        render () {
          if (this.parent.ready.val) {
            fn.apply(this, arguments)
          }
        }
      })
    }
  }
}).Constructor

exports.define = {
  // createStateProperty () {
  //   let define = {}
  //   for (let i = arguments.length - 1; i >= 0; i--) {
  //     let key = arguments[i]
  //     define[key] = {
  //       set (val) {
  //         if (this.state) {
  //           this.state.props[key] = val
  //         }
  //       },
  //       get () {
  //         return this.state && this.state.props[key]
  //       }
  //     }
  //   }
  //   this.define(define)
  // },
  initialised: {
    set (val) {
      if (this.state) {
        this.state.props.initialised = val
      }
    },
    get () {
      return this.state && this.state.props && this.state.props.initialised
    }
  },
  instance: {
    set (val) {
      if (this.state) {
        this.state.props.instance = val
      }
    },
    get () {
      return this.state && this.state.props.instance
    }
  },
  setTime: {
    set (val) {
      if (this.state) {
        this.state.props.setTime = val
      }
    },
    get () {
      return this.state && this.state.props.setTime
    }
  },
  loaded: {
    set (val) {
      scriptLoaded = val
    },
    get () {
      return scriptLoaded
    }
  }
}

exports.properties = {
  config: require('./config'),
  id: true,
  ready: new Property({
    $type: 'boolean',
    render (val, properties, children, rdata, current, previous) {
      console.error('READY:', val)
      let player = this.parent
      if (val) {
        console.log('LOADING false')
        player.loading.origin.set(false)
        player.volume.render(player.volume.val)
        player.playing.render(player.playing.val)
        player.time.render(player.state.data.time.val)
      } else {
        console.log('LOADING true')
        player.loading.origin.set(true)
      }
    }
  }),
  playing: new Property({
    $type: 'boolean',
    properties: {
      render (fn) {
        this.define({
          render (val) {
            var player = this.parent
            var ready = player.ready.val
            if (val) {
              // do the interval stuff
              if (ready && !player.interval) {
                let store = player.storeContext()
                player.interval = setInterval(function () {
                  player.applyContext(store)
                  if (player.setTime) {
                    player.setTime = null
                  } else if (player.ready.val) {
                    let time = player.getTime()
                    if (time) {
                      let stamp = '$vp' + (cnt++)
                      let event = new Event(
                        'data',
                        stamp
                      )
                      player.state.data.time.set(time, event)
                      event.trigger()
                    }
                  }
                }, 500)
              }
            } else if (player.interval) {
              clearInterval(player.interval)
              player.interval = null
              player.setTime = null
            }
            if (ready) {
              fn.apply(this, arguments)
            }
          }
        })
      }
    }
  }),
  time: new Property({
    $type: 'number',
    properties: {
      render (fn) {
        this.define({
          render (val, properties, children, rdata, current) {
            var player = this.parent
            if (player.ready.val && (!current || !test.test(current.state.stamp))) {
              player.setTime = val
              fn.apply(this, arguments)
            }
          }
        })
      }
    }
  }),
  src: new Property({
    $type: 'string',
    properties: {
      render (fn) {
        this.define({
          render (val, properties, children, rdata, current) {
            if (val) {
              var player = this.parent

              console.error('!!!!!!!!!!', player)

              if (player.initialised) {
                if (!test.test(current.state.stamp)) {
                  player.ready.origin.set(false)
                  player.ready.render(false)
                  fn.apply(this, arguments)
                }
              } else {
                player.init(val)
              }
            }
          }
        })
      }
    }
  }),
  duration: new exports.Child({
    $type: 'number'
  })
}
<commit_msg>no compate<commit_after>'use strict'
var currentState = require('../util/currentstate')
var Event = require('vigour-js/lib/event')
var Property = require('../property')
var scriptLoaded
var test = /\$vp/
var cnt = 0

Property = new Property({
  define: {
    compare (property, data, props, children, current, prev) {
      let key = property.key
      if (prev && prev.state.stamp === current.state.stamp) {
        currentState(key, current, prev)
        return true
      }
      let stamp = property.getStamp(data)
      if (prev) {
        if (prev.state.props[key] === stamp) {
          currentState(key, current, prev)
          return true
        }
      }
      currentState(key, current, prev)
      console.log(' ------> ', stamp, current.state.data)
      current.state.props[key] = stamp
    }
  }
}).Constructor

exports.Child = new Property({
  properties: {
    render (fn) {
      this.define({
        render () {
          if (this.parent.ready.val) {
            fn.apply(this, arguments)
          }
        }
      })
    }
  }
}).Constructor

exports.define = {
  // createStateProperty () {
  //   let define = {}
  //   for (let i = arguments.length - 1; i >= 0; i--) {
  //     let key = arguments[i]
  //     define[key] = {
  //       set (val) {
  //         if (this.state) {
  //           this.state.props[key] = val
  //         }
  //       },
  //       get () {
  //         return this.state && this.state.props[key]
  //       }
  //     }
  //   }
  //   this.define(define)
  // },
  initialised: {
    set (val) {
      if (this.state && this.state.props) {
        this.state.props.initialised = val
      }
    },
    get () {
      return this.state && this.state.props && this.state.props.initialised
    }
  },
  instance: {
    set (val) {
      if (this.state && this.state.props) {
        this.state.props.instance = val
      }
    },
    get () {
      return this.state && this.state.props.instance
    }
  },
  setTime: {
    set (val) {
      if (this.state && this.state.props) {
        this.state.props.setTime = val
      }
    },
    get () {
      return this.state && this.state.props.setTime
    }
  },
  loaded: {
    set (val) {
      scriptLoaded = val
    },
    get () {
      return scriptLoaded
    }
  }
}

exports.properties = {
  config: require('./config'),
  id: true,
  ready: new Property({
    $type: 'boolean',
    render (val, properties, children, rdata, current, previous) {
      console.error('READY:', val)
      let player = this.parent
      if (val) {
        console.log('LOADING false')
        player.loading.origin.set(false)
        player.volume.render(player.volume.val)
        player.playing.render(player.playing.val)
        player.time.render(player.state.data.time.val)
      } else {
        console.log('LOADING true')
        player.loading.origin.set(true)
      }
    }
  }),
  playing: new Property({
    $type: 'boolean',
    properties: {
      render (fn) {
        this.define({
          render (val) {
            var player = this.parent
            var ready = player.ready.val
            if (val) {
              // do the interval stuff
              if (ready && !player.interval) {
                let store = player.storeContext()
                player.interval = setInterval(function () {
                  player.applyContext(store)
                  if (player.setTime) {
                    player.setTime = null
                  } else if (player.ready.val) {
                    let time = player.getTime()
                    if (time) {
                      let stamp = '$vp' + (cnt++)
                      let event = new Event(
                        'data',
                        stamp
                      )
                      player.state.data.time.set(time, event)
                      event.trigger()
                    }
                  }
                }, 500)
              }
            } else if (player.interval) {
              clearInterval(player.interval)
              player.interval = null
              player.setTime = null
            }
            if (ready) {
              fn.apply(this, arguments)
            }
          }
        })
      }
    }
  }),
  time: new Property({
    $type: 'number',
    properties: {
      render (fn) {
        this.define({
          render (val, properties, children, rdata, current) {
            var player = this.parent
            if (player.ready.val && (!current || !test.test(current.state.stamp))) {
              player.setTime = val
              fn.apply(this, arguments)
            }
          }
        })
      }
    }
  }),
  src: new Property({
    $type: 'string',
    properties: {
      render (fn) {
        this.define({
          render (val, properties, children, rdata, current) {
            if (val) {
              var player = this.parent

              console.error('!!!!!!!!!!', player)

              if (player.initialised) {
                if (!test.test(current.state.stamp)) {
                  player.ready.origin.set(false)
                  player.ready.render(false)
                  fn.apply(this, arguments)
                }
              } else {
                player.init(val)
              }
            }
          }
        })
      }
    }
  }),
  duration: new exports.Child({
    $type: 'number'
  })
}
<|endoftext|>


<commit_before>'use strict';

// Module dependencies
const Application = require('../Application');
const utils = require('../utils');
const chalk = require('chalk');

// Constants
const logPrefix = chalk.blue.bold('  baiji:evaluator');

// Evaluator Plugin
module.exports = function evaluatorPlugin(app, options) {
  if (process.env.NODE_ENV === 'production') {
    utils.logWarning('evaluator plugin should not be used in production!');
  }

  options = options || {};
  let warningThreshold = options.warningThreshold || 20;

  function injectEvaluator(defaultName) {
    return function(hook) {
      return function(ctx, next) {
        let startedAt = +new Date();
        return hook(ctx, function() {
          let millis = +new Date() - startedAt;
          let name = (hook.name).replace(/^bound\ /, '').trim();
          name = name || defaultName || '<anonymous>';
          let message = `${name} TIME COMSUMPTION: +${millis} ms`;
          if (millis >= warningThreshold) {
            // eslint-disable-next-line no-console
            console.log(logPrefix, chalk.red(message));
          } else {
            // eslint-disable-next-line no-console
            console.log(logPrefix, chalk.green(message));
          }
          return next();
        });
      };
    };
  }

  // Hack composedMethods
  Application.prototype.composedMethods = function() {
    let beforeHooks = this.searchHooksByType('before');
    let afterHooks = this.searchHooksByType('after');
    let afterErrorHooks = this.searchHooksByType('afterError');

    let filter = utils.filterHooks;

    return this.allMethods().map((method) => {
      let name = method.fullName();

      let beforeStack = filter(beforeHooks, name).map(injectEvaluator());
      let afterStack = filter(afterHooks, name).map(injectEvaluator());
      let afterErrorStack = filter(afterErrorHooks, name).map(injectEvaluator());

      method.fn = injectEvaluator(name)(method.fn);

      method.compose(
        beforeStack,
        afterStack,
        afterErrorStack
      );

      return method;
    });
  };
};
<commit_msg>add more comments<commit_after>'use strict';

// Module dependencies
const Application = require('../Application');
const utils = require('../utils');
const chalk = require('chalk');

// Constants
const logPrefix = chalk.blue.bold('  baiji:evaluator');

// Evaluator Plugin
module.exports = function evaluatorPlugin(app, options) {
  if (process.env.NODE_ENV === 'production') {
    utils.logWarning('evaluator plugin should not be used in production!');
  }

  options = options || {};
  let warningThreshold = options.warningThreshold || 20;

  function injectEvaluator(defaultName) {
    return function(fn) {

      return function(ctx, next) {
        let startedAt = +new Date();

        return fn(ctx, function() {
          let millis = +new Date() - startedAt;

          let name = (fn.name).replace(/^bound\ /, '').trim();
          name = name || defaultName || '<anonymous>';

          let message = `${name} TIME COMSUMPTION: +${millis} ms`;

          if (millis >= warningThreshold) {
            // eslint-disable-next-line no-console
            console.log(logPrefix, chalk.red(message));
          } else {
            // eslint-disable-next-line no-console
            console.log(logPrefix, chalk.green(message));
          }
          return next();
        });
      };
    };
  }

  // Hack composedMethods
  Application.prototype.composedMethods = function() {
    let beforeHooks = this.searchHooksByType('before');
    let afterHooks = this.searchHooksByType('after');
    let afterErrorHooks = this.searchHooksByType('afterError');

    let filter = utils.filterHooks;

    // Loop and then inject evaluator into all methods and hooks
    return this.allMethods().map((method) => {
      let name = method.fullName();

      let beforeStack = filter(beforeHooks, name).map(injectEvaluator());
      let afterStack = filter(afterHooks, name).map(injectEvaluator());
      let afterErrorStack = filter(afterErrorHooks, name).map(injectEvaluator());

      method.fn = injectEvaluator(name)(method.fn);

      method.compose(
        beforeStack,
        afterStack,
        afterErrorStack
      );

      return method;
    });
  };
};
<|endoftext|>


<commit_before>import _ from 'lodash';
import nymagHbs from 'nymag-handlebars';
import { getComponentName, descProp, componentListProp, componentProp } from '../utils/references';
import deepReduce from '../utils/deep-reduce';
import { normalizeSiteData } from '../core-data/site';
import { PRELOAD_PENDING, PRELOAD_SUCCESS, LOADING_SUCCESS } from './mutationTypes';
import { START_PROGRESS, FINISH_PROGRESS } from '../toolbar/mutationTypes';
import getPageState from '../page/page-state';
import defaultState from './default-state';

const hbs = nymagHbs();

/**
 * get schema for a layout
 * @param  {object} schemas
 * @param  {string} layoutRef
 * @return {object}
 */
function getLayoutSchema(schemas, layoutRef) {
  return schemas[getComponentName(layoutRef)];
}

/**
 * extract component data from preloadData obj
 * @param  {obj} result
 * @param  {obj} val
 * @return {obj}
 */
function reduceComponents(result, val) {
  return deepReduce(result, val, function (ref, val) {
    result[ref] = val;
  });
}

/**
 * recursively reduce component refs,
 * producing objects with _parent and refs
 * @param  {string} parentUri
 * @return {object}
 */
function reduceDeepArea(parentUri) {
  return function (result, val) {
    return deepReduce(result, val, function (ref, data) {
      result[ref] = _.reduce(data, reduceDeepArea(ref), { _parent: parentUri });
    });
  };
}

/**
 * build tree of component references
 * @param {string} root uri (page or layout uri)
 * @param  {array} areas to check against
 * @return {object}
 */
function reduceDeepTree(root, areas) {
  return function (result, val, key) {
    if (_.includes(areas, key)) {
      const parentUri = root;

      _.reduce(val, reduceDeepArea(parentUri), result);
    }

    return result;
  };
}

/**
 * extract layout data from original data
 * @param  {object} layoutSchema schema for layout
 * @param  {object} components   key/value store of components
 * @param  {object} original     original preloaded data
 * @return {object}
 */
function composeLayoutData(layoutSchema, components, original) {
  const layoutData = _.reduce(layoutSchema, (result, val, key) => {
    const isPage = _.has(val, `${componentListProp}.page`),
      isList = _.has(val, componentListProp);

    if (isPage) {
      // if it's a page area, simply return the string alias
      result[key] = key; // note: assumes layout prop is the same as page area prop
    } else if (isList) {
      // if it's an actual layout component list, grab the data
      result[key] = original[key];
    }
    return result;
  }, {});

  return { [original._layoutRef]: layoutData };
}

/**
 * extract tree of component refs from preloadData obj
 * @param {object} original
 * @param {object} layoutSchema
 * @return {obj}
 */
function reduceTree(original, layoutSchema) {
  const pageAreas = _.filter(Object.keys(layoutSchema), function (key) {
      return key !== descProp && _.get(layoutSchema, `${key}.${componentListProp}.page`) || _.get(layoutSchema, `${key}.${componentProp}.page`);
    }),
    layoutAreas = _.filter(Object.keys(layoutSchema), function (key) {
      return key !== descProp && !_.includes(pageAreas, key);
    }),
    pageRoot = original._self,
    layoutRoot = original._layoutRef;

  return {
    [pageRoot]: _.reduce(original, reduceDeepTree(pageRoot, pageAreas), {}),
    [layoutRoot]: _.reduce(original, reduceDeepTree(layoutRoot, layoutAreas), {}),
  };
}

/**
 * make precompiled hbs templates ready for user
 * @param  {obj} result
 * @param  {obj} val
 * @param  {string} key
 * @return {obj}
 */
function reduceTemplates(result, val, key) {
  const tpl = hbs.template(val);

  hbs.registerPartial(key, tpl); // register template as partial
  result[key] = tpl; // and add it to the store
  return result;
}

/**
 * get string state to pass to progress bar
 * @param  {object} state
 * @return {string}
 */
function getPageStatus(state) {
  if (state.scheduled) {
    return 'scheduled';
  } else if (state.published) {
    return 'published';
  } else {
    return 'draft';
  }
}

export default function preload({ commit }) {
  const data = _.get(window, 'kiln.preloadData'),
    schemas = _.get(window, 'kiln.preloadSchemas'),
    locals = _.get(window, 'kiln.locals'),
    models = _.get(window, 'kiln.componentModels'),
    templates = _.get(window, 'kiln.componentTemplates'),
    user = locals && locals.user,
    site = locals && normalizeSiteData(locals.site),
    layoutSchema = getLayoutSchema(schemas, data._layoutRef),
    tabulaRasa = _.assign({}, defaultState),
    components = _.reduce(data, reduceComponents, {});

  commit(PRELOAD_PENDING);
  commit(START_PROGRESS, 'offline');

  return getPageState(data._self).then((pageState) => {
    commit(PRELOAD_SUCCESS, _.assign(tabulaRasa, {
      components: _.assign(components, composeLayoutData(layoutSchema, components, data)),
      tree: reduceTree(data, layoutSchema),
      page: {
        uri: data._self,
        data: data._pageData,
        state: pageState
      },
      user: user,
      schemas: schemas,
      locals: locals,
      models: models,
      templates: _.reduce(templates, reduceTemplates, {}),
      site: site
    }));
    commit(LOADING_SUCCESS);
    commit(FINISH_PROGRESS, getPageStatus(pageState));
  });
}
<commit_msg>Preloader action for hashing<commit_after>import _ from 'lodash';
import nymagHbs from 'nymag-handlebars';
import { getComponentName, descProp, componentListProp, componentProp } from '../utils/references';
import deepReduce from '../utils/deep-reduce';
import { normalizeSiteData } from '../core-data/site';
import { PRELOAD_PENDING, PRELOAD_SUCCESS, LOADING_SUCCESS } from './mutationTypes';
import { START_PROGRESS, FINISH_PROGRESS } from '../toolbar/mutationTypes';
import getPageState from '../page/page-state';
import defaultState from './default-state';

const hbs = nymagHbs();

/**
 * get schema for a layout
 * @param  {object} schemas
 * @param  {string} layoutRef
 * @return {object}
 */
function getLayoutSchema(schemas, layoutRef) {
  return schemas[getComponentName(layoutRef)];
}

/**
 * extract component data from preloadData obj
 * @param  {obj} result
 * @param  {obj} val
 * @return {obj}
 */
function reduceComponents(result, val) {
  return deepReduce(result, val, function (ref, val) {
    result[ref] = val;
  });
}

/**
 * recursively reduce component refs,
 * producing objects with _parent and refs
 * @param  {string} parentUri
 * @return {object}
 */
function reduceDeepArea(parentUri) {
  return function (result, val) {
    return deepReduce(result, val, function (ref, data) {
      result[ref] = _.reduce(data, reduceDeepArea(ref), { _parent: parentUri });
    });
  };
}

/**
 * build tree of component references
 * @param {string} root uri (page or layout uri)
 * @param  {array} areas to check against
 * @return {object}
 */
function reduceDeepTree(root, areas) {
  return function (result, val, key) {
    if (_.includes(areas, key)) {
      const parentUri = root;

      _.reduce(val, reduceDeepArea(parentUri), result);
    }

    return result;
  };
}

/**
 * extract layout data from original data
 * @param  {object} layoutSchema schema for layout
 * @param  {object} components   key/value store of components
 * @param  {object} original     original preloaded data
 * @return {object}
 */
function composeLayoutData(layoutSchema, components, original) {
  const layoutData = _.reduce(layoutSchema, (result, val, key) => {
    const isPage = _.has(val, `${componentListProp}.page`),
      isList = _.has(val, componentListProp);

    if (isPage) {
      // if it's a page area, simply return the string alias
      result[key] = key; // note: assumes layout prop is the same as page area prop
    } else if (isList) {
      // if it's an actual layout component list, grab the data
      result[key] = original[key];
    }
    return result;
  }, {});

  return { [original._layoutRef]: layoutData };
}

/**
 * extract tree of component refs from preloadData obj
 * @param {object} original
 * @param {object} layoutSchema
 * @return {obj}
 */
function reduceTree(original, layoutSchema) {
  const pageAreas = _.filter(Object.keys(layoutSchema), function (key) {
      return key !== descProp && _.get(layoutSchema, `${key}.${componentListProp}.page`) || _.get(layoutSchema, `${key}.${componentProp}.page`);
    }),
    layoutAreas = _.filter(Object.keys(layoutSchema), function (key) {
      return key !== descProp && !_.includes(pageAreas, key);
    }),
    pageRoot = original._self,
    layoutRoot = original._layoutRef;

  return {
    [pageRoot]: _.reduce(original, reduceDeepTree(pageRoot, pageAreas), {}),
    [layoutRoot]: _.reduce(original, reduceDeepTree(layoutRoot, layoutAreas), {}),
  };
}

/**
 * make precompiled hbs templates ready for user
 * @param  {obj} result
 * @param  {obj} val
 * @param  {string} key
 * @return {obj}
 */
function reduceTemplates(result, val, key) {
  const tpl = hbs.template(val);

  hbs.registerPartial(key, tpl); // register template as partial
  result[key] = tpl; // and add it to the store
  return result;
}

/**
 * get string state to pass to progress bar
 * @param  {object} state
 * @return {string}
 */
function getPageStatus(state) {
  if (state.scheduled) {
    return 'scheduled';
  } else if (state.published) {
    return 'published';
  } else {
    return 'draft';
  }
}

/**
 * Turn the hash string on the location
 * into an object
 *
 * @return {Object}
 */
function parseUrl() {
  if (window.location.hash) {
    let props = window.location.hash.replace('#', '').split('&'),
      propMapping = {};

    _.forEach(props, prop => {
      var split = prop.split('=');

      propMapping[split[0]] = split[1];
    });

    return propMapping;
  } else {
    return null;
  }
}

export default function preload({ dispatch, commit }) {
  const data = _.get(window, 'kiln.preloadData'),
    schemas = _.get(window, 'kiln.preloadSchemas'),
    locals = _.get(window, 'kiln.locals'),
    models = _.get(window, 'kiln.componentModels'),
    templates = _.get(window, 'kiln.componentTemplates'),
    user = locals && locals.user,
    site = locals && normalizeSiteData(locals.site),
    layoutSchema = getLayoutSchema(schemas, data._layoutRef),
    tabulaRasa = _.assign({}, defaultState),
    components = _.reduce(data, reduceComponents, {}),
    urlProps = parseUrl();

  commit(PRELOAD_PENDING);
  commit(START_PROGRESS, 'offline');

  return getPageState(data._self).then((pageState) => {
    commit(PRELOAD_SUCCESS, _.assign(tabulaRasa, {
      components: _.assign(components, composeLayoutData(layoutSchema, components, data)),
      tree: reduceTree(data, layoutSchema),
      page: {
        uri: data._self,
        data: data._pageData,
        state: pageState
      },
      user: user,
      schemas: schemas,
      locals: locals,
      models: models,
      templates: _.reduce(templates, reduceTemplates, {}),
      site: site,
      url: urlProps
    }));
    commit(LOADING_SUCCESS);
    commit(FINISH_PROGRESS, getPageStatus(pageState));

    // Open a form that was hashed in the url
    return dispatch('openHashedForm');
  })
}
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor, runs */

'use strict';

describe('api', function() {
  // TODO run with worker enabled
  var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf');
  function waitsForPromise(promise, successCallback) {
    var data;
    promise.then(function(val) {
      data = val;
      successCallback(data);
    },
    function(error) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  describe('PDFJS', function() {
    describe('getDocument', function() {
      it('creates pdf doc from URL', function() {
        var promise = PDFJS.getDocument(basicApiUrl);
        waitsForPromise(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      /*
      it('creates pdf doc from typed array', function() {
        // TODO
      });
      */
    });
  });
  describe('PDFDocument', function() {
    var promise = PDFJS.getDocument(basicApiUrl);
    var doc;
    waitsForPromise(promise, function(data) {
      doc = data;
    });
    it('gets number of pages', function() {
      expect(doc.numPages).toEqual(3);
    });
    it('gets fingerprint', function() {
      expect(typeof doc.fingerprint).toEqual('string');
    });
    it('gets page', function() {
      var promise = doc.getPage(1);
      waitsForPromise(promise, function(data) {
        expect(true).toEqual(true);
      });
    });
    it('gets destinations', function() {
      var promise = doc.getDestinations();
      waitsForPromise(promise, function(data) {
        // TODO this seems to be broken for the test pdf
      });
    });
    it('gets outline', function() {
      var promise = doc.getOutline();
      waitsForPromise(promise, function(outline) {
        // Two top level entries.
        expect(outline.length).toEqual(2);
        // Make sure some basic attributes are set.
        expect(outline[1].title).toEqual('Chapter 1');
        expect(outline[1].items.length).toEqual(1);
        expect(outline[1].items[0].title).toEqual('Paragraph 1.1');
      });
    });
    it('gets metadata', function() {
      var promise = doc.getMetadata();
      waitsForPromise(promise, function(metadata) {
        expect(metadata.info['Title']).toEqual('Basic API Test');
        expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
      });
    });
  });
  describe('Page', function() {
    var resolvePromise;
    var promise = new Promise(function (resolve) {
      resolvePromise = resolve;
    });
    PDFJS.getDocument(basicApiUrl).then(function(doc) {
      doc.getPage(1).then(function(data) {
        resolvePromise(data);
      });
    });
    var page;
    waitsForPromise(promise, function(data) {
      page = data;
    });

    it('gets ref', function() {
      expect(page.ref).toEqual({num: 15, gen: 0});
    });
    // TODO rotate
    // TODO viewport
    // TODO annotaions
    // TOOD text content
    // TODO operation list
  });
});
<commit_msg>Add Test for PDFDocumentProxy_getPageIndex<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* globals PDFJS, expect, it, describe, Promise, combineUrl, waitsFor, runs */

'use strict';

describe('api', function() {
  // TODO run with worker enabled
  var basicApiUrl = combineUrl(window.location.href, '../pdfs/basicapi.pdf');
  function waitsForPromise(promise, successCallback) {
    var data;
    promise.then(function(val) {
      data = val;
      successCallback(data);
    },
    function(error) {
      // Shouldn't get here.
      expect(false).toEqual(true);
    });
    waitsFor(function() {
      return data !== undefined;
    }, 20000);
  }
  describe('PDFJS', function() {
    describe('getDocument', function() {
      it('creates pdf doc from URL', function() {
        var promise = PDFJS.getDocument(basicApiUrl);
        waitsForPromise(promise, function(data) {
          expect(true).toEqual(true);
        });
      });
      /*
      it('creates pdf doc from typed array', function() {
        // TODO
      });
      */
    });
  });
  describe('PDFDocument', function() {
    var promise = PDFJS.getDocument(basicApiUrl);
    var doc;
    waitsForPromise(promise, function(data) {
      doc = data;
    });
    it('gets number of pages', function() {
      expect(doc.numPages).toEqual(3);
    });
    it('gets fingerprint', function() {
      expect(typeof doc.fingerprint).toEqual('string');
    });
    it('gets page', function() {
      var promise = doc.getPage(1);
      waitsForPromise(promise, function(data) {
        expect(true).toEqual(true);
      });
    });
    it('gets page index', function() {
      // reference to second page
      var ref = {num: 17, gen: 0};
      var promise = doc.getPageIndex(ref);
      waitsForPromise(promise, function(pageIndex) {
        expect(pageIndex).toEqual(1);
      });
    });
    it('gets destinations', function() {
      var promise = doc.getDestinations();
      waitsForPromise(promise, function(data) {
        // TODO this seems to be broken for the test pdf
      });
    });
    it('gets outline', function() {
      var promise = doc.getOutline();
      waitsForPromise(promise, function(outline) {
        // Two top level entries.
        expect(outline.length).toEqual(2);
        // Make sure some basic attributes are set.
        expect(outline[1].title).toEqual('Chapter 1');
        expect(outline[1].items.length).toEqual(1);
        expect(outline[1].items[0].title).toEqual('Paragraph 1.1');
      });
    });
    it('gets metadata', function() {
      var promise = doc.getMetadata();
      waitsForPromise(promise, function(metadata) {
        expect(metadata.info['Title']).toEqual('Basic API Test');
        expect(metadata.metadata.get('dc:title')).toEqual('Basic API Test');
      });
    });
  });
  describe('Page', function() {
    var resolvePromise;
    var promise = new Promise(function (resolve) {
      resolvePromise = resolve;
    });
    PDFJS.getDocument(basicApiUrl).then(function(doc) {
      doc.getPage(1).then(function(data) {
        resolvePromise(data);
      });
    });
    var page;
    waitsForPromise(promise, function(data) {
      page = data;
    });

    it('gets ref', function() {
      expect(page.ref).toEqual({num: 15, gen: 0});
    });
    // TODO rotate
    // TODO viewport
    // TODO annotaions
    // TOOD text content
    // TODO operation list
  });
});
<|endoftext|>


<commit_before>/*
 * boilerplate-redux-react
 *
 * Copyright(c) 2015 André König <andre.koenig@posteo.de>
 * MIT Licensed
 *
 */

/**
 * @author André König <andre.koenig@posteo.de>
 *
 */

import {handleActions} from 'redux-actions';

import Actions from '../actions';

const {RANDOMIZE} = Actions.greeting;

const GREETINS = [
    'Servus',
    'Hello',
    'Hallo',
    'Guten Tag',
    'Hey',
    'S\'up?',
    'Moin',
    'Moin Moin'
];

function getRandomGreeting () {
    return GREETINS[Math.floor(Math.random() * 1000) % GREETINS.length];
}

function createState () {
    return getRandomGreeting();
}

export default handleActions({
    [RANDOMIZE]: (state, action) => {
        return getRandomGreeting()
    }
}, createState());
<commit_msg>[TASK] Fix typo<commit_after>/*
 * boilerplate-redux-react
 *
 * Copyright(c) 2015 André König <andre.koenig@posteo.de>
 * MIT Licensed
 *
 */

/**
 * @author André König <andre.koenig@posteo.de>
 *
 */

import {handleActions} from 'redux-actions';

import Actions from '../actions';

const {RANDOMIZE} = Actions.greeting;

const GREETINGS = [
    'Servus',
    'Hello',
    'Hallo',
    'Guten Tag',
    'Hey',
    'S\'up?',
    'Moin',
    'Moin Moin'
];

function getRandomGreeting () {
    return GREETINGS[Math.floor(Math.random() * 1000) % GREETINGS.length];
}

function createState () {
    return getRandomGreeting();
}

export default handleActions({
    [RANDOMIZE]: (state, action) => {
        return getRandomGreeting()
    }
}, createState());
<|endoftext|>


<commit_before>/*
 * xbee-api
 * https://github.com/jouz/xbee-api
 *
 * Copyright (c) 2013 Jan Kolkmeier
 * Licensed under the MIT license.
 */

'use strict';

var util = require('util');
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('../lib/xbee-api.js');
var T = require('../lib/tools.js');
var C = require('../lib/constants.js');
var events = require('events');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['MAIN'] = {
  setUp: function(done) {
    done();
  },
  tearDown: function (done) {
    done();
  },
  'Option passing': function(test) {
    test.expect(3);
    var xbeeAPI1 = new xbee_api.XBeeAPI();
    test.equal(xbeeAPI1.options.api_mode, 1, "Do default options work?");

    var options = { api_mode: 2 };
    var xbeeAPI2 = new xbee_api.XBeeAPI(options);
    // given a byte array like [3,21], convert to a decimal value.
    test.equal(xbeeAPI2.options.api_mode, 2, "Are passed options applied?");

    var xbeeAPI3 = new xbee_api.XBeeAPI();
    test.equal(xbeeAPI3.options.api_mode, 1, "Are default options left untouched?");

    test.done();
  },
};

exports['PHYSICAL'] = {
  setUp: function(done) {
    done();
  },
  tearDown: function (done) {
    done();
  },
  'todo': function(test) {
    /*
    if (false) {
      test.expect(1);

      var xbeeAPI = new xbee_api.XBeeAPI({
        raw_frames: true
      });

      // TODO: Pass com port option to nodeunit
      var serialport = new SerialPort("COM13", {
        baudrate: 57600
        parser: xbeeAPI.parse
      });

      serialport.on("open", function() {
        var query = new Buffer([ 0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x4A, 0x0D]);
        serialport.write(, function(err, results) {
          test.equal(err, null, "Can we write to the port?");
        });
      });

      serialport.on("frame_raw"; function(frame) {
        test.equal(1, 1, "");
        test.done();
      });
    }
    */
    test.done();
  }
}

exports['TOOLS'] = {
  setUp: function(done) {
    done();
  },
  tearDown: function (done) {
    done();
  },
  'bArr2Dec': function(test) {
    test.expect(1);
    // given a byte array like [3,21], convert to a decimal value.
    test.equal(T.bArr2Dec([3,21]), 789);

    test.done();
  },
  'bArr2HexStr': function(test) {
    test.expect(1);
    // given a byte array like [0xff,0xfe], convert to a string representaiton in hex.
    test.equal(T.bArr2HexStr([0xff,0xfe]), 'fffe');

    test.done();

  }
};

exports['API Frame Building'] = { // These have to be tested both for AP=1 and 2
  'AT Command Requests': function(test) {
    test.expect(0);
    // AT Command; 0x08; Queries ATNJ
    var expected0 = new Buffer([ 0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x4A, 0x0D]);

    // AT Command - Queue Param. Value; 0x09; Queues ATBD7
    var expected1 = new Buffer([ 0x7E, 0x00, 0x05, 0x09, 0x01, 0x42, 0x44, 0x07, 0x68]);

    // Remote AT Command Req.; 0x17; ATBH1
    var expected2 = new Buffer([ 0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x40, 0x11, 0x22, 0xFF, 0xFE, 0x02, 0x42, 0x48, 0x01, 0xF5]);

    //test.equal(XBee_api...(), 'value', 'Should be value');
    test.done();
  },
  'Transmit Requests': function(test) {
    test.expect(0);
    // Transmit request; 0x10; sends chars: TxData1B (AP=1)
    var expected0 = new Buffer([ 0x7E, 0x00, 0x16, 0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x0A, 0x01, 0x27, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x30, 0x41, 0x13 ]);

    test.done();
  }
}

exports['API Frame Parsing'] = {
  'AT Remote Command Responses': function(test) {
    test.expect(6);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) { // frame1
      test.equal(frame.id, 0x55, "Parse frameid");
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.command, "SL", "Parse command");
      test.equal(frame.commandStatus, 0, "Parse command status");
      test.deepEqual(frame.commandData, [ 0x40, 0x52, 0x2b, 0xaa ]);
      test.done();
    });

    // Remote Command Response; 0x97; ATSL [OK] 40522BAA
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x13, 0x97, 0x55, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x53, 0x4C, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0xF0 ]);
    parser(dummy, Escape(rawFrame));
  },
  'AT Command Responses': function(test) {
    test.expect(3);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) { // frame0
      test.equal(frame.id, 0x01, "Parse frameid");
      test.equal(frame.command, "BD", "Parse command");
      test.equal(frame.commandStatus, 0, "Parse command status");
      test.done();
    });

    // AT Command Response; 0x88; ATBD [OK] (no data)
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x05, 0x88, 0x01, 0x42, 0x44, 0x00, 0xF0 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Transmit Status': function(test) {
    test.expect(4);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote16, "7d84", "Parse remote16");
      test.equal(frame.transmitRetryCount, 0, "Parse retry count");
      test.equal(frame.deliveryStatus, 0, "Parse delivery status");
      test.equal(frame.discoveryStatus, 1, "Parse discovery status");
      test.done();
    });
    // ZigBee Transmit Status; 0x8B; 0 retransmit, Success, Address Discovery
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x07, 0x8B, 0x01, 0x7D, 0x84, 0x00, 0x00, 0x01, 0x71 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Modem Status': function(test) {
    test.expect(1);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.status, 6, "Parse status");
      test.done();
    });
    // Modem status; 0x8A; Coordinator Started
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x02, 0x8A, 0x06, 0x6F ]);
    parser(dummy, Escape(rawFrame));
  },
  'Receive Packet': function(test) {
    test.expect(4);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.receiveOptions, 1, "Parse receive options");
      test.deepEqual(frame.data, [ 0x52, 0x78, 0x44, 0x61, 0x74, 0x61 ]);
      test.done();
    });
    // Receive Packet; 0x90; Receive packet with chars RxData
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x12, 0x90, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x01, 0x52, 0x78, 0x44, 0x61, 0x74, 0x61, 0x0D ]);
    parser(dummy, Escape(rawFrame));
  },
  'ZigBee IO Data Sample Rx': function(test) {
    test.expect(6);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.receiveOptions, 1, "Parse receive options");
      test.equal(frame.numSamples, 1, "Parse number of samples");
      test.deepEqual(frame.digitalSamples, {
        "DIO2": 1,
        "DIO3": 0,
        "DIO4": 1
      }, "Parsing digital samples");
      test.deepEqual(frame.analogSamples, {
        "AD1": 644
      }, "Parse analog samples");
      test.done();
    });

    // Receive IO Data Sample; 0x92; ...
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x14, 0x92, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x01, 0x01, 0x00, 0x1C, 0x02, 0x00, 0x14, 0x02, 0x25, 0xF5 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Node Identification Indicator': function(test) {
    test.expect(9);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) {
      test.equal(frame.sender64, '0013a20040522baa', "Parse sender64");
      test.equal(frame.sender16, '7d84', "Parse sender16");
      test.equal(frame.receiveOptions, 2, "Parse receive options");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.nodeIdentifier, " ", "Parse node identifier");
      test.equal(frame.remoteParent16, 'fffe', "Parse parent16 ");
      test.equal(frame.deviceType, 1, "Parse device type");
      test.equal(frame.sourceEvent, 1, "Parse source event");
      // digi app profile...
      test.done();
    });

    // Receive IO Data Sample; 0x95; ...
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x20, 0x95, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x02, 0x7D, 0x84, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x20, 0x00, 0xFF, 0xFE, 0x01, 0x01, 0xC1, 0x05, 0x10, 0x1E, 0x1B ]);
    parser(dummy, Escape(rawFrame));
  }
};

function Escape(buffer) {
    var packetdata = buffer.toJSON();
    var res = [packetdata[0]];
    for (var p = 1; p<packetdata.length; p++) {
      if (packetdata[p] == C.START_BYTE ||
          packetdata[p] == C.ESCAPE ||
          packetdata[p] == C.XOFF ||
          packetdata[p] == C.XON) {
        res.push(C.ESCAPE);
        res.push(packetdata[p] ^ 0x20);
      } else res.push(packetdata[p]);
    }
    return new Buffer(res, 'ascii');
}
<commit_msg>wrote tests for building api frames<commit_after>/*
 * xbee-api
 * https://github.com/jouz/xbee-api
 *
 * Copyright (c) 2013 Jan Kolkmeier
 * Licensed under the MIT license.
 */

'use strict';

var util = require('util');
var xbee_api = require('../lib/xbee-api.js');
var C = require('../lib/constants.js');
var events = require('events');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['Main'] = {
  setUp: function(done) {
    done();
  },
  tearDown: function (done) {
    done();
  },
  'Option passing': function(test) {
    test.expect(3);
    var xbeeAPI1 = new xbee_api.XBeeAPI();
    test.equal(xbeeAPI1.options.api_mode, 1, "Do default options work?");

    var options = { api_mode: 2 };
    var xbeeAPI2 = new xbee_api.XBeeAPI(options);
    // given a byte array like [3,21], convert to a decimal value.
    test.equal(xbeeAPI2.options.api_mode, 2, "Are passed options applied?");

    var xbeeAPI3 = new xbee_api.XBeeAPI();
    test.equal(xbeeAPI3.options.api_mode, 1, "Are default options left untouched?");

    test.done();
  },
};

exports['API Frame Building'] = { // These have to be tested both for AP=1 and 2
  'AT Command Requests': function(test) {
    test.expect(1);

    var frame = {
      type: C.FRAME_TYPE.AT_COMMAND,
      id: 0x52,
      command: "NJ",
      commandParameter: [],
    };

    // AT Command; 0x08; Queries ATNJ
    var expected0 = new Buffer([ 0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x4A, 0x0D]);

    var xbeeAPI = new xbee_api.XBeeAPI();
    test.deepEqual(expected0, xbeeAPI.BuildFrame(frame), "create raw frame");
    test.done();
  },
  'AT Command Queue Requests': function(test) {
    test.expect(1);

    var frame = {
      type: C.FRAME_TYPE.AT_COMMAND_QUEUE_PARAMETER_VALUE,
      id: 0x01,
      command: "BD",
      commandParameter: [ 0x07 ]
    };

    // AT Command - Queue Param. Value; 0x09; Queues ATBD7
    var expected0 = new Buffer([ 0x7E, 0x00, 0x05, 0x09, 0x01, 0x42, 0x44, 0x07, 0x68]);

    var xbeeAPI = new xbee_api.XBeeAPI();
    test.deepEqual(expected0, xbeeAPI.BuildFrame(frame), "create raw frame");
    test.done();
  },
  'AT Remote Command Requests': function(test) {
    test.expect(1);

    var frame = {
      type: C.FRAME_TYPE.REMOTE_AT_COMMAND_REQUEST,
      id: 0x01,
      destination64: "0013a20040401122",
      destination16: "fffe",
      remoteCommandOptions: 0x02,
      command: "BH",
      commandParameter: [ 0x01 ]
    };

    // Remote AT Command Req.; 0x17; ATBH1
    var expected0 = new Buffer([ 0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x40, 0x11, 0x22, 0xFF, 0xFE, 0x02, 0x42, 0x48, 0x01, 0xF5]);

    var xbeeAPI = new xbee_api.XBeeAPI();
    test.deepEqual(expected0, xbeeAPI.BuildFrame(frame), "create raw frame");
    test.done();
  },
  'Transmit Requests': function(test) {
    test.expect(1);

    var frame = {
      type: C.FRAME_TYPE.ZIGBEE_TRANSMIT_REQUEST,
      id: 0x01,
      destination64: "0013a200400a0127",
      destination16: "fffe",
      broadcastRadius: 0x00,
      options: 0x00,
      data: "TxData0A"
    };

    // Transmit request; 0x10; sends chars: TxData1B (AP=1)
    var expected0 = new Buffer([ 0x7E, 0x00, 0x16, 0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x0A, 0x01, 0x27, 0xFF, 0xFE, 0x00, 0x00, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x30, 0x41, 0x13 ]);

    var xbeeAPI = new xbee_api.XBeeAPI();
    test.deepEqual(expected0, xbeeAPI.BuildFrame(frame), "create raw frame");
    test.done();
  }
}

exports['API Frame Parsing'] = {
  'AT Remote Command Responses': function(test) {
    test.expect(6);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) { // frame1
      test.equal(frame.id, 0x55, "Parse frameid");
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.command, "SL", "Parse command");
      test.equal(frame.commandStatus, 0, "Parse command status");
      test.deepEqual(frame.commandData, [ 0x40, 0x52, 0x2b, 0xaa ]);
      test.done();
    });

    // Remote Command Response; 0x97; ATSL [OK] 40522BAA
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x13, 0x97, 0x55, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x53, 0x4C, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0xF0 ]);
    parser(dummy, Escape(rawFrame));
  },
  'AT Command Responses': function(test) {
    test.expect(3);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) { // frame0
      test.equal(frame.id, 0x01, "Parse frameid");
      test.equal(frame.command, "BD", "Parse command");
      test.equal(frame.commandStatus, 0, "Parse command status");
      test.done();
    });

    // AT Command Response; 0x88; ATBD [OK] (no data)
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x05, 0x88, 0x01, 0x42, 0x44, 0x00, 0xF0 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Transmit Status': function(test) {
    test.expect(4);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote16, "7d84", "Parse remote16");
      test.equal(frame.transmitRetryCount, 0, "Parse retry count");
      test.equal(frame.deliveryStatus, 0, "Parse delivery status");
      test.equal(frame.discoveryStatus, 1, "Parse discovery status");
      test.done();
    });
    // ZigBee Transmit Status; 0x8B; 0 retransmit, Success, Address Discovery
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x07, 0x8B, 0x01, 0x7D, 0x84, 0x00, 0x00, 0x01, 0x71 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Modem Status': function(test) {
    test.expect(1);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.status, 6, "Parse status");
      test.done();
    });
    // Modem status; 0x8A; Coordinator Started
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x02, 0x8A, 0x06, 0x6F ]);
    parser(dummy, Escape(rawFrame));
  },
  'Receive Packet': function(test) {
    test.expect(4);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();
    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.receiveOptions, 1, "Parse receive options");
      test.deepEqual(frame.data, [ 0x52, 0x78, 0x44, 0x61, 0x74, 0x61 ]);
      test.done();
    });
    // Receive Packet; 0x90; Receive packet with chars RxData
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x12, 0x90, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x01, 0x52, 0x78, 0x44, 0x61, 0x74, 0x61, 0x0D ]);
    parser(dummy, Escape(rawFrame));
  },
  'ZigBee IO Data Sample Rx': function(test) {
    test.expect(6);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) {
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.receiveOptions, 1, "Parse receive options");
      test.equal(frame.numSamples, 1, "Parse number of samples");
      test.deepEqual(frame.digitalSamples, {
        "DIO2": 1,
        "DIO3": 0,
        "DIO4": 1
      }, "Parsing digital samples");
      test.deepEqual(frame.analogSamples, {
        "AD1": 644
      }, "Parse analog samples");
      test.done();
    });

    // Receive IO Data Sample; 0x92; ...
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x14, 0x92, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x01, 0x01, 0x00, 0x1C, 0x02, 0x00, 0x14, 0x02, 0x25, 0xF5 ]);
    parser(dummy, Escape(rawFrame));
  },
  'Node Identification Indicator': function(test) {
    test.expect(9);
    var xbeeAPI = new xbee_api.XBeeAPI();
    var parser = xbeeAPI.parser();
    var dummy = new events.EventEmitter();

    dummy.once("frame_object", function(frame) {
      test.equal(frame.sender64, '0013a20040522baa', "Parse sender64");
      test.equal(frame.sender16, '7d84', "Parse sender16");
      test.equal(frame.receiveOptions, 2, "Parse receive options");
      test.equal(frame.remote16, '7d84', "Parse remote16");
      test.equal(frame.remote64, '0013a20040522baa', "Parse remote64");
      test.equal(frame.nodeIdentifier, " ", "Parse node identifier");
      test.equal(frame.remoteParent16, 'fffe', "Parse parent16 ");
      test.equal(frame.deviceType, 1, "Parse device type");
      test.equal(frame.sourceEvent, 1, "Parse source event");
      // digi app profile...
      test.done();
    });

    // Receive IO Data Sample; 0x95; ...
    var rawFrame = new Buffer([ 0x7E, 0x00, 0x20, 0x95, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x7D, 0x84, 0x02, 0x7D, 0x84, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA, 0x20, 0x00, 0xFF, 0xFE, 0x01, 0x01, 0xC1, 0x05, 0x10, 0x1E, 0x1B ]);
    parser(dummy, Escape(rawFrame));
  }
};

function Escape(packetdata) {
    var res = [packetdata[0]];
    for (var p = 1; p<packetdata.length; p++) {
      if (packetdata[p] == C.START_BYTE ||
          packetdata[p] == C.ESCAPE ||
          packetdata[p] == C.XOFF ||
          packetdata[p] == C.XON) {
        res.push(C.ESCAPE);
        res.push(packetdata[p] ^ 0x20);
      } else res.push(packetdata[p]);
    }
    return new Buffer(res, 'ascii');
}
<|endoftext|>


<commit_before>var Piper            = require('./piper'),
    EventEmitter     = require('events').EventEmitter;

function stringifyRequest(options) {
  var method = options.method || 'GET',
      path = options.path,
      body = options.body;

  if (body && typeof(body) !== 'string') {
    body = body.toString();
  }
  return method + ' ' + path + ' ' + body;
}

function getHeader(request, name) {
  if (!request._headers) return;

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._headers[key] = value;
  request._headerNames[key] = name;
}

function RequestOverrider(req, options, interceptors, remove) {
  var response = new EventEmitter(),
      requestBodyBuffers = [],
      aborted,
      end,
      ended,
      headers,
      keys,
      key,
      i,
      l;

  if (options.headers) {
    headers = options.headers;
    keys = Object.keys(headers);

    for (i = 0, l = keys.length; i < l; i++) {
      key = keys[i];

      setHeader(req, key, headers[key]);
    };
  }

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  if (options.host && !getHeader(req, 'host')) {
    var hostHeader = options.host;

    if (options.host && +options.port !== 80) {
      hostHeader += ':' + options.port;
    }

    setHeader(req, 'Host', hostHeader);
  }

  req.write = function(buffer, encoding) {
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
  };

  req.end = function(buffer, encoding) {
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end();
      req.emit('end');
    }
  };

  req.abort = function() {
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted'
    response.emit('close', err);
  };

  end = function() {
    ended = true;
    var encoding,
        requestBody,
        responseBody,
        interceptor,
        paused,
        next = [];

    var requestBodySize = 0;
    var copyTo = 0;
    requestBodyBuffers.forEach(function(b) {
      requestBodySize += b.length;
    });
    requestBody = new Buffer(requestBodySize);
    requestBodyBuffers.forEach(function(b) {
    b.copy(requestBody, copyTo);
      copyTo += b.length;
    });

    requestBody = requestBody.toString();

    interceptors = interceptors.filter(function(interceptor) {
      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) { throw new Error("Nock: No match for HTTP request " + stringifyRequest(options)); }
    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};
    response.readable = true;
    responseBody = interceptor.body;
    if (! Buffer.isBuffer(responseBody)) {
      responseBody = new Buffer(responseBody);
    }
    response.setEncoding = function(newEncoding) {
      encoding = newEncoding;
    };
    remove(interceptor);
    interceptor.discard();

    if (aborted) { return; }

    response.pause = function() {
      paused = true;
    };

    response.resume = function() {
      paused = false;
      callnext();
    };

    response.pipe = Piper();
    next.push(function() {
      if (encoding) {
        responseBody = responseBody.toString(encoding);
      }
      response.emit('data', responseBody);
    });

    next.push(function() {
      response.emit('end');
    });

    function callnext() {
      process.nextTick(function() {
      if (paused || next.length === 0 || aborted) { return; }
        next.shift()();
        callnext();
      });
    };

    process.nextTick(function() {
      if (typeof callback === 'function') {
        callback(response);
      }
      req.emit('response', response);
      callnext();
    });
  };

  return req;
}

module.exports = RequestOverrider;<commit_msg>Output body in error message<commit_after>var Piper            = require('./piper'),
    EventEmitter     = require('events').EventEmitter;

function stringifyRequest(options, body) {
  var method = options.method || 'GET',
      path = options.path;

  if (body && typeof(body) !== 'string') {
    body = body.toString();
  }
  return method + ' ' + path + ' ' + body;
}

function getHeader(request, name) {
  if (!request._headers) return;

  var key = name.toLowerCase();

  return request._headers[key];
}

function setHeader(request, name, value) {
  var key = name.toLowerCase();

  request._headers = request._headers || {};
  request._headerNames = request._headerNames || {};
  request._headers[key] = value;
  request._headerNames[key] = name;
}

function RequestOverrider(req, options, interceptors, remove) {
  var response = new EventEmitter(),
      requestBodyBuffers = [],
      aborted,
      end,
      ended,
      headers,
      keys,
      key,
      i,
      l;

  if (options.headers) {
    headers = options.headers;
    keys = Object.keys(headers);

    for (i = 0, l = keys.length; i < l; i++) {
      key = keys[i];

      setHeader(req, key, headers[key]);
    };
  }

  options.getHeader = function(name) {
    return getHeader(req, name);
  };

  if (options.host && !getHeader(req, 'host')) {
    var hostHeader = options.host;

    if (options.host && +options.port !== 80) {
      hostHeader += ':' + options.port;
    }

    setHeader(req, 'Host', hostHeader);
  }

  req.write = function(buffer, encoding) {
    if (buffer && !aborted) {
      if (! Buffer.isBuffer(buffer)) {
        buffer = new Buffer(buffer, encoding);
      }
      requestBodyBuffers.push(buffer);
    }
  };

  req.end = function(buffer, encoding) {
    if (!aborted && !ended) {
      req.write(buffer, encoding);
      end();
      req.emit('end');
    }
  };

  req.abort = function() {
    aborted = true;
    if (!ended) {
      end();
    }
    var err = new Error();
    err.code = 'aborted'
    response.emit('close', err);
  };

  end = function() {
    ended = true;
    var encoding,
        requestBody,
        responseBody,
        interceptor,
        paused,
        next = [];

    var requestBodySize = 0;
    var copyTo = 0;
    requestBodyBuffers.forEach(function(b) {
      requestBodySize += b.length;
    });
    requestBody = new Buffer(requestBodySize);
    requestBodyBuffers.forEach(function(b) {
    b.copy(requestBody, copyTo);
      copyTo += b.length;
    });

    requestBody = requestBody.toString();

    interceptors = interceptors.filter(function(interceptor) {
      return interceptor.match(options, requestBody);
    });

    if (interceptors.length < 1) { throw new Error("Nock: No match for HTTP request " + stringifyRequest(options, requestBody)); }
    interceptor = interceptors.shift();

    response.statusCode = interceptor.statusCode || 200;
    response.headers = interceptor.headers || {};
    response.readable = true;
    responseBody = interceptor.body;
    if (! Buffer.isBuffer(responseBody)) {
      responseBody = new Buffer(responseBody);
    }
    response.setEncoding = function(newEncoding) {
      encoding = newEncoding;
    };
    remove(interceptor);
    interceptor.discard();

    if (aborted) { return; }

    response.pause = function() {
      paused = true;
    };

    response.resume = function() {
      paused = false;
      callnext();
    };

    response.pipe = Piper();
    next.push(function() {
      if (encoding) {
        responseBody = responseBody.toString(encoding);
      }
      response.emit('data', responseBody);
    });

    next.push(function() {
      response.emit('end');
    });

    function callnext() {
      process.nextTick(function() {
      if (paused || next.length === 0 || aborted) { return; }
        next.shift()();
        callnext();
      });
    };

    process.nextTick(function() {
      if (typeof callback === 'function') {
        callback(response);
      }
      req.emit('response', response);
      callnext();
    });
  };

  return req;
}

module.exports = RequestOverrider;<|endoftext|>