<commit_before>'use strict'
/* global describe, it, beforeEach, afterEach */

const {expect} = require('chai')
const {globalMiddlewareFactory} = require('../lib/middleware')
let yargs
require('chai').should()

describe('middleware', () => {
  beforeEach(() => {
    yargs = require('../')
  })
  afterEach(() => {
    delete require.cache[require.resolve('../')]
  })

  it('should add a list of callbacks to global middleware', () => {
    const globalMiddleware = []

    globalMiddlewareFactory(globalMiddleware)([() => {}, () => {}])

    globalMiddleware.should.have.lengthOf(2)
  })

  it('should throw exception if middleware is not a function', () => {
    const globalMiddleware = []

    expect(() => {
      globalMiddlewareFactory(globalMiddleware)(['callback1', 'callback2'])
    }).to.throw('middleware must be a function')
  })

  it('should add a single callback to global middleware', () => {
    const globalMiddleware = []

    globalMiddlewareFactory(globalMiddleware)(function () {})

    globalMiddleware.should.have.lengthOf(1)
  })

  it('runs the middleware before reaching the handler', function (done) {
    yargs(['mw'])
      .middleware(function (argv) {
        argv.mw = 'mw'
      })
      .command(
        'mw',
        'adds func to middleware',
        function () {},
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .parse()
  })

  it('runs all middleware before reaching the handler', function (done) {
    yargs(['mw'])
      .middleware([
        function (argv) {
          argv.mw1 = 'mw1'
        },
        function (argv) {
          argv.mw2 = 'mw2'
        }
      ])
      .command(
        'mw',
        'adds func list to middleware',
        function () {},
        function (argv) {
          argv.mw1.should.equal('mw1')
          argv.mw2.should.equal('mw2')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  it('should be able to register middleware regardless of when middleware is called', function (done) {
    yargs(['mw'])
      .middleware(function (argv) {
        argv.mw1 = 'mw1'
      })
      .command(
        'mw',
        'adds func list to middleware',
        function () {},
        function (argv) {
          // we should get the argv filled with data from the middleware
          argv.mw1.should.equal('mw1')
          argv.mw2.should.equal('mw2')
          argv.mw3.should.equal('mw3')
          argv.mw4.should.equal('mw4')
          return done()
        }
      )
      .middleware(function (argv) {
        argv.mw2 = 'mw2'
      })
      .middleware([
        function (argv) {
          argv.mw3 = 'mw3'
        },
        function (argv) {
          argv.mw4 = 'mw4'
        }
      ])
      .exitProcess(false)
      .parse()
  })

  // addresses https://github.com/yargs/yargs/issues/1237
  describe('async', () => {
    it('fails when the promise returned by the middleware rejects', (done) => {
      const error = new Error()
      const handlerErr = new Error('should not have been called')
      yargs('foo')
        .command('foo', 'foo command', () => {}, (argv) => done(handlerErr), [ (argv) => Promise.reject(error) ])
        .fail((msg, err) => {
          expect(msg).to.equal(null)
          expect(err).to.equal(error)
          done()
        })
        .parse()
    })

    it('calls the command handler when all middleware promises resolve', (done) => {
      const middleware = (key, value) => () => new Promise((resolve, reject) => {
        setTimeout(() => {
          return resolve({ [key]: value })
        }, 5)
      })
      yargs('foo hello')
        .command('foo <pos>', 'foo command', () => {}, (argv) => {
          argv.hello.should.equal('world')
          argv.foo.should.equal('bar')
          done()
        }, [ middleware('hello', 'world'), middleware('foo', 'bar') ])
        .fail((msg, err) => {
          return done(Error('should not have been called'))
        })
        .exitProcess(false)
        .parse()
    })
  })

  // see: https://github.com/yargs/yargs/issues/1281
  it("doesn't modify globalMiddleware array when executing middleware", () => {
    let count = 0
    yargs('bar')
      .middleware((argv) => {
        count++
      })
      .command('foo', 'foo command', () => {}, () => {}, [
        () => {
          count++
        }
      ])
      .command('bar', 'bar command', () => {}, () => {}, [
        () => {
          count++
        }
      ])
      .exitProcess(false)
      .parse()
    count.should.equal(2)
  })

  it('allows middleware to be added in builder', (done) => {
    yargs(['mw'])
      .command(
        'mw',
        'adds func to middleware',
        function (yargs) {
          yargs.middleware(function (argv) {
            argv.mw = 'mw'
          })
        },
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  it('passes yargs object to middleware', (done) => {
    yargs(['mw'])
      .command(
        'mw',
        'adds func to middleware',
        function (yargs) {
          yargs.middleware(function (argv, yargs) {
            expect(typeof yargs.help).to.equal('function')
            argv.mw = 'mw'
          })
        },
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  describe('applyBeforeValidation', () => {
    it('runs before validation when "true"', function (done) {
      yargs(['mw'])
        .middleware(function (argv) {
          argv.mw = 'mw'
        }, true)
        .command(
          'mw',
          'adds func to middleware',
          {
            'mw': {
              'demand': true,
              'string': true
            }
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .exitProcess(false)
        .parse()
    })

    it('throws an error if "true" and async function provided', function () {
      expect(() => {
        yargs(['mw'])
          .middleware([async function (argv) {
            argv.mw = 'mw'
            argv.other = true
          }], true)
          .command(
            'mw',
            'adds func to middleware',
            {
              'mw': {
                'demand': true,
                'string': true
              }
            },
            function (argv) {
              throw Error('we should not get here')
            }
          )
          .exitProcess(false)
          .parse()
      }).to.throw('middleware cannot return a promise when applyBeforeValidation is true')
    })

    it('runs before validation, when middleware is added in builder', (done) => {
      yargs(['mw'])
        .command(
          'mw',
          'adds func to middleware',
          function (yargs) {
            // we know that this middleware is being run in the context of the
            // mw command.
            yargs.middleware(function (argv) {
              argv.mw = 'mw'
            }, true)
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .demand('mw')
        .exitProcess(false)
        .parse()
    })
  })
})
<commit_msg>test: add tests for alias behavior, based on conversations today (#1291)<commit_after>'use strict'
/* global describe, it, beforeEach, afterEach */

const {expect} = require('chai')
const {globalMiddlewareFactory} = require('../lib/middleware')
let yargs
require('chai').should()

describe('middleware', () => {
  beforeEach(() => {
    yargs = require('../')
  })
  afterEach(() => {
    delete require.cache[require.resolve('../')]
  })

  it('should add a list of callbacks to global middleware', () => {
    const globalMiddleware = []

    globalMiddlewareFactory(globalMiddleware)([() => {}, () => {}])

    globalMiddleware.should.have.lengthOf(2)
  })

  it('should throw exception if middleware is not a function', () => {
    const globalMiddleware = []

    expect(() => {
      globalMiddlewareFactory(globalMiddleware)(['callback1', 'callback2'])
    }).to.throw('middleware must be a function')
  })

  it('should add a single callback to global middleware', () => {
    const globalMiddleware = []

    globalMiddlewareFactory(globalMiddleware)(function () {})

    globalMiddleware.should.have.lengthOf(1)
  })

  it('runs the middleware before reaching the handler', function (done) {
    yargs(['mw'])
      .middleware(function (argv) {
        argv.mw = 'mw'
      })
      .command(
        'mw',
        'adds func to middleware',
        function () {},
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .parse()
  })

  it('runs all middleware before reaching the handler', function (done) {
    yargs(['mw'])
      .middleware([
        function (argv) {
          argv.mw1 = 'mw1'
        },
        function (argv) {
          argv.mw2 = 'mw2'
        }
      ])
      .command(
        'mw',
        'adds func list to middleware',
        function () {},
        function (argv) {
          argv.mw1.should.equal('mw1')
          argv.mw2.should.equal('mw2')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  it('should be able to register middleware regardless of when middleware is called', function (done) {
    yargs(['mw'])
      .middleware(function (argv) {
        argv.mw1 = 'mw1'
      })
      .command(
        'mw',
        'adds func list to middleware',
        function () {},
        function (argv) {
          // we should get the argv filled with data from the middleware
          argv.mw1.should.equal('mw1')
          argv.mw2.should.equal('mw2')
          argv.mw3.should.equal('mw3')
          argv.mw4.should.equal('mw4')
          return done()
        }
      )
      .middleware(function (argv) {
        argv.mw2 = 'mw2'
      })
      .middleware([
        function (argv) {
          argv.mw3 = 'mw3'
        },
        function (argv) {
          argv.mw4 = 'mw4'
        }
      ])
      .exitProcess(false)
      .parse()
  })

  // addresses https://github.com/yargs/yargs/issues/1237
  describe('async', () => {
    it('fails when the promise returned by the middleware rejects', (done) => {
      const error = new Error()
      const handlerErr = new Error('should not have been called')
      yargs('foo')
        .command('foo', 'foo command', () => {}, (argv) => done(handlerErr), [ (argv) => Promise.reject(error) ])
        .fail((msg, err) => {
          expect(msg).to.equal(null)
          expect(err).to.equal(error)
          done()
        })
        .parse()
    })

    it('calls the command handler when all middleware promises resolve', (done) => {
      const middleware = (key, value) => () => new Promise((resolve, reject) => {
        setTimeout(() => {
          return resolve({ [key]: value })
        }, 5)
      })
      yargs('foo hello')
        .command('foo <pos>', 'foo command', () => {}, (argv) => {
          argv.hello.should.equal('world')
          argv.foo.should.equal('bar')
          done()
        }, [ middleware('hello', 'world'), middleware('foo', 'bar') ])
        .fail((msg, err) => {
          return done(Error('should not have been called'))
        })
        .exitProcess(false)
        .parse()
    })
  })

  // see: https://github.com/yargs/yargs/issues/1281
  it("doesn't modify globalMiddleware array when executing middleware", () => {
    let count = 0
    yargs('bar')
      .middleware((argv) => {
        count++
      })
      .command('foo', 'foo command', () => {}, () => {}, [
        () => {
          count++
        }
      ])
      .command('bar', 'bar command', () => {}, () => {}, [
        () => {
          count++
        }
      ])
      .exitProcess(false)
      .parse()
    count.should.equal(2)
  })

  it('allows middleware to be added in builder', (done) => {
    yargs(['mw'])
      .command(
        'mw',
        'adds func to middleware',
        function (yargs) {
          yargs.middleware(function (argv) {
            argv.mw = 'mw'
          })
        },
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  it('passes yargs object to middleware', (done) => {
    yargs(['mw'])
      .command(
        'mw',
        'adds func to middleware',
        function (yargs) {
          yargs.middleware(function (argv, yargs) {
            expect(typeof yargs.help).to.equal('function')
            argv.mw = 'mw'
          })
        },
        function (argv) {
          argv.mw.should.equal('mw')
          return done()
        }
      )
      .exitProcess(false)
      .parse()
  })

  it('applies aliases before middleware is called', (done) => {
    yargs(['mw', '--foo', '99'])
      .middleware(function (argv) {
        argv.f.should.equal(99)
        argv.mw = 'mw'
      })
      .command(
        'mw',
        'adds func to middleware',
        function (yargs) {
          yargs.middleware((argv) => {
            argv.f.should.equal(99)
            argv.mw2 = 'mw2'
          })
        },
        function (argv) {
          argv.mw.should.equal('mw')
          argv.mw2.should.equal('mw2')
          return done()
        }
      )
      .alias('foo', 'f')
      .exitProcess(false)
      .parse()
  })

  describe('applyBeforeValidation=true', () => {
    it('runs before validation', function (done) {
      yargs(['mw'])
        .middleware(function (argv) {
          argv.mw = 'mw'
        }, true)
        .command(
          'mw',
          'adds func to middleware',
          {
            'mw': {
              'demand': true,
              'string': true
            }
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .exitProcess(false)
        .parse()
    })

    it('throws an error if async function provided', function () {
      expect(() => {
        yargs(['mw'])
          .middleware([async function (argv) {
            argv.mw = 'mw'
            argv.other = true
          }], true)
          .command(
            'mw',
            'adds func to middleware',
            {
              'mw': {
                'demand': true,
                'string': true
              }
            },
            function (argv) {
              throw Error('we should not get here')
            }
          )
          .exitProcess(false)
          .parse()
      }).to.throw('middleware cannot return a promise when applyBeforeValidation is true')
    })

    it('runs before validation, when middleware is added in builder', (done) => {
      yargs(['mw'])
        .command(
          'mw',
          'adds func to middleware',
          function (yargs) {
            // we know that this middleware is being run in the context of the
            // mw command.
            yargs.middleware(function (argv) {
              argv.mw = 'mw'
            }, true)
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .demand('mw')
        .exitProcess(false)
        .parse()
    })

    it('applies aliases before middleware is called, for global middleware', (done) => {
      yargs(['mw', '--foo', '99'])
        .middleware(function (argv) {
          argv.f.should.equal(99)
          argv.mw = 'mw'
        }, true)
        .command(
          'mw',
          'adds func to middleware',
          {
            'mw': {
              'demand': true
            }
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .alias('foo', 'f')
        .exitProcess(false)
        .parse()
    })

    it('applies aliases before middleware is called, when middleware is added in builder', (done) => {
      yargs(['mw', '--foo', '99'])
        .command(
          'mw',
          'adds func to middleware',
          function (yargs) {
            yargs
              .middleware((argv) => {
                argv.f.should.equal(99)
                argv.mw = 'mw'
              }, true)
              .demand('mw')
          },
          function (argv) {
            argv.mw.should.equal('mw')
            return done()
          }
        )
        .alias('foo', 'f')
        .exitProcess(false)
        .parse()
    })
  })
})
<|endoftext|>


<commit_before>var test = require('tape');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var ModalForm = require('../index');
var simulant = require('simulant');

test('ModalForm', function(t) {
  t.test('is exported', function(t) {
    t.plan(1);
    t.equal(typeof ModalForm, 'function', 'Exported the constructor');
  });

  t.test('can be created', function(t) {
    var instance = React.createElement(ModalForm);
    t.plan(1);
    t.ok(instance, 'Instance created');
  });

  t.test('can get a bounding rectangle including margin', function(t) {
    var rectElement = document.createElement('div');
    rectElement.id = 'rect-element';
    rectElement.style.width = '10px';
    rectElement.style.height = '10px';
    rectElement.style.margin = '10px';
    document.body.appendChild(rectElement);

    var rect = ModalForm.prototype.getRect(rectElement);
    t.plan(2);
    t.equal(rect.width, 30, 'Correct rect width');
    t.equal(rect.height, 30, 'Correct rect height');

    rectElement.parentElement.removeChild(rectElement);
  });
});

test('An instance', function(t) {
  var container = document.createElement('div');
  container.id = 'modal-form-container';
  document.body.appendChild(container);

  var anchor = document.createElement('div');
  anchor.id = 'modal-form-anchor';
  anchor.style.width = '100px';
  anchor.style.height = '100px';
  anchor.style.position = 'absolute';
  anchor.style.left = '100px';
  anchor.style.top = '100px';
  document.body.appendChild(anchor);

  var submissions = 0;
  var cancellations = 0;

  var modal = React.render(React.createElement(ModalForm, {
    anchor: anchor,
    onSubmit: function() {
      submissions += 1;
    },
    onCancel: function() {
      cancellations += 1;
    }
  }, React.createElement('div', {
    style: {
      width: '50px',
      height: '50px'
    }
  })), container);

  t.test('is positioned under its anchor', function(t) {
    var form = React.findDOMNode(modal.refs.form);
    var formCenter = form.offsetLeft + (form.offsetWidth / 2);
    var formTop = form.offsetTop;
    var anchorCenter = anchor.offsetLeft + (anchor.offsetWidth / 2);
    var anchorBottom = anchor.offsetTop + anchor.offsetHeight;
    t.plan(2);
    t.equal(formCenter, anchorCenter, 'Lines up with its anchor horizontally');
    t.ok(formTop >= anchorBottom, 'Sits below its anchor');
  });

  t.test('calls its onSubmit prop on form submission', function(t) {
    var form = React.findDOMNode(modal.refs.form);
    TestUtils.Simulate.submit(form);
    t.plan(1);
    t.equal(submissions, 1, 'onSubmit called');
  });

  t.test('calls its onCancel prop on ESC', function(t) {
    simulant.fire(window, 'keydown', {
      which: modal.ESC_KEY
    });
    t.plan(1);
    t.equal(cancellations, 1, 'onCancel called');
  });

  t.test('calls its onCancel prop on clicking the underlay', function(t) {
    var underlay = React.findDOMNode(modal.refs.underlay);
    TestUtils.Simulate.click(underlay);
    t.plan(1);
    t.equal(cancellations, 2, 'onCancel called');
  });

  t.test('clean up', function() {
    React.unmountComponentAtNode(container);
    anchor.parentElement.removeChild(anchor);
    container.parentElement.removeChild(container);
    t.end();
  });
});
<commit_msg>Test hash change<commit_after>var test = require('tape');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var ModalForm = require('../index');
var simulant = require('simulant');

test('ModalForm', function(t) {
  t.test('is exported', function(t) {
    t.plan(1);
    t.equal(typeof ModalForm, 'function', 'Exported the constructor');
  });

  t.test('can be created', function(t) {
    var instance = React.createElement(ModalForm);
    t.plan(1);
    t.ok(instance, 'Instance created');
  });

  t.test('can get a bounding rectangle including margin', function(t) {
    var rectElement = document.createElement('div');
    rectElement.id = 'rect-element';
    rectElement.style.width = '10px';
    rectElement.style.height = '10px';
    rectElement.style.margin = '10px';
    document.body.appendChild(rectElement);

    var rect = ModalForm.prototype.getRect(rectElement);
    t.plan(2);
    t.equal(rect.width, 30, 'Correct rect width');
    t.equal(rect.height, 30, 'Correct rect height');

    rectElement.parentElement.removeChild(rectElement);
  });
});

test('An instance', function(t) {
  var container = document.createElement('div');
  container.id = 'modal-form-container';
  document.body.appendChild(container);

  var anchor = document.createElement('div');
  anchor.id = 'modal-form-anchor';
  anchor.style.width = '100px';
  anchor.style.height = '100px';
  anchor.style.position = 'absolute';
  anchor.style.left = '100px';
  anchor.style.top = '100px';
  document.body.appendChild(anchor);

  var submissions = 0;
  var cancellations = 0;

  var modal = React.render(React.createElement(ModalForm, {
    anchor: anchor,
    onSubmit: function() {
      submissions += 1;
    },
    onCancel: function() {
      cancellations += 1;
    }
  }, React.createElement('div', {
    style: {
      width: '50px',
      height: '50px'
    }
  })), container);

  t.test('is positioned under its anchor', function(t) {
    var form = React.findDOMNode(modal.refs.form);
    var formCenter = form.offsetLeft + (form.offsetWidth / 2);
    var formTop = form.offsetTop;
    var anchorCenter = anchor.offsetLeft + (anchor.offsetWidth / 2);
    var anchorBottom = anchor.offsetTop + anchor.offsetHeight;
    t.plan(2);
    t.equal(formCenter, anchorCenter, 'Lines up with its anchor horizontally');
    t.ok(formTop >= anchorBottom, 'Sits below its anchor');
  });

  t.test('calls its onSubmit prop on form submission', function(t) {
    var form = React.findDOMNode(modal.refs.form);
    TestUtils.Simulate.submit(form);
    t.plan(1);
    t.equal(submissions, 1, 'onSubmit called');
  });

  t.test('calls its onCancel prop on ESC', function(t) {
    simulant.fire(window, 'keydown', {
      which: modal.ESC_KEY
    });
    t.plan(1);
    t.equal(cancellations, 1, 'onCancel called');
  });

  t.test('calls its onCancel prop on clicking the underlay', function(t) {
    var underlay = React.findDOMNode(modal.refs.underlay);
    TestUtils.Simulate.click(underlay);
    t.plan(1);
    t.equal(cancellations, 2, 'onCancel called');
  });

  t.test('calls its onCancel prop when changing the hash', function(t) {
    simulant.fire(window, 'hashchange');
    t.plan(1);
    t.equal(cancellations, 3, 'onCancel called');
  });

  t.test('clean up', function() {
    React.unmountComponentAtNode(container);
    anchor.parentElement.removeChild(anchor);
    container.parentElement.removeChild(container);
    t.end();
  });
});
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var assert = require('assert');

var summary = require('../').parse.summary;
var navigation = require('../').parse.navigation;

var CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/SUMMARY.md'), 'utf8');
var LEXED = summary(CONTENT);

describe('Summary navigation', function() {
    it('should provide next & prev entries for a file', function() {
        var nav = navigation(LEXED, [
            'README.html',
            'chapter-1/README.html',
            'chapter-1/ARTICLE1.html',
            'chapter-1/ARTICLE2.html',
            'chapter-2/README.html',
        ]);

        // Make sure it found the files we gave it
        assert(nav['README.html']);
        assert(nav['chapter-1/README.html']);
        assert(nav['chapter-1/ARTICLE1.html']);
        assert(nav['chapter-1/ARTICLE2.html']);
        assert(nav['chapter-2/README.html']);

        assert.equal(nav['README.html'].prev, null);
        assert.equal(nav['README.html'].next.path, 'chapter-1/README.html');

        assert.equal(nav['chapter-1/README.html'].prev.path, 'README.html');
        assert.equal(nav['chapter-1/README.html'].next.path, 'chapter-1/ARTICLE1.html');

        assert.equal(nav['chapter-1/ARTICLE1.html'].prev.path, 'chapter-1/README.html');
        assert.equal(nav['chapter-1/ARTICLE1.html'].next.path, 'chapter-1/ARTICLE2.html');

        assert.equal(nav['chapter-1/ARTICLE2.html'].prev.path, 'chapter-1/ARTICLE1.html');
        assert.equal(nav['chapter-1/ARTICLE2.html'].next.path, 'chapter-2/README.html');

        assert.equal(nav['chapter-2/README.html'].prev.path, 'chapter-1/ARTICLE2.html');
        assert.equal(nav['chapter-2/README.html'].next.path, 'chapter-3/README.html');
    });

    it('should give full tree, when not limited', function() {
        var nav = navigation(LEXED);

        assert(nav['README.html']);
        assert(nav['chapter-1/README.html']);
        assert(nav['chapter-1/ARTICLE1.html']);
        assert(nav['chapter-1/ARTICLE2.html']);
        assert(nav['chapter-2/README.html']);
        assert(nav['chapter-3/README.html']);
    });
});
<commit_msg>Add tests for level attribute in navigation<commit_after>var fs = require('fs');
var path = require('path');
var assert = require('assert');

var summary = require('../').parse.summary;
var navigation = require('../').parse.navigation;

var CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/SUMMARY.md'), 'utf8');
var LEXED = summary(CONTENT);

describe('Summary navigation', function() {
    it('should provide next & prev entries for a file', function() {
        var nav = navigation(LEXED, [
            'README.html',
            'chapter-1/README.html',
            'chapter-1/ARTICLE1.html',
            'chapter-1/ARTICLE2.html',
            'chapter-2/README.html',
        ]);

        // Make sure it found the files we gave it
        assert(nav['README.html']);
        assert(nav['chapter-1/README.html']);
        assert(nav['chapter-1/ARTICLE1.html']);
        assert(nav['chapter-1/ARTICLE2.html']);
        assert(nav['chapter-2/README.html']);

        assert.equal(nav['README.html'].prev, null);
        assert.equal(nav['README.html'].next.path, 'chapter-1/README.html');

        assert.equal(nav['chapter-1/README.html'].prev.path, 'README.html');
        assert.equal(nav['chapter-1/README.html'].next.path, 'chapter-1/ARTICLE1.html');

        assert.equal(nav['chapter-1/ARTICLE1.html'].prev.path, 'chapter-1/README.html');
        assert.equal(nav['chapter-1/ARTICLE1.html'].next.path, 'chapter-1/ARTICLE2.html');

        assert.equal(nav['chapter-1/ARTICLE2.html'].prev.path, 'chapter-1/ARTICLE1.html');
        assert.equal(nav['chapter-1/ARTICLE2.html'].next.path, 'chapter-2/README.html');

        assert.equal(nav['chapter-2/README.html'].prev.path, 'chapter-1/ARTICLE2.html');
        assert.equal(nav['chapter-2/README.html'].next.path, 'chapter-3/README.html');
    });

    it('should give full tree, when not limited', function() {
        var nav = navigation(LEXED);

        assert(nav['README.html']);
        assert(nav['chapter-1/README.html']);
        assert(nav['chapter-1/ARTICLE1.html']);
        assert(nav['chapter-1/ARTICLE2.html']);
        assert(nav['chapter-2/README.html']);
        assert(nav['chapter-3/README.html']);
    });

    it('should detect levels correctly', function() {
        var nav = navigation(LEXED);

        assert.equal(nav['README.html'].level, '0');
        assert.equal(nav['chapter-1/README.html'].level, '1');
        assert.equal(nav['chapter-1/ARTICLE1.html'].level, '1.1');
        assert.equal(nav['chapter-1/ARTICLE2.html'].level, '1.2');
        assert.equal(nav['chapter-2/README.html'].level, '2');
        assert.equal(nav['chapter-3/README.html'].level, '3');
    });
});
<|endoftext|>


<commit_before>/*
 * daycount.js v0.1.4
 * http://yellowseed.org/daycount.js/
 *
 * Copyright 2011, Joshua Tacoma
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

// All other globals defined here are kept in this object:
var daycount = (typeof exports !== 'undefined' && exports !== null)
  ? exports : {};

// The 'moment' type, which may include associated information from any
// calendar system:
daycount.moment = (function() {

  // 'moment' constructor:
  function moment(arg) {
    this.set(arg);
  };

  moment.prototype.set = function(arg) {
    if(!arg || arg === null)
      arg = new Date();

    // Now, we're going to calculate as many counts as possible...

    // 'todo' lists counts to be calculated:
    var todo = []
    for(var name in daycount.counts)
    {
      todo.push(name);
      // wipe out any counts lingering from previous calculations:
      if(name in this)
        delete this[name];
    }

    // 'done' lists known counts:
    var done = [arg.constructor.name];
    // TODO: make sure that no item in 'done' is also in 'todo'.

    if (!(arg.constructor.name in daycount.counts))
      this.isUnknown = true;

    // Store argument as the only known property of this:
    this[arg.constructor.name] = arg;

    // Iterate through counts in 'done'.  We're going to add to this list as we
    // go, which makes this for loop a little more interesting:
    for (var indexDone = 0;
         indexDone < done.length && todo.length > 0;
         ++indexDone)
    {
      var nameDone = done[indexDone];
      var builderNameTodo = 'from_' + nameDone;

      // Iterate through counts in 'todo'.  Since we're going to remove
      // them as we go, iterate backwards to keep remaining indices
      // from shifting:
      for (var indexTodo = todo.length - 1; indexTodo >= 0; --indexTodo) {
        var nameTodo = todo[indexTodo];
        var countTodo = daycount.counts[nameTodo];

        if(!countTodo.hasOwnProperty(builderNameTodo)) continue;

        // Found one!  Calculate the value for 'countTodo':
        var builder = countTodo[builderNameTodo];
        var built = builder(this[nameDone]);
        if(built === null) continue;

        this[nameTodo] = built;
        done.push(nameTodo);
        todo.splice(indexTodo, 1)
        if('isUnknown' in this)
          delete this['isUnknown'];
      }
    }
  };

  moment.prototype.plusEarthSolarDays = function(days) {
    if('localJulianDay' in this)
      return new moment(
        new daycount.counts.localJulianDay(
          this.localJulianDay.number + days));
    else
      throw 'this moment has no counts that support the specified increment.';
  };

  moment.prototype.plus = moment.prototype.plusEarthSolarDays;

  return moment;
})();

// A collection of counts i.e. calendar systems.
// Each calendar system should be added to this object.
daycount.counts = {};

daycount.version_ = {
  major: 0,
  minor: 1,
  build: 4,
};

<commit_msg>updated version to 0.1.5.<commit_after>/*
 * daycount.js v0.1.5
 * http://yellowseed.org/daycount.js/
 *
 * Copyright 2011, Joshua Tacoma
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

// All other globals defined here are kept in this object:
var daycount = (typeof exports !== 'undefined' && exports !== null)
  ? exports : {};

// The 'moment' type, which may include associated information from any
// calendar system:
daycount.moment = (function() {

  // 'moment' constructor:
  function moment(arg) {
    this.set(arg);
  };

  moment.prototype.set = function(arg) {
    if(!arg || arg === null)
      arg = new Date();

    // Now, we're going to calculate as many counts as possible...

    // 'todo' lists counts to be calculated:
    var todo = []
    for(var name in daycount.counts)
    {
      todo.push(name);
      // wipe out any counts lingering from previous calculations:
      if(name in this)
        delete this[name];
    }

    // 'done' lists known counts:
    var done = [arg.constructor.name];
    // TODO: make sure that no item in 'done' is also in 'todo'.

    if (!(arg.constructor.name in daycount.counts))
      this.isUnknown = true;

    // Store argument as the only known property of this:
    this[arg.constructor.name] = arg;

    // Iterate through counts in 'done'.  We're going to add to this list as we
    // go, which makes this for loop a little more interesting:
    for (var indexDone = 0;
         indexDone < done.length && todo.length > 0;
         ++indexDone)
    {
      var nameDone = done[indexDone];
      var builderNameTodo = 'from_' + nameDone;

      // Iterate through counts in 'todo'.  Since we're going to remove
      // them as we go, iterate backwards to keep remaining indices
      // from shifting:
      for (var indexTodo = todo.length - 1; indexTodo >= 0; --indexTodo) {
        var nameTodo = todo[indexTodo];
        var countTodo = daycount.counts[nameTodo];

        if(!countTodo.hasOwnProperty(builderNameTodo)) continue;

        // Found one!  Calculate the value for 'countTodo':
        var builder = countTodo[builderNameTodo];
        var built = builder(this[nameDone]);
        if(built === null) continue;

        this[nameTodo] = built;
        done.push(nameTodo);
        todo.splice(indexTodo, 1)
        if('isUnknown' in this)
          delete this['isUnknown'];
      }
    }
  };

  moment.prototype.plusEarthSolarDays = function(days) {
    if('localJulianDay' in this)
      return new moment(
        new daycount.counts.localJulianDay(
          this.localJulianDay.number + days));
    else
      throw 'this moment has no counts that support the specified increment.';
  };

  moment.prototype.plus = moment.prototype.plusEarthSolarDays;

  return moment;
})();

// A collection of counts i.e. calendar systems.
// Each calendar system should be added to this object.
daycount.counts = {};

daycount.version_ = {
  major: 0,
  minor: 1,
  build: 5,
};

<|endoftext|>


<commit_before>'use strict';

/* global select, update, Model, Manager, hasMany, belongsTo, w, f */
function dontRun() {

// db abstraction layer

select('users').join('posts', 'users.id', 'posts.user_id'); // select * from users left join posts on users.id = posts.user_id;
select('users').join('posts'); // select * from users left join posts on users.id = posts.user_id;

// REVISIT: distinct
// REVISIT: return values (rather than objects)
// REVISIT: express transaction middleware (every request wrapped in a transaction)

// types

update('people').set({ name: 'Whit' }).where({ id: '1' });

// REVISIT: testing. here are some things to consider
//   - handle insert of objects with specific IDs
//   - handle reseting sequence ids for testing

var query = w({ 'id[gte]': 4 }, w.and, w({ name: 'Whit' }, w.or, { name: 'Brit' }));
// id >= $1 && (name = $2 || name = $3) [4, 'Whit', 'Brit']

update('people').set({ fullName: f('firstName + " " + lastName') });

// orm layer

// REVISIT: validations (before/after save, before/after update, before/after destroy)
// REVISIT: polymorphic
// REVISIT: inherited
// REVISIT: aggregation
// REVISIT: transactions
// REVISIT: events/hooks for logging
// REVISIT: raw that returns real model objects & raw that returns just js objects
// REVISIT: all association types & through associations + convenience methods for associations
// REVISIT: feature like scope in rails or just use django manager style

// REVISIT: allow pk override
// REVISIT: allow table name override

var FemaleManager = Manager.extend({
  querySet: function() {
    return this._super().where({ sex: 'female' });
  }
});

var MaleManager = Manager.extend({
  querySet: function() {
    return this._super().where({ sex: 'male' });
  }
});

var Person = Model.extend('person', {
  posts: hasMany('posts')
}, {
  women: FemaleManager,
  men: MaleManager,
  objects: Manager // could customize...
});

var Post = Model.extend('post', {
  author: belongsTo('person', { key: 'user_id', foreignKey: 'id' })
});

var person, post, post1, post2;

person = Person.create({ name: 'Whitney' });
person.save().then('...'); // insert into people (name) values "$1" ["Whitney"]

// REVISIT: createOrUpdate()

// or can this use real property setting?
person.set('name', 'Whit'); // update people set name = 'Whit' where id = 1;

Post.objects.all().then('...'); // select * from posts;
Post.objects.where({ pk: 1 }).fetch().then('...'); // select * from posts where posts.id = 1;
Post.objects.with('author').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id;
Post.objects.with('author').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id;
Post.objects.with('author', 'comments').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id; REVISIT: more query for second relation

// REVISIT: consider more active record approach than django approach where there are no managers, and
// Post.objects.... becomes Post.all() or Post.where....
// REVISIT: consider Post.objects.first()
// REVISIT: consider helper methods like Post.objects.find_by_title() returning just one (exception for 0 or many) by title
// REVISIT: events/hooks for lifecycle and/or validation

// REVISIT: support difference between join queries and prefetching?

Post.objects.update({ 'title': 'What' }); // update posts set title = 'What'
Post.objects.with('author').update({ 'title': f('title + " "') }); // update posts left join poeple on posts.user_id = user.id

Post.objects.delete(); // delete from posts;
post.delete(); // delete from posts where id = 2;

Post.objects.where({ 'author.name[contains]': 'Whit' }).fetch().then('...');
// select * from posts left join people on posts.user_id = user.id where people.name like $1 ["Whit"];
Post.objects.where({ 'author.name[contains]': 'Whit' }).fetchOne().then('...'); // throws if not exactly one record
// select * from posts left join people on posts.user_id = user.id where people.name like $1 ["Whit"];
Post.objects.where({ 'author.name[contains]': 'Whit' }).orderBy('name', 'desc').limit(10).offset(20).fetch().then('...');
// select * from posts left join people on posts.user_id = user.id where people.name like $1 order by name desc limit 10 offset 20 ["Whit"];

post = Post.create({ title: 'Example' });
person.posts.add(post).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]
person.posts.create({ title: 'Example' }).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]

person.posts.add(post1, post2).then('...'); // insert into posts (title, person_id) values ($1, $2), ($3, $4) ["Example1", 1, "Example2", 1]
person.posts.remove(post1, post2).then('...'); // update posts set id = null where person_id = 1 and id in $1 [1, 2]
person.posts.clear().then('...'); // update posts set id = null where person_id = 1

post = person.posts.create({ title: 'Example' }).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]

var qs = Post.objects.all();
qs.fetch(); // runs query
qs.fetch(); // pulls from cache (this could be optional)

qs.clone(); // creates duplicate that you can do different things with (generally not needed because each call would clone the query set)

var createTable, createJoinTable;

// migrations
// migrations must run within both a transaction and a serial wrapper
// change handle both up and down (reversible) migrations
exports.change = function() {
  createTable('people', function(table) {
    table.string('name');
    table.text('something');
    table.timestamps();
  });
  createTable('posts', function(table) {
    table.references('person');
  });
  createTable('things');
  createJoinTable('author', 'book');
};

exports.serialEnabled = false; // disable automatic serial wrapping for this migration
exports.transactionEnabled = false; // disable automatic transaction wrapping for this migration

// separate up/down migrations (throws with change defined as well)
exports.up = function() {

};
exports.down = function() {

};

console.log(query);

}
if (dontRun) {}<commit_msg>Removed notes for items that have already been implemented.<commit_after>'use strict';

/* global select, update, Model, Manager, hasMany, belongsTo, w, f */
function dontRun() {

// db abstraction layer

// REVISIT: distinct
// REVISIT: return values (rather than objects)
// REVISIT: express transaction middleware (every request wrapped in a transaction)

// REVISIT: testing helpers. here are some things to consider that are nice to have
// during app development:
//   - handle insert of objects with specific IDs
//   - handle reseting sequence ids for testing

// orm layer

// REVISIT: validations (before/after save, before/after update, before/after destroy)
// REVISIT: polymorphic
// REVISIT: inherited
// REVISIT: aggregation
// REVISIT: transactions
// REVISIT: events/hooks for logging
// REVISIT: raw that returns real model objects & raw that returns just js objects
// REVISIT: all association types & through associations + convenience methods for associations
// REVISIT: feature like scope in rails or just use django manager style

// REVISIT: allow pk override
// REVISIT: allow table name override

var FemaleManager = Manager.extend({
  querySet: function() {
    return this._super().where({ sex: 'female' });
  }
});

var MaleManager = Manager.extend({
  querySet: function() {
    return this._super().where({ sex: 'male' });
  }
});

var Person = Model.extend('person', {
  posts: hasMany('posts')
}, {
  women: FemaleManager,
  men: MaleManager,
  objects: Manager // could customize...
});

var Post = Model.extend('post', {
  author: belongsTo('person', { key: 'user_id', foreignKey: 'id' })
});

var person, post, post1, post2;

person = Person.create({ name: 'Whitney' });
person.save().then('...'); // insert into people (name) values "$1" ["Whitney"]

// REVISIT: createOrUpdate()

// or can this use real property setting?
person.set('name', 'Whit'); // update people set name = 'Whit' where id = 1;

Post.objects.all().then('...'); // select * from posts;
Post.objects.where({ pk: 1 }).fetch().then('...'); // select * from posts where posts.id = 1;
Post.objects.with('author').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id;
Post.objects.with('author').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id;
Post.objects.with('author', 'comments').fetch().then('...'); // select * from posts left join people on posts.user_id = user.id; REVISIT: more query for second relation

// REVISIT: consider more active record approach than django approach where there are no managers, and
// Post.objects.... becomes Post.all() or Post.where....
// REVISIT: consider Post.objects.first()
// REVISIT: consider helper methods like Post.objects.find_by_title() returning just one (exception for 0 or many) by title
// REVISIT: events/hooks for lifecycle and/or validation

// REVISIT: support difference between join queries and prefetching?

Post.objects.update({ 'title': 'What' }); // update posts set title = 'What'
Post.objects.with('author').update({ 'title': f('title + " "') }); // update posts left join poeple on posts.user_id = user.id

Post.objects.delete(); // delete from posts;
post.delete(); // delete from posts where id = 2;

Post.objects.where({ 'author.name[contains]': 'Whit' }).fetch().then('...');
// select * from posts left join people on posts.user_id = user.id where people.name like $1 ["Whit"];
Post.objects.where({ 'author.name[contains]': 'Whit' }).fetchOne().then('...'); // throws if not exactly one record
// select * from posts left join people on posts.user_id = user.id where people.name like $1 ["Whit"];
Post.objects.where({ 'author.name[contains]': 'Whit' }).orderBy('name', 'desc').limit(10).offset(20).fetch().then('...');
// select * from posts left join people on posts.user_id = user.id where people.name like $1 order by name desc limit 10 offset 20 ["Whit"];

post = Post.create({ title: 'Example' });
person.posts.add(post).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]
person.posts.create({ title: 'Example' }).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]

person.posts.add(post1, post2).then('...'); // insert into posts (title, person_id) values ($1, $2), ($3, $4) ["Example1", 1, "Example2", 1]
person.posts.remove(post1, post2).then('...'); // update posts set id = null where person_id = 1 and id in $1 [1, 2]
person.posts.clear().then('...'); // update posts set id = null where person_id = 1

post = person.posts.create({ title: 'Example' }).then('...'); // insert into posts (title, person_id) values $1, $2 ["Example", 1]

var qs = Post.objects.all();
qs.fetch(); // runs query
qs.fetch(); // pulls from cache (this could be optional)

qs.clone(); // creates duplicate that you can do different things with (generally not needed because each call would clone the query set)

var createTable, createJoinTable;

// migrations
// migrations must run within both a transaction and a serial wrapper
// change handle both up and down (reversible) migrations
exports.change = function() {
  createTable('people', function(table) {
    table.string('name');
    table.text('something');
    table.timestamps();
  });
  createTable('posts', function(table) {
    table.references('person');
  });
  createTable('things');
  createJoinTable('author', 'book');
};

exports.serialEnabled = false; // disable automatic serial wrapping for this migration
exports.transactionEnabled = false; // disable automatic transaction wrapping for this migration

// separate up/down migrations (throws with change defined as well)
exports.up = function() {

};
exports.down = function() {

};

console.log(query);

}
if (dontRun) {}<|endoftext|>


<commit_before><commit_msg>BUG #69056 - Avoid show mutliple progress bar at the same time<commit_after><|endoftext|>


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

describe('Accounts', () => {
  it('Should be', () => {
    expect(true).eql(true);
  });
});
<commit_msg>[UNIT-TEST] - up coverage Account<commit_after>import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
chai.use(sinonChai);
const { expect } = chai;
import account from '../src/Account';

describe('Accounts', () => {
  global.localStorage = {
    removeItem: sinon.spy(),
    setItem: sinon.spy(),
  };

  global.window = {
    dispatchEvent: sinon.spy(),
  };

  global.CustomEvent = sinon.spy();
  global.Event = sinon.spy();
  account.logger = sinon.spy();

  context('when loggedIn', () => {
    context('when success', () => {
      it('Should set item in localStorage and execute dispatchEvent', () => {
        const loginToken = '123456';
        const loginTokenExpires = 0;
        const userId = '123456';

        account.loggedIn(loginToken, loginTokenExpires, userId);
        expect(localStorage.setItem).to.have.been.calledWith('Graphite.loginToken', loginToken);
        expect(localStorage.setItem).to.have.been.calledWith('Graphite.loginTokenExpires', loginTokenExpires);
        expect(localStorage.setItem).to.have.been.calledWith('Graphite.userId', userId);
        expect(CustomEvent).to.have.been.calledWith('loggedIn',  { detail: { loginToken, loginTokenExpires, userId } });
        expect(window.dispatchEvent).to.have.been.called;
      });
    });

    context('when failed', () => {
      it('Should execute logger with error message', () => {
        const loginToken = '123456';
        const loginTokenExpires = 0;
        const userId = '123456';
        const error = 'Error';
        localStorage.setItem = () => {};
        sinon.stub(localStorage, 'setItem', () => { throw new Error(error); });

        account.loggedIn(loginToken, loginTokenExpires, userId);

        expect(account.logger).to.have.been.calledWith(`Error loggedIn: ${error}`);
      });
    });
  });

  context('when logout', () => {
    context('when success', () => {
      it('Should remove item in localStorage and execute dispatchEvent', () => {
        account.logout();
        expect(localStorage.removeItem).to.have.been.calledWith('Graphite.loginToken');
        expect(localStorage.removeItem).to.have.been.calledWith('Graphite.loginTokenExpires');
        expect(localStorage.removeItem).to.have.been.calledWith('Graphite.userId');
        expect(Event).to.have.been.calledWith('logout');
        expect(window.dispatchEvent).to.have.been.called;
      });
    });

    context('when failed', () => {
      it('Should execute logger with error message', () => {
        const error = 'Error';
        localStorage.removeItem = () => {};
        sinon.stub(localStorage, 'removeItem', () => { throw new Error(error); });

        account.logout();

        expect(account.logger).to.have.been.calledWith(`Error logout: ${error}`);
      });
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>Use library.textAdd where possible.<commit_after><|endoftext|>


<commit_before>import {
  default as createStore
} from 'store/createStore'

describe('(Store) createStore', () => {
  let store

  before(() => {
    store = createStore()
  })

  it('should have an empty asyncReducers object', () => {
    expect(store.asyncReducers).to.be.an('object')
    expect(store.asyncReducers).to.be.empty()
  })

  describe('(Location)', () => {
    it('store should be initialized with Location state', () => {
      const location = {
        pathname : '/echo'
      }
      store.dispatch({
        type    : 'LOCATION_CHANGE',
        payload : location
      })
      expect(store.getState().location).not.to.deep.equal(location)
    })
  })
})
<commit_msg>Fixed a test<commit_after>import {
  default as createStore
} from 'store/createStore'

describe('(Store) createStore', () => {
  let store

  before(() => {
    store = createStore()
  })

  it('should have an empty asyncReducers object', () => {
    expect(store.asyncReducers).to.be.an('object')
    expect(store.asyncReducers).to.be.empty()
  })

  describe('(Location)', () => {
    it('store should be initialized with Location state', () => {
      const location = {
        pathname : '/echo'
      }
      store.dispatch({
        type    : 'LOCATION_CHANGE',
        payload : location
      })
      expect(store.getState().location).to.deep.equal(location)
    })
  })
})
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import InputRange from 'react-input-range'
import classnames from 'classnames'
import themed from 'react-themed'

@themed('*', {
  pure: true,
})

export default class RangeSlider extends Component {
  static propTypes = {
    theme: PropTypes.object,
    className: PropTypes.string,
    onChange: PropTypes.func,
    formatHeader: PropTypes.func,
    value: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.object,
    ]),
  }

  static defaultProps = {
    theme: {},
    value: 0,
  }

  constructor(props) {
    super(props)
    this.onChange = this.onChange.bind(this)
    this.state = { value: props.value }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ value: nextProps.value })
  }

  onChange(value) {
    if (this.props.onChange) this.props.onChange(value)
    this.setState({ value })
  }

  render() {
    const {
      theme,
      className,
      onChange,
      formatHeader,
      ...props
    } = this.props

    return (

        {formatHeader && formatHeader(this.state.value)}
        <InputRange
          {...props}
          onChange={this.onChange}
          value={this.state.value}
          classNames={theme}
        />

    )
  }
}
<commit_msg>fixing react warning on react-input-range<commit_after>import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import InputRange from 'react-input-range'
import classnames from 'classnames'
import omit from 'lodash/omit'
import themed from 'react-themed'

@themed('*', {
  pure: true,
})

export default class RangeSlider extends PureComponent {
  static propTypes = {
    theme: PropTypes.object,
    className: PropTypes.string,
    onChange: PropTypes.func,
    formatHeader: PropTypes.func,
    value: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.object,
    ]),
  }

  static defaultProps = {
    theme: {},
    value: 0,
  }

  constructor(props) {
    super(props)
    this.onChange = this.onChange.bind(this)
    this.state = { value: props.value }

    this.setSliderTheme(props.theme)
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.value !== nextProps.value) {
      this.setState({ value: nextProps.value })
    }

    if (this.props.theme !== nextProps.theme) {
      this.setSliderTheme(nextProps.theme)
    }
  }

  onChange(value) {
    if (this.props.onChange) this.props.onChange(value)
    this.setState({ value })
  }

  setSliderTheme(theme) {
    // NOTE: this ensures react-input-range plays nicely with theme object
    this.sliderTheme = omit(theme, '_getCss', '_insertCss')
  }

  render() {
    const {
      theme,
      className,
      onChange,
      formatHeader,
      ...props
    } = this.props

    return (

        {formatHeader && formatHeader(this.state.value)}
        <InputRange
          {...props}
          onChange={this.onChange}
          value={this.state.value}
          classNames={this.sliderTheme}
        />

    )
  }
}
<|endoftext|>


<commit_before>const webpack = require('webpack');

const DEBUG = process.env.NODE_ENV !== 'production';

module.exports = {
  output: {
    library: 'ReduxSagaRequests',
    libraryTarget: 'umd',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
  externals: {
    'redux-saga/effects': {
      commonjs: 'redux-saga/effects',
      commonjs2: 'redux-saga/effects',
      amd: 'redux-saga/effects',
      root: 'ReduxSaga.effects',
    },
  },
  devtool: 'source-map',
  plugins: [
    DEBUG
      ? new webpack.NamedModulesPlugin()
      : new webpack.HashedModuleIdsPlugin({
          hashFunction: 'sha256',
          hashDigest: 'hex',
          hashDigestLength: 20,
        }),
  ],
};
<commit_msg>Removed redux-saga from umd bundle<commit_after>const webpack = require('webpack');

const DEBUG = process.env.NODE_ENV !== 'production';

module.exports = {
  output: {
    library: 'ReduxSagaRequests',
    libraryTarget: 'umd',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
  externals: {
    'redux-saga/effects': {
      commonjs: 'redux-saga/effects',
      commonjs2: 'redux-saga/effects',
      amd: 'redux-saga/effects',
      root: 'ReduxSaga.effects',
    },
    'redux-saga': {
      commonjs: 'redux-saga',
      commonjs2: 'redux-saga',
      amd: 'redux-saga',
      root: 'ReduxSaga',
    },
  },
  devtool: 'source-map',
  plugins: [
    DEBUG
      ? new webpack.NamedModulesPlugin()
      : new webpack.HashedModuleIdsPlugin({
          hashFunction: 'sha256',
          hashDigest: 'hex',
          hashDigestLength: 20,
        }),
  ],
};
<|endoftext|>


<commit_before>/* globals getHttpBridge, waitPromise */

RocketChat.Sandstorm.notify = function() {};

if (process.env.SANDSTORM === '1') {
	var ACTIVITY_TYPES = {
		'message': 0,
		'privateMessage': 1
	};

	RocketChat.Sandstorm.notify = function(message, userIds, caption, type) {
		var sessionId = message.sandstormSessionId;
		if (!sessionId) {
			return;
		}
		var httpBridge = getHttpBridge();
		var activity = {};

		if (type) {
			activity.type = ACTIVITY_TYPES[type];
		}

		if (caption) {
			activity.notification = {caption: {defaultText: caption}};
		}

		if (userIds) {
			activity.users = _.map(userIds, function(userId) {
				var user = Meteor.users.findOne({_id: userId}, {fields: {'services.sandstorm.id': 1}});
				return {
					identity: httpBridge.getSavedIdentity(user.services.sandstorm.id).identity,
					mentioned: true
				};
			});
		}

		return waitPromise(httpBridge.getSessionContext(sessionId).context.activity(activity));
	};
}
<commit_msg>Try to work around bug with identity being saved/restored<commit_after>/* globals getHttpBridge, waitPromise */

RocketChat.Sandstorm.notify = function() {};

if (process.env.SANDSTORM === '1') {
	var ACTIVITY_TYPES = {
		'message': 0,
		'privateMessage': 1
	};

	RocketChat.Sandstorm.notify = function(message, userIds, caption, type) {
		var sessionId = message.sandstormSessionId;
		if (!sessionId) {
			return;
		}
		var httpBridge = getHttpBridge();
		var activity = {};

		if (type) {
			activity.type = ACTIVITY_TYPES[type];
		}

		if (caption) {
			activity.notification = {caption: {defaultText: caption}};
		}

		if (userIds) {
			activity.users = _.map(userIds, function(userId) {
				var user = Meteor.users.findOne({_id: userId}, {fields: {'services.sandstorm.id': 1}});
				return {
					identity: waitPromise(httpBridge.getSavedIdentity(user.services.sandstorm.id)).identity,
					mentioned: true
				};
			});
		}

		return waitPromise(httpBridge.getSessionContext(sessionId).context.activity(activity));
	};
}
<|endoftext|>


<commit_before>// saves some loading time by loading most of the commonly-used
// JBrowse modules at the outset
require([
            'JBrowse/Browser',
            'JBrowse/ConfigAdaptor/JB_json_v1',

            // default tracklist view
            'JBrowse/View/TrackList/Hierarchical',

            // common stores
            'JBrowse/Store/Sequence/StaticChunked',
            'JBrowse/Store/SeqFeature/NCList',
            'JBrowse/Store/TiledImage/Fixed',
            'JBrowse/Store/Names/Hash',
            'JBrowse/Store/Names/REST',

            // common track views
            'JBrowse/View/Track/Sequence',
            'JBrowse/View/Track/HTMLFeatures',
            'JBrowse/View/Track/FixedImage/Wiggle',
            'JBrowse/View/Track/Wiggle',
            'JBrowse/View/Track/Wiggle/XYPlot',
            'JBrowse/View/Track/Wiggle/Density',
            'JBrowse/View/Track/Alignments',
            'JBrowse/View/Track/Alignments2',
            'JBrowse/View/Track/FeatureCoverage',
            'JBrowse/View/Track/SNPCoverage',

            // track lists
            'JBrowse/Store/TrackMetaData',
            'dojox/gfx/svg'
        ]);
<commit_msg>Include dstore in build<commit_after>// saves some loading time by loading most of the commonly-used
// JBrowse modules at the outset
require([
            'JBrowse/Browser',
            'JBrowse/ConfigAdaptor/JB_json_v1',

            // default tracklist view
            'JBrowse/View/TrackList/Hierarchical',

            // common stores
            'JBrowse/Store/Sequence/StaticChunked',
            'JBrowse/Store/SeqFeature/NCList',
            'JBrowse/Store/TiledImage/Fixed',
            'JBrowse/Store/Names/Hash',
            'JBrowse/Store/Names/REST',

            // common track views
            'JBrowse/View/Track/Sequence',
            'JBrowse/View/Track/HTMLFeatures',
            'JBrowse/View/Track/FixedImage/Wiggle',
            'JBrowse/View/Track/Wiggle',
            'JBrowse/View/Track/Wiggle/XYPlot',
            'JBrowse/View/Track/Wiggle/Density',
            'JBrowse/View/Track/Alignments',
            'JBrowse/View/Track/Alignments2',
            'JBrowse/View/Track/FeatureCoverage',
            'JBrowse/View/Track/SNPCoverage',

            // track lists
            'JBrowse/Store/TrackMetaData',
            'dojox/gfx/svg',
            'dstore/Memory'
        ]);
<|endoftext|>


<commit_before>const React = require('react');
const classNames = require('classnames');

const Icon = require('./Icon');
const STYLES = require('./STYLES');
const SIZES = require('./SIZES');

const BUTTONS_STYLES = STYLES.concat([
    'link',
    'marketing-primary',
    'secondary',
    'count'
]);

const Button = React.createClass({
    propTypes: {
        className:      React.PropTypes.string,
        children:       React.PropTypes.node,
        type:           React.PropTypes.string,
        size:           React.PropTypes.oneOf(SIZES),
        style:          React.PropTypes.oneOf(BUTTONS_STYLES),
        // Makes a link button
        href:           React.PropTypes.string,
        // Form button
        value:          React.PropTypes.oneOfType([
            React.PropTypes.string,
            React.PropTypes.bool,
            React.PropTypes.number
        ]),
        name:           React.PropTypes.string,
        // For links
        target:         React.PropTypes.string,
        filled:         React.PropTypes.bool,
        noBorder:       React.PropTypes.bool,
        disabled:       React.PropTypes.bool,
        active:         React.PropTypes.bool,
        block:          React.PropTypes.bool,
        dropdownToggle: React.PropTypes.bool,
        onClick:        React.PropTypes.func,
        title:          React.PropTypes.string,
        icon:           React.PropTypes.string
    },

    getInitialState() {
        return {
            clicked: false
        };
    },

    getDefaultProps() {
        return {
            style:    'default',
            size:     'md',
            type:     'button',
            filled:   false,
            disabled: false,
            active:   false
        };
    },

    onClick(e) {
        const { clicked } = this.state;

        if (this.props.onClick && !clicked) {
            this.props.onClick(e);
        }

        if (!this.isFormButton()) {
            return;
        } else if (clicked) {
            return this.setState({
                clicked: false
            });
        }

        // Add this submitting button's value to the form as hidden
        // input. Only after that do the click.
        // This fixes issues with PJAX[1] in Firefox[2]
        // [1]: https://github.com/defunkt/jquery-pjax/pull/295
        // [2]: http://stackoverflow.com/questions/38277900/formdata-object-does-not-add-submit-type-inputs-from-form-while-on-firefox
        e.preventDefault();
        this.setState({
            clicked: true
        }, () => {
            this.refs.button.click();
        });
    },

    isFormButton() {
        const { type, name } = this.props;
        return type === 'submit' && name;
    },

    render() {
        const { clicked } = this.state;
        const {
            title, icon, filled, block, noBorder, active, dropdownToggle,
            style, size, className, children, name, value, disabled,
            ...props
        } = this.props;

        const inner = icon ? <Icon className={icon} /> : '';

        props.className = classNames(
            'btn', 'btn-' + style, 'btn-' + size,
            className, {
                'btn-fill':        filled,
                'btn-block':       block,
                'btn-noborder':    noBorder,
                active, disabled,
                'dropdown-toggle': dropdownToggle,
                'tooltipped':      Boolean(title)
            }
        );
        props['aria-label'] = title;
        props.role          = 'button';
        props.disabled      = disabled;
        props.onClick       = this.onClick;

        let input;

        if (clicked && this.isFormButton()) {
            input = <input type="hidden" name={name} value={value} />;
        }

        if (props.href) {
            delete props.type;
            return {inner} {children};
        } else {
            return <button ref="button" {...props}>{inner} {children}{input}</button>;
        }
    }
});

const ButtonGroup = React.createClass({
    propTypes: {
        className: React.PropTypes.string,
        children:  React.PropTypes.node,
        pull:      React.PropTypes.string,
        block:     React.PropTypes.bool
    },

    render() {
        let { className, pull, children, block, ...props } = this.props;

        className = classNames(
            'btn-group',
            className,
            pull ? 'pull-' + pull : '',
            {
                'btn-group-block': block
            }
        );

        return
{children}
;
    }
});

const ButtonToolbar = React.createClass({
    propTypes: {
        className:  React.PropTypes.string,
        children: React.PropTypes.node
    },

    render() {
        const { className, children, ...props } = this.props;

        return
{children}
;
    }
});

const ButtonCaret = React.createClass({
    render() {
        return ;
    }
});

const ButtonTextExpander = React.createClass({
    propTypes: {
        onClick: React.PropTypes.func
    },

    onClick(e) {
        if (this.props.onClick) {
            this.props.onClick();
        }
    },

    render() {
        return (

                <button type="button" className="ellipsis-expander" onClick={this.onClick}>…</button>

        );
    }
});

module.exports              = Button;
module.exports.Group        = ButtonGroup;
module.exports.Toolbar      = ButtonToolbar;
module.exports.Caret        = ButtonCaret;
module.exports.TextExpander = ButtonTextExpander;
module.exports.STYLES       = BUTTONS_STYLES;
<commit_msg>Prevent clicks on links in Button when component is disabled (#48)<commit_after>const React = require('react');
const classNames = require('classnames');

const Icon = require('./Icon');
const STYLES = require('./STYLES');
const SIZES = require('./SIZES');

const BUTTONS_STYLES = STYLES.concat([
    'link',
    'marketing-primary',
    'secondary',
    'count'
]);

const Button = React.createClass({
    propTypes: {
        className:      React.PropTypes.string,
        children:       React.PropTypes.node,
        type:           React.PropTypes.string,
        size:           React.PropTypes.oneOf(SIZES),
        style:          React.PropTypes.oneOf(BUTTONS_STYLES),
        // Makes a link button
        href:           React.PropTypes.string,
        // Form button
        value:          React.PropTypes.oneOfType([
            React.PropTypes.string,
            React.PropTypes.bool,
            React.PropTypes.number
        ]),
        name:           React.PropTypes.string,
        // For links
        target:         React.PropTypes.string,
        filled:         React.PropTypes.bool,
        noBorder:       React.PropTypes.bool,
        disabled:       React.PropTypes.bool,
        active:         React.PropTypes.bool,
        block:          React.PropTypes.bool,
        dropdownToggle: React.PropTypes.bool,
        onClick:        React.PropTypes.func,
        title:          React.PropTypes.string,
        icon:           React.PropTypes.string
    },

    getInitialState() {
        return {
            clicked: false
        };
    },

    getDefaultProps() {
        return {
            style:    'default',
            size:     'md',
            type:     'button',
            filled:   false,
            disabled: false,
            active:   false
        };
    },

    onClick(e) {
        // Prevent any action if button is disabled
        const { disabled } = this.props;
        if (disabled) {
            e.preventDefault();
            return;
        }

        const { clicked } = this.state;
        if (this.props.onClick && !clicked) {
            this.props.onClick(e);
        }

        if (!this.isFormButton()) {
            return;
        } else if (clicked) {
            return this.setState({
                clicked: false
            });
        }

        // Add this submitting button's value to the form as hidden
        // input. Only after that do the click.
        // This fixes issues with PJAX[1] in Firefox[2]
        // [1]: https://github.com/defunkt/jquery-pjax/pull/295
        // [2]: http://stackoverflow.com/questions/38277900/formdata-object-does-not-add-submit-type-inputs-from-form-while-on-firefox
        e.preventDefault();
        this.setState({
            clicked: true
        }, () => {
            this.refs.button.click();
        });
    },

    isFormButton() {
        const { type, name } = this.props;
        return type === 'submit' && name;
    },

    render() {
        const { clicked } = this.state;
        const {
            title, icon, filled, block, noBorder, active, dropdownToggle,
            style, size, className, children, name, value, disabled,
            ...props
        } = this.props;

        const inner = icon ? <Icon className={icon} /> : '';

        props.className = classNames(
            'btn', 'btn-' + style, 'btn-' + size,
            className, {
                'btn-fill':        filled,
                'btn-block':       block,
                'btn-noborder':    noBorder,
                active, disabled,
                'dropdown-toggle': dropdownToggle,
                'tooltipped':      Boolean(title)
            }
        );
        props['aria-label'] = title;
        props.role = 'button';
        props.disabled = disabled;
        props.onClick = this.onClick;
        // Update href if button is disabled
        props.href = disabled ? '#' : props.href;

        let input;

        if (clicked && this.isFormButton()) {
            input = <input type="hidden" name={name} value={value} />;
        }

        if (props.href) {
            delete props.type;
            return {inner} {children};
        } else {
            return <button ref="button" {...props}>{inner} {children}{input}</button>;
        }
    }
});

const ButtonGroup = React.createClass({
    propTypes: {
        className: React.PropTypes.string,
        children:  React.PropTypes.node,
        pull:      React.PropTypes.string,
        block:     React.PropTypes.bool
    },

    render() {
        let { className, pull, children, block, ...props } = this.props;

        className = classNames(
            'btn-group',
            className,
            pull ? 'pull-' + pull : '',
            {
                'btn-group-block': block
            }
        );

        return
{children}
;
    }
});

const ButtonToolbar = React.createClass({
    propTypes: {
        className:  React.PropTypes.string,
        children: React.PropTypes.node
    },

    render() {
        const { className, children, ...props } = this.props;

        return
{children}
;
    }
});

const ButtonCaret = React.createClass({
    render() {
        return ;
    }
});

const ButtonTextExpander = React.createClass({
    propTypes: {
        onClick: React.PropTypes.func
    },

    onClick(e) {
        if (this.props.onClick) {
            this.props.onClick();
        }
    },

    render() {
        return (

                <button type="button" className="ellipsis-expander" onClick={this.onClick}>…</button>

        );
    }
});

module.exports              = Button;
module.exports.Group        = ButtonGroup;
module.exports.Toolbar      = ButtonToolbar;
module.exports.Caret        = ButtonCaret;
module.exports.TextExpander = ButtonTextExpander;
module.exports.STYLES       = BUTTONS_STYLES;
<|endoftext|>


<commit_before>// namespace for holding all Canvas2D related classes and functions
var Canvas2D = {};

// technical wrapper class for the HTML5 Canvas element
Canvas2D.Canvas = Class.create( {
    tabbed     : false, // tabbed interface

    wait       : false, // indicator not to draw

    htmlcanvas : null,  // the Canvas Element
    canvas     : null,  // the Canvas Element 2D context

    console    : null,  // the HTML element to use as Console
    source     : null,  // the HTML element to use as SourceViewer

    sheets       : [], // list of sheets on this Canvas
    currentSheet : 0,  // index of the current show sheet

    eventHandlers : {}, // map of registered eventHandlers

    mouseOver : false,   // indicator if the mouse is currently over the canvas
    mousePos  : { x:0, y:0 }, // current mouse position

    currentX    : 0,       // current drawing position on X-axis
    currentY    : 0,       // current drawing position on Y-axis
    lineWidth   : 1,       // current drawing lineWidth
    lineStyle   : "solid", // current drawing lineStyle [solid|dashed]
    strokeStyle : "black", // current drawing strokeStyle
    fillStyle   : "black", // current drawing fillStyle

    initialize: function(id) {
	this.tabbed  = false;

	this.wait = false;

	this.sheets = new Array();
	this.currentSheet = 0;

	this.eventHandlers = {},

	this.currentX    = 0;
	this.currentY    = 0;
	this.lineWidth   = 1;
	this.lineStyle   = "solid";
	this.strokeStyle = "black";
	this.fillStyle   = "black";

	// setup HTML5 canvas
	this.htmlcanvas = document.getElementById(id);
	this.wireCanvas();

	// look for a console and sources for this canvas
	this.console = document.getElementById( id+"Console" );
	this.source  = document.getElementById( id+"Source" );
    },

    clear: function() {
	this.sheets = [];
    },

    wireCanvas: function() {
	if( this.htmlcanvas ) {
	    this.canvas = this.htmlcanvas.getContext('2d');
	    if( this.canvas ) {
		// attach eventhandlers for mouse events
		Event.observe(this.htmlcanvas, 'mousedown',
			      this.handleMouseDown.bindAsEventListener(this));
		Event.observe(this.htmlcanvas, 'mouseup',
			      this.handleMouseUp.bindAsEventListener(this));
		Event.observe(window, 'mousemove',
			      this.handleMouseMove.bindAsEventListener(this));
		// add textfunctions
		CanvasTextFunctions.enable(this.canvas);
	    }
	}
    },

    makeTab: function(name, height, content) {
	var tab = document.createElement("div");
	tab.className = "tabbertab";
	tab.style.height = ( 4 + parseInt(height) ) + "px";
	var head = document.createElement("h2");
	var txt = document.createTextNode(name);
	head.appendChild(txt);
	tab.appendChild(head);
	tab.appendChild(content);
	return tab;
    },

    getAboutTab: function(width,height) {
	var about = document.createElement("div");
	about.className = "Canvas2D-about";
	about.style.height = height + "px";
	about.style.width = (parseInt(width)-4)  + "px";
	about.innerHTML = '' +
	    'Canvas2D
Copyright &copy 2009, ' +
	    'Christophe VG'+
	    ' & The Software Factory
' +
	    'Visit http://thesoftwarefactory.be/wiki/Canvas2D ' +
	    'for more info. Licensed under the ' +
	    'BSD License.';
	return this.makeTab("About", height, about );
    },

    getConsoleTab: function(width, height) {
	this.console = document.createElement("textarea");
	this.console.className = "Canvas2D-console";
	this.console.style.height = height + "px";
	this.console.style.width  = ( parseInt(width) - 4 )  + "px";
	return this.makeTab("Console", height, this.console );
    },

    getSourceTab: function(width, height) {
	this.source = document.createElement("textarea");
	this.source.className = "Canvas2D-source";
	this.source.style.height = height + "px";
	this.source.style.width  = ( parseInt(width) - 4 )  + "px";
	return this.makeTab("Source", height, this.source );
    },

    getCurrentSheet: function() {
	return this.sheets[this.currentSheet];
    },

    updateSource: function(source) {
	if( this.source && this.getCurrentSheet() ) {
	    this.source.value = this.getCurrentSheet().toString();
	}
    },

    // TODO: this is ugly, try to find a better solution
    makeTabbed: function(tabs) {
	if( this.tabbed ) { return; }
	var source = this.htmlcanvas;
	var tabber = document.createElement("div");
	tabber.className="tabber";
	tabber.style.width = (parseInt(source.width) + 17) + "px";
	tabber.style.height = (parseInt(source.height) + 37) + "px";
	var tab1 = document.createElement("div");
	tab1.className = "tabbertab";
	var h1 = document.createElement("h2");
	var t1 = document.createTextNode("Diagram");
	h1.appendChild(t1);
	tab1.appendChild(h1);
	var newCanvas = document.createElement("canvas");
	newCanvas.id = source.id;
	newCanvas.className = source.className;
	newCanvas.width = source.width;
	newCanvas.height = source.height;
	tab1.appendChild(newCanvas);
	tabber.appendChild(tab1);

	if( tabs ) {
	    if( tabs.indexOf("console") > -1 ) {
		tabber.appendChild(this.getConsoleTab(source.width,
						      source.height));
	    }
	    if( tabs.indexOf("source") > -1 ) {
		tabber.appendChild(this.getSourceTab(source.width,
						     source.height));
	    }

	    if( tabs.indexOf("about") > -1 ) {
		tabber.appendChild(this.getAboutTab(source.width,
						    source.height));
	    }
	}

	source.parentNode.replaceChild(tabber, source);
	// apply excanvas to new element
	try {
	    this.htmlcanvas = G_vmlCanvasManager.initElement(newCanvas);
	} catch(err) {
	    this.htmlcanvas = newCanvas;
	}
	tabberAutomatic(); // activate Tabber
	this.wireCanvas(); // rewire Canvas2D events,...
	this.render();     // force rerender

	this.tabbed = true;
    },

    on: function( event, handler ) {
	this.eventHandlers[event] = handler;
    },

    fireEvent: function( event, data ) {
	if( this.eventHandlers[event] ) {
	    this.eventHandlers[event](data);
	}
    },

    log: function( msg ) {
	if( this.console ) {
	    this.console.value = msg + "\n" + this.console.value;
	}
    },

    getLeft: function() {
	var elem = this.htmlcanvas;
	var left = 0;
	while( elem != null ) {
	    left += elem.offsetLeft;
	    elem = elem.offsetParent;
	}
	return left;
    },

    getTop: function() {
	var elem = this.htmlcanvas;
	var top = 0;
	while( elem != null ) {
	    top += elem.offsetTop;
	    elem = elem.offsetParent;
	}
	return top;
    },

    getXY: function(event) {
	if( event == null ) { event = window.event; }
	if( event == null ) { return null;          }
	if( event.pageX || event.pageY ) {
            return { x: event.pageX - this.getLeft(),
		     y: event.pageY - this.getTop()  };
	}
	return null;
    },

    handleMouseDown: function(event) {
	this.mousepressed = true;
	var pos = this.getXY(event);
	this.fireEvent( "mousedown", pos );
	this.mousePos = pos;
	this.render();
    },

    handleMouseUp: function(event) {
	this.mousepressed = false;
	var pos = this.getXY();
	this.fireEvent( "mouseup", pos );
	this.mousePos = pos;
	this.render();
    },

    handleMouseMove: function(event) {
	if( this.mousepressed ) {
	    this.handleMouseDrag(event);
	}
	var pos = this.getXY();
	this.mouseOver =
	    ( pos.x >= 0 && pos.x <= this.htmlcanvas.width )
	    &&
	    ( pos.y >= 0 && pos.y <= this.htmlcanvas.height );
    },

    handleMouseDrag: function(event) {
	var pos = this.getXY(event);
	this.fireEvent( "mousedrag", { x: pos.x,
				       y: pos.y,
				       dx: pos.x - this.mousePos.x,
				       dy: pos.y - this.mousePos.y } );
	this.mousePos = pos;
	this.render();
    },

    clearRect: function(x, y, w, h ) {
	this.canvas.clearRect( x, y, w, h );
    },

    fillRect: function(x, y, w, h ) {
	this.canvas.fillStyle = this.fillStyle;
	this.canvas.fillRect( x, y, w, h );
    },

    strokeRect: function(x, y, w, h ) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.strokeRect( x, y, w, h );
    },

    beginPath: function() {
	this.canvas.beginPath();
    },

    closePath: function() {
	this.canvas.closePath();
    },

    stroke: function() {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.lineWidth = this.lineWidth;
	this.canvas.stroke();
    },

    fill: function() {
	this.canvas.fillStyle = this.fillStyle;
	this.canvas.fill();
    },

    moveTo: function(x,y) {
	this.canvas.moveTo( x, y );
	this.currentX = x;
	this.currentY = y;
    },

    lineTo: function(x,y) {
	if( this.lineStyle == "dashed" ) {
	    this._drawLine( this.currentX, this.currentY, x, y );
	} else {
	    this.canvas.lineTo( x, y );
	}
	this.currentX = x;
	this.currentY = y;
    },

    measureText: function(font, size, text) {
	return this.canvas.measureText( font, size, text );
    },

    drawTextCenter: function(font, size, left, top, text) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.drawTextCenter(font, size, left, top, text);
    },

    drawText: function(font, size, left, top, text) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.drawText(font, size, left, top, text);
    },

    rotate: function(ang) {
	this.canvas.rotate(ang);
    },

    arc: function(left, top, radius, startAngle, endAngle, anticlockwise ) {
	this.canvas.arc(left, top, radius,
			startAngle, endAngle, anticlockwise );
    },

    _plotPixel: function( x, y, c ) {
	with( this.canvas ) {
	    var oldStyle = strokeStyle;
	    beginPath();
	    strokeStyle = c;
	    moveTo(x,y);
	    lineTo(x+1,y+1);
	    stroke();
	    closePath();
	    strokeStyle = oldStyle;
	}
    },

    _drawLine: function(x1, y1, x2, y2 ) {
	x1 = Math.floor(x1);
	x2 = Math.floor(x2);
	y1 = Math.floor(y1-1);
	y2 = Math.floor(y2-1);
	// to make sure other strokes are stroked:
	this.canvas.stroke();

	var c = this.strokeStyle;
	var style = this.lineStyle;

	var steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);
	if (steep) {
            t = y1;            y1 = x1;            x1 = t;
            t = y2;            y2 = x2;            x2 = t;
	}
	var deltaX = Math.abs(x2 - x1);
	var deltaY = Math.abs(y2 - y1);
	var error = 0;
	var deltaErr = deltaY;
	var xStep;
	var yStep;
	var x = x1;
	var y = y1;
	if(x1 < x2) {  xStep = 1; } else { xStep = -1; }
	if(y1 < y2) {  yStep = 1; } else { yStep = -1;	}
	if( steep ) { this._plotPixel(y, x, c); }
	else        { this._plotPixel(x, y, c); }
	var dot = 0;
	while( x != x2 ) {
            x = x + xStep;
            error = error + deltaErr;
            if( 2 * error >= deltaX ) {
		y = y + yStep;
		error = error - deltaX;
            }
	    var color = ( style != "dashed" || ++dot % 15 ) < 10 ? c : "white";
            if(steep) { this._plotPixel(y, x, color); }
	    else      { this._plotPixel(x, y, color); }
	}
    },

    freeze: function() {
	this.wait = true;
    },

    thaw: function() {
	this.wait = false;
	this.render();
    },

    addWaterMark: function() {
	this.canvas.save();
	this.strokeStyle = "rgba(0,0,0,0.50)";
	this.rotate(Math.PI/2);
	this.drawText( "Sans", 6, 3, (this.htmlcanvas.width * -1) + 7,
		       "Canvas2D / Christophe VG" );
	this.canvas.restore();
    },

    addToolbar: function() {
	if( this.mouseOver ) {
	    // TODO: future feature ;-)
	}
    },

    render: function() {
	if( this.wait || !this.canvas ) { return; }

	if( this.getCurrentSheet() ) {
	    this.canvas.clearRect( 0, 0,
				   this.htmlcanvas.width,
				   this.htmlcanvas.height );
	    this.getCurrentSheet().render();
	    this.updateSource();
	}

	this.addWaterMark();
	this.addToolbar();
    },

    toString: function() {
	var s = "";
	this.sheets.each(function(sheet) {
	    s += sheet.toString() + "\n";
	} );
	return s;
    },

    addSheet: function(sheet) {
	this.sheets.push(sheet);
	sheet.setCanvas(this);
	return sheet;
    },

    add: function(sheet) {
	return this.addSheet(sheet);
    },

    load: function(source) {
	this.clear();

	var parser = new ADL.Parser();
	var tree;
	if( ( tree = parser.parse( source ) ) ) {
	    this.freeze();
	    tree.getRoot().accept(new Canvas2D.ADLVisitor(), this );
	    this.thaw();
	}
    }

} );
<commit_msg>fixed bad calls of getXY, not passing event<commit_after>// namespace for holding all Canvas2D related classes and functions
var Canvas2D = {};

// technical wrapper class for the HTML5 Canvas element
Canvas2D.Canvas = Class.create( {
    tabbed     : false, // tabbed interface

    wait       : false, // indicator not to draw

    htmlcanvas : null,  // the Canvas Element
    canvas     : null,  // the Canvas Element 2D context

    console    : null,  // the HTML element to use as Console
    source     : null,  // the HTML element to use as SourceViewer

    sheets       : [], // list of sheets on this Canvas
    currentSheet : 0,  // index of the current show sheet

    eventHandlers : {}, // map of registered eventHandlers

    mouseOver : false,   // indicator if the mouse is currently over the canvas
    mousePos  : { x:0, y:0 }, // current mouse position

    currentX    : 0,       // current drawing position on X-axis
    currentY    : 0,       // current drawing position on Y-axis
    lineWidth   : 1,       // current drawing lineWidth
    lineStyle   : "solid", // current drawing lineStyle [solid|dashed]
    strokeStyle : "black", // current drawing strokeStyle
    fillStyle   : "black", // current drawing fillStyle

    initialize: function(id) {
	this.tabbed  = false;

	this.wait = false;

	this.sheets = new Array();
	this.currentSheet = 0;

	this.eventHandlers = {},

	this.currentX    = 0;
	this.currentY    = 0;
	this.lineWidth   = 1;
	this.lineStyle   = "solid";
	this.strokeStyle = "black";
	this.fillStyle   = "black";

	// setup HTML5 canvas
	this.htmlcanvas = document.getElementById(id);
	this.wireCanvas();

	// look for a console and sources for this canvas
	this.console = document.getElementById( id+"Console" );
	this.source  = document.getElementById( id+"Source" );
    },

    clear: function() {
	this.sheets = [];
    },

    wireCanvas: function() {
	if( this.htmlcanvas ) {
	    this.canvas = this.htmlcanvas.getContext('2d');
	    if( this.canvas ) {
		// attach eventhandlers for mouse events
		Event.observe(this.htmlcanvas, 'mousedown',
			      this.handleMouseDown.bindAsEventListener(this));
		Event.observe(this.htmlcanvas, 'mouseup',
			      this.handleMouseUp.bindAsEventListener(this));
		Event.observe(window, 'mousemove',
			      this.handleMouseMove.bindAsEventListener(this));
		// add textfunctions
		CanvasTextFunctions.enable(this.canvas);
	    }
	}
    },

    makeTab: function(name, height, content) {
	var tab = document.createElement("div");
	tab.className = "tabbertab";
	tab.style.height = ( 4 + parseInt(height) ) + "px";
	var head = document.createElement("h2");
	var txt = document.createTextNode(name);
	head.appendChild(txt);
	tab.appendChild(head);
	tab.appendChild(content);
	return tab;
    },

    getAboutTab: function(width,height) {
	var about = document.createElement("div");
	about.className = "Canvas2D-about";
	about.style.height = height + "px";
	about.style.width = (parseInt(width)-4)  + "px";
	about.innerHTML = '' +
	    'Canvas2D
Copyright &copy 2009, ' +
	    'Christophe VG'+
	    ' & The Software Factory
' +
	    'Visit http://thesoftwarefactory.be/wiki/Canvas2D ' +
	    'for more info. Licensed under the ' +
	    'BSD License.';
	return this.makeTab("About", height, about );
    },

    getConsoleTab: function(width, height) {
	this.console = document.createElement("textarea");
	this.console.className = "Canvas2D-console";
	this.console.style.height = height + "px";
	this.console.style.width  = ( parseInt(width) - 4 )  + "px";
	return this.makeTab("Console", height, this.console );
    },

    getSourceTab: function(width, height) {
	this.source = document.createElement("textarea");
	this.source.className = "Canvas2D-source";
	this.source.style.height = height + "px";
	this.source.style.width  = ( parseInt(width) - 4 )  + "px";
	return this.makeTab("Source", height, this.source );
    },

    getCurrentSheet: function() {
	return this.sheets[this.currentSheet];
    },

    updateSource: function(source) {
	if( this.source && this.getCurrentSheet() ) {
	    this.source.value = this.getCurrentSheet().toString();
	}
    },

    // TODO: this is ugly, try to find a better solution
    makeTabbed: function(tabs) {
	if( this.tabbed ) { return; }
	var source = this.htmlcanvas;
	var tabber = document.createElement("div");
	tabber.className="tabber";
	tabber.style.width = (parseInt(source.width) + 17) + "px";
	tabber.style.height = (parseInt(source.height) + 37) + "px";
	var tab1 = document.createElement("div");
	tab1.className = "tabbertab";
	var h1 = document.createElement("h2");
	var t1 = document.createTextNode("Diagram");
	h1.appendChild(t1);
	tab1.appendChild(h1);
	var newCanvas = document.createElement("canvas");
	newCanvas.id = source.id;
	newCanvas.className = source.className;
	newCanvas.width = source.width;
	newCanvas.height = source.height;
	tab1.appendChild(newCanvas);
	tabber.appendChild(tab1);

	if( tabs ) {
	    if( tabs.indexOf("console") > -1 ) {
		tabber.appendChild(this.getConsoleTab(source.width,
						      source.height));
	    }
	    if( tabs.indexOf("source") > -1 ) {
		tabber.appendChild(this.getSourceTab(source.width,
						     source.height));
	    }

	    if( tabs.indexOf("about") > -1 ) {
		tabber.appendChild(this.getAboutTab(source.width,
						    source.height));
	    }
	}

	source.parentNode.replaceChild(tabber, source);
	// apply excanvas to new element
	try {
	    this.htmlcanvas = G_vmlCanvasManager.initElement(newCanvas);
	} catch(err) {
	    this.htmlcanvas = newCanvas;
	}
	tabberAutomatic(); // activate Tabber
	this.wireCanvas(); // rewire Canvas2D events,...
	this.render();     // force rerender

	this.tabbed = true;
    },

    on: function( event, handler ) {
	this.eventHandlers[event] = handler;
    },

    fireEvent: function( event, data ) {
	if( this.eventHandlers[event] ) {
	    this.eventHandlers[event](data);
	}
    },

    log: function( msg ) {
	if( this.console ) {
	    this.console.value = msg + "\n" + this.console.value;
	}
    },

    getLeft: function() {
	var elem = this.htmlcanvas;
	var left = 0;
	while( elem != null ) {
	    left += elem.offsetLeft;
	    elem = elem.offsetParent;
	}
	return left;
    },

    getTop: function() {
	var elem = this.htmlcanvas;
	var top = 0;
	while( elem != null ) {
	    top += elem.offsetTop;
	    elem = elem.offsetParent;
	}
	return top;
    },

    getXY: function(event) {
	if( event == null ) { event = window.event; }
	if( event == null ) { return null;          }
	if( event.pageX || event.pageY ) {
            return { x: event.pageX - this.getLeft(),
		     y: event.pageY - this.getTop()  };
	}
	return null;
    },

    handleMouseDown: function(event) {
	this.mousepressed = true;
	var pos = this.getXY(event);
	this.fireEvent( "mousedown", pos );
	this.mousePos = pos;
	this.render();
    },

    handleMouseUp: function(event) {
	this.mousepressed = false;
	var pos = this.getXY(event);
	this.fireEvent( "mouseup", pos );
	this.mousePos = pos;
	this.render();
    },

    handleMouseMove: function(event) {
	if( this.mousepressed ) {
	    this.handleMouseDrag(event);
	}
	var pos = this.getXY(event);
	if( pos ) {
	    this.mouseOver =
		( pos.x >= 0 && pos.x <= this.htmlcanvas.width )
		&&
		( pos.y >= 0 && pos.y <= this.htmlcanvas.height );
	}
    },

    handleMouseDrag: function(event) {
	var pos = this.getXY(event);
	this.fireEvent( "mousedrag", { x: pos.x,
				       y: pos.y,
				       dx: pos.x - this.mousePos.x,
				       dy: pos.y - this.mousePos.y } );
	this.mousePos = pos;
	this.render();
    },

    clearRect: function(x, y, w, h ) {
	this.canvas.clearRect( x, y, w, h );
    },

    fillRect: function(x, y, w, h ) {
	this.canvas.fillStyle = this.fillStyle;
	this.canvas.fillRect( x, y, w, h );
    },

    strokeRect: function(x, y, w, h ) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.strokeRect( x, y, w, h );
    },

    beginPath: function() {
	this.canvas.beginPath();
    },

    closePath: function() {
	this.canvas.closePath();
    },

    stroke: function() {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.lineWidth = this.lineWidth;
	this.canvas.stroke();
    },

    fill: function() {
	this.canvas.fillStyle = this.fillStyle;
	this.canvas.fill();
    },

    moveTo: function(x,y) {
	this.canvas.moveTo( x, y );
	this.currentX = x;
	this.currentY = y;
    },

    lineTo: function(x,y) {
	if( this.lineStyle == "dashed" ) {
	    this._drawLine( this.currentX, this.currentY, x, y );
	} else {
	    this.canvas.lineTo( x, y );
	}
	this.currentX = x;
	this.currentY = y;
    },

    measureText: function(font, size, text) {
	return this.canvas.measureText( font, size, text );
    },

    drawTextCenter: function(font, size, left, top, text) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.drawTextCenter(font, size, left, top, text);
    },

    drawText: function(font, size, left, top, text) {
	this.canvas.strokeStyle = this.strokeStyle;
	this.canvas.drawText(font, size, left, top, text);
    },

    rotate: function(ang) {
	this.canvas.rotate(ang);
    },

    arc: function(left, top, radius, startAngle, endAngle, anticlockwise ) {
	this.canvas.arc(left, top, radius,
			startAngle, endAngle, anticlockwise );
    },

    _plotPixel: function( x, y, c ) {
	with( this.canvas ) {
	    var oldStyle = strokeStyle;
	    beginPath();
	    strokeStyle = c;
	    moveTo(x,y);
	    lineTo(x+1,y+1);
	    stroke();
	    closePath();
	    strokeStyle = oldStyle;
	}
    },

    _drawLine: function(x1, y1, x2, y2 ) {
	x1 = Math.floor(x1);
	x2 = Math.floor(x2);
	y1 = Math.floor(y1-1);
	y2 = Math.floor(y2-1);
	// to make sure other strokes are stroked:
	this.canvas.stroke();

	var c = this.strokeStyle;
	var style = this.lineStyle;

	var steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);
	if (steep) {
            t = y1;            y1 = x1;            x1 = t;
            t = y2;            y2 = x2;            x2 = t;
	}
	var deltaX = Math.abs(x2 - x1);
	var deltaY = Math.abs(y2 - y1);
	var error = 0;
	var deltaErr = deltaY;
	var xStep;
	var yStep;
	var x = x1;
	var y = y1;
	if(x1 < x2) {  xStep = 1; } else { xStep = -1; }
	if(y1 < y2) {  yStep = 1; } else { yStep = -1;	}
	if( steep ) { this._plotPixel(y, x, c); }
	else        { this._plotPixel(x, y, c); }
	var dot = 0;
	while( x != x2 ) {
            x = x + xStep;
            error = error + deltaErr;
            if( 2 * error >= deltaX ) {
		y = y + yStep;
		error = error - deltaX;
            }
	    var color = ( style != "dashed" || ++dot % 15 ) < 10 ? c : "white";
            if(steep) { this._plotPixel(y, x, color); }
	    else      { this._plotPixel(x, y, color); }
	}
    },

    freeze: function() {
	this.wait = true;
    },

    thaw: function() {
	this.wait = false;
	this.render();
    },

    addWaterMark: function() {
	this.canvas.save();
	this.strokeStyle = "rgba(0,0,0,0.50)";
	this.rotate(Math.PI/2);
	this.drawText( "Sans", 6, 3, (this.htmlcanvas.width * -1) + 7,
		       "Canvas2D / Christophe VG" );
	this.canvas.restore();
    },

    addToolbar: function() {
	if( this.mouseOver ) {
	    // TODO: future feature ;-)
	}
    },

    render: function() {
	if( this.wait || !this.canvas ) { return; }

	if( this.getCurrentSheet() ) {
	    this.canvas.clearRect( 0, 0,
				   this.htmlcanvas.width,
				   this.htmlcanvas.height );
	    this.getCurrentSheet().render();
	    this.updateSource();
	}

	this.addWaterMark();
	this.addToolbar();
    },

    toString: function() {
	var s = "";
	this.sheets.each(function(sheet) {
	    s += sheet.toString() + "\n";
	} );
	return s;
    },

    addSheet: function(sheet) {
	this.sheets.push(sheet);
	sheet.setCanvas(this);
	return sheet;
    },

    add: function(sheet) {
	return this.addSheet(sheet);
    },

    load: function(source) {
	this.clear();

	var parser = new ADL.Parser();
	var tree;
	if( ( tree = parser.parse( source ) ) ) {
	    this.freeze();
	    tree.getRoot().accept(new Canvas2D.ADLVisitor(), this );
	    this.thaw();
	}
    }

} );
<|endoftext|>


<commit_before>'use strict'

import readCache from '../lib/read-cache'
import test from 'blue-tape'
import Request from './helpers/req'
import debug from 'debug'

const log = debug('readCache')

test('readCache closure', t => {
  const closure = readCache({})

  t.equals(typeof closure, 'function', 'reading from cache should return a closure')
  t.end()
})

test('readCache closure is a promise', t => {
  const closure = readCache({})

  t.ok(closure() instanceof Promise, 'reading from cache should return a promise')
  t.end()
})

test('readCache success callback', t => {
  const value = {
    expires: 0,
    data: {
      body: {
        responseType: 'text',
        responseText: 'Hello world',
        status: 200,
        statusText: 'OK'
      },
      headers: 'content-type: text/plain'
    }
  }

  const req = new Request()

  return new Promise(resolve => {
    readCache(req, log)(value)
      .then(res => {
        t.equals(res.body, value.data.body.responseText, 'response should be defined')

        resolve()
      })
      .catch(err => {
        // add test in case of error
        t.error(err, 'hydration should not throw')

        resolve()
      })
  })
})

test('readCache error callback', t => {
  const req = new Request()

  return new Promise(resolve => {
    readCache(req, log)(false)
      .then(res => {
        t.error('response should not be defined on cache miss')

        resolve()
      })
      .catch(err => {
        // add test in case of error
        t.equals(err.reason, 'cache-miss', 'reading from cache should throw on cache miss')

        resolve()
      })
  })
})
<commit_msg>test(readCache): rename test title<commit_after>'use strict'

import readCache from '../lib/read-cache'
import test from 'blue-tape'
import Request from './helpers/req'
import debug from 'debug'

const log = debug('readCache')

test('readCache closure', t => {
  const closure = readCache({})

  t.equals(typeof closure, 'function', 'reading from cache should return a closure')
  t.end()
})

test('readCache closure is a promise', t => {
  const closure = readCache({})

  t.ok(closure() instanceof Promise, 'reading from cache should return a promise')
  t.end()
})

test('readCache cache success', t => {
  const value = {
    expires: 0,
    data: {
      body: {
        responseType: 'text',
        responseText: 'Hello world',
        status: 200,
        statusText: 'OK'
      },
      headers: 'content-type: text/plain'
    }
  }

  const req = new Request()

  return new Promise(resolve => {
    readCache(req, log)(value)
      .then(res => {
        t.equals(res.body, value.data.body.responseText, 'response should be defined')

        resolve()
      })
      .catch(err => {
        // add test in case of error
        t.error(err, 'hydration should not throw')

        resolve()
      })
  })
})

test('readCache cache miss', t => {
  const req = new Request()

  return new Promise(resolve => {
    readCache(req, log)(false)
      .then(res => {
        t.error('response should not be defined on cache miss')

        resolve()
      })
      .catch(err => {
        // add test in case of error
        t.equals(err.reason, 'cache-miss', 'reading from cache should throw on cache miss')

        resolve()
      })
  })
})
<|endoftext|>