diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/background/actions/find.test.js | 13 | ||||
| -rw-r--r-- | test/background/reducers/find.test.js | 19 | ||||
| -rw-r--r-- | test/background/reducers/setting.test.js | 36 | ||||
| -rw-r--r-- | test/console/actions/console.test.js | 6 | ||||
| -rw-r--r-- | test/console/reducers/console.test.js | 6 | ||||
| -rw-r--r-- | test/content/actions/setting.test.js | 2 | ||||
| -rw-r--r-- | test/content/navigates.test.js | 156 | ||||
| -rw-r--r-- | test/content/reducers/find.test.js | 2 | ||||
| -rw-r--r-- | test/settings/components/form/blacklist-form.test.jsx | 82 | ||||
| -rw-r--r-- | test/settings/components/form/keymaps-form.test.jsx | 53 | ||||
| -rw-r--r-- | test/settings/components/form/properties-form.test.jsx | 86 | ||||
| -rw-r--r-- | test/settings/components/form/search-engine-form.test.jsx | 104 | ||||
| -rw-r--r-- | test/settings/components/ui/input.test.jsx | 83 | ||||
| -rw-r--r-- | test/shared/commands/parsers.test.js | 85 | ||||
| -rw-r--r-- | test/shared/settings/validator.test.js (renamed from test/shared/validators/setting.test.js) | 2 | ||||
| -rw-r--r-- | test/shared/settings/values.test.js | 139 | 
16 files changed, 835 insertions, 39 deletions
| diff --git a/test/background/actions/find.test.js b/test/background/actions/find.test.js new file mode 100644 index 0000000..467604f --- /dev/null +++ b/test/background/actions/find.test.js @@ -0,0 +1,13 @@ +import { expect } from "chai"; +import actions from 'background/actions'; +import * as findActions from 'background/actions/find'; + +describe("find actions", () => { +  describe("setKeyword", () => { +    it('create FIND_SET_KEYWORD action', () => { +      let action = findActions.setKeyword('banana'); +      expect(action.type).to.equal(actions.FIND_SET_KEYWORD); +      expect(action.keyword).to.equal('banana'); +    }); +  }); +}); diff --git a/test/background/reducers/find.test.js b/test/background/reducers/find.test.js new file mode 100644 index 0000000..707d73a --- /dev/null +++ b/test/background/reducers/find.test.js @@ -0,0 +1,19 @@ +import { expect } from "chai"; +import actions from 'background/actions'; +import findReducer from 'background/reducers/find'; + +describe("find reducer", () => { +  it('return the initial state', () => { +    let state = findReducer(undefined, {}); +    expect(state).to.have.deep.property('keyword', null); +  }); + +  it('return next state for FIND_SET_KEYWORD', () => { +    let action = { +      type: actions.FIND_SET_KEYWORD, +      keyword: 'cherry', +    }; +    let state = findReducer(undefined, action); +    expect(state).to.have.deep.property('keyword', 'cherry') +  }); +}); diff --git a/test/background/reducers/setting.test.js b/test/background/reducers/setting.test.js new file mode 100644 index 0000000..8df5abe --- /dev/null +++ b/test/background/reducers/setting.test.js @@ -0,0 +1,36 @@ +import { expect } from "chai"; +import actions from 'background/actions'; +import settingReducer from 'background/reducers/setting'; + +describe("setting reducer", () => { +  it('return the initial state', () => { +    let state = settingReducer(undefined, {}); +    expect(state).to.have.deep.property('value', {}); +  }); + +  it('return next state for SETTING_SET_SETTINGS', () => { +    let action = { +      type: actions.SETTING_SET_SETTINGS, +      value: { key: 123 }, +    }; +    let state = settingReducer(undefined, action); +    expect(state).to.have.deep.property('value', { key: 123 }); +  }); + +  it('return next state for SETTING_SET_PROPERTY', () => { +    let state = { +      value: { +        properties: { smoothscroll: true } +      } +    } +    let action = { +      type: actions.SETTING_SET_PROPERTY, +      name: 'encoding', +      value: 'utf-8', +    }; +    state = settingReducer(state, action); + +    expect(state.value.properties).to.have.property('smoothscroll', true); +    expect(state.value.properties).to.have.property('encoding', 'utf-8'); +  }); +}); diff --git a/test/console/actions/console.test.js b/test/console/actions/console.test.js index 9af13d4..1774431 100644 --- a/test/console/actions/console.test.js +++ b/test/console/actions/console.test.js @@ -3,6 +3,12 @@ import actions from 'console/actions';  import * as consoleActions from 'console/actions/console';  describe("console actions", () => { +  describe('hide', () => { +    it('create CONSOLE_HIDE action', () => { +      let action = consoleActions.hide(); +      expect(action.type).to.equal(actions.CONSOLE_HIDE); +    }); +  });    describe("showCommand", () => {      it('create CONSOLE_SHOW_COMMAND action', () => {        let action = consoleActions.showCommand('hello'); diff --git a/test/console/reducers/console.test.js b/test/console/reducers/console.test.js index 438d513..d196011 100644 --- a/test/console/reducers/console.test.js +++ b/test/console/reducers/console.test.js @@ -13,6 +13,12 @@ describe("console reducer", () => {      expect(state).to.have.property('itemSelection', -1);    }); +  it('return next state for CONSOLE_HIDE', () => { +    let action = { type: actions.CONSOLE_HIDE }; +    let state = reducer({ mode: 'error' }, action); +    expect(state).to.have.property('mode', ''); +  }) +    it('return next state for CONSOLE_SHOW_COMMAND', () => {      let action = { type: actions.CONSOLE_SHOW_COMMAND, text: 'open ' };      let state = reducer({}, action); diff --git a/test/content/actions/setting.test.js b/test/content/actions/setting.test.js index 1248edf..3112b2d 100644 --- a/test/content/actions/setting.test.js +++ b/test/content/actions/setting.test.js @@ -23,6 +23,8 @@ describe("setting actions", () => {        let map = new Map(keymaps);        expect(map).to.have.deep.all.keys(          [ +          [{ key: 'Esc', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }], +          [{ key: '[', shiftKey: false, ctrlKey: true, altKey: false, metaKey: false }],            [{ key: 'd', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },             { key: 'd', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }],            [{ key: 'z', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }, diff --git a/test/content/navigates.test.js b/test/content/navigates.test.js index b5144e9..f1f0741 100644 --- a/test/content/navigates.test.js +++ b/test/content/navigates.test.js @@ -1,56 +1,138 @@ -import { expect } from "chai"; +import { expect } from 'chai';  import * as navigates from 'content/navigates'; +const testRel = (done, rel, html) => { +  const method = rel === 'prev' ? 'linkPrev' : 'linkNext'; +  document.body.innerHTML = html; +  navigates[method](window); +  setTimeout(() => { +    expect(document.location.hash).to.equal(`#${rel}`); +    done(); +  }, 0); +}; + +const testPrev = html => done => testRel(done, 'prev', html); +const testNext = html => done => testRel(done, 'next', html); +  describe('navigates module', () => {    describe('#linkPrev', () => { -    it('clicks prev link by text content', (done) => { -      document.body.innerHTML = '<a href="#dummy">xprevx</a>  <a href="#prev">go to prev</a>'; -      navigates.linkPrev(window); -      setTimeout(() => { -        expect(document.location.hash).to.equal('#prev'); -        done(); -      }, 0); -    }); +    it('navigates to <link> elements whose rel attribute is "prev"', testPrev( +      '<link rel="prev" href="#prev" />' +    )); -    it('clicks a[rel=prev] element preferentially', (done) => { -      document.body.innerHTML = '<a href="#dummy">prev</a>  <a rel="prev" href="#prev">rel</a>'; -      navigates.linkPrev(window); -      setTimeout(() => { -        expect(document.location.hash).to.equal('#prev'); -        done(); -      }, 0); -    }); -  }); +    it('navigates to <link> elements whose rel attribute starts with "prev"', testPrev( +      '<link rel="prev bar" href="#prev" />' +    )); + +    it('navigates to <link> elements whose rel attribute ends with "prev"', testPrev( +      '<link rel="foo prev" href="#prev" />' +    )); + +    it('navigates to <link> elements whose rel attribute contains "prev"', testPrev( +      '<link rel="foo prev bar" href="#prev" />' +    )); + +    it('navigates to <a> elements whose rel attribute is "prev"', testPrev( +      '<a rel="prev" href="#prev">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute starts with "prev"', testPrev( +      '<a rel="prev bar" href="#prev">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute ends with "prev"', testPrev( +      '<a rel="foo prev" href="#prev">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute contains "prev"', testPrev( +      '<a rel="foo prev bar" href="#prev">click me</a>' +    )); + +    it('navigates to <a> elements whose text matches "prev"', testPrev( +      '<a href="#dummy">preview</a><a href="#prev">go to prev</a>' +    )); + +    it('navigates to <a> elements whose text matches "previous"', testPrev( +      '<a href="#dummy">previously</a><a href="#prev">previous page</a>' +    )); + +    it('navigates to <a> elements whose decoded text matches "<<"', testPrev( +      '<a href="#dummy">click me</a><a href="#prev"><<</a>' +    )); + +    it('navigates to matching <a> elements by clicking', testPrev( +      `<a rel="prev" href="#dummy" onclick="return location = '#prev', false">go to prev</a>` +    )); + +    it('prefers link[rel~=prev] to a[rel~=prev]', testPrev( +      '<a rel="prev" href="#dummy">click me</a><link rel="prev" href="#prev" />' +    )); +    it('prefers a[rel~=prev] to a::text(pattern)', testPrev( +      '<a href="#dummy">go to prev</a><a rel="prev" href="#prev">click me</a>' +    )); +  });    describe('#linkNext', () => { -    it('clicks next link by text content', (done) => { -      document.body.innerHTML = '<a href="#dummy">xnextx</a>  <a href="#next">go to next</a>'; -      navigates.linkNext(window); -      setTimeout(() => { -        expect(document.location.hash).to.equal('#next'); -        done(); -      }, 0); -    }); +    it('navigates to <link> elements whose rel attribute is "next"', testNext( +      '<link rel="next" href="#next" />' +    )); -    it('clicks a[rel=next] element preferentially', (done) => { -      document.body.innerHTML = '<a href="#dummy">next</a>  <a rel="next" href="#next">rel</a>'; -      navigates.linkNext(window); -      setTimeout(() => { -        expect(document.location.hash).to.equal('#next'); -        done(); -      }, 0); -    }); +    it('navigates to <link> elements whose rel attribute starts with "next"', testNext( +      '<link rel="next bar" href="#next" />' +    )); + +    it('navigates to <link> elements whose rel attribute ends with "next"', testNext( +      '<link rel="foo next" href="#next" />' +    )); + +    it('navigates to <link> elements whose rel attribute contains "next"', testNext( +      '<link rel="foo next bar" href="#next" />' +    )); + +    it('navigates to <a> elements whose rel attribute is "next"', testNext( +      '<a rel="next" href="#next">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute starts with "next"', testNext( +      '<a rel="next bar" href="#next">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute ends with "next"', testNext( +      '<a rel="foo next" href="#next">click me</a>' +    )); + +    it('navigates to <a> elements whose rel attribute contains "next"', testNext( +      '<a rel="foo next bar" href="#next">click me</a>' +    )); + +    it('navigates to <a> elements whose text matches "next"', testNext( +      '<a href="#dummy">inextricable</a><a href="#next">go to next</a>' +    )); + +    it('navigates to <a> elements whose decoded text matches ">>"', testNext( +      '<a href="#dummy">click me</a><a href="#next">>></a>' +    )); + +    it('navigates to matching <a> elements by clicking', testNext( +      `<a rel="next" href="#dummy" onclick="return location = '#next', false">go to next</a>` +    )); + +    it('prefers link[rel~=next] to a[rel~=next]', testNext( +      '<a rel="next" href="#dummy">click me</a><link rel="next" href="#next" />' +    )); + +    it('prefers a[rel~=next] to a::text(pattern)', testNext( +      '<a href="#dummy">next page</a><a rel="next" href="#next">click me</a>' +    ));    });    describe('#parent', () => {      // NOTE: not able to test location      it('removes hash', () => { -      window.location.hash = "#section-1"; +      window.location.hash = '#section-1';        navigates.parent(window);        expect(document.location.hash).to.be.empty;      });    });  }); - - diff --git a/test/content/reducers/find.test.js b/test/content/reducers/find.test.js index 93625da..908b01b 100644 --- a/test/content/reducers/find.test.js +++ b/test/content/reducers/find.test.js @@ -5,7 +5,7 @@ import findReducer from 'content/reducers/find';  describe("find reducer", () => {    it('return the initial state', () => {      let state = findReducer(undefined, {}); -    expect(state).to.have.property('keyword', ''); +    expect(state).to.have.property('keyword', null);      expect(state).to.have.property('found', false);    }); diff --git a/test/settings/components/form/blacklist-form.test.jsx b/test/settings/components/form/blacklist-form.test.jsx new file mode 100644 index 0000000..95f5cde --- /dev/null +++ b/test/settings/components/form/blacklist-form.test.jsx @@ -0,0 +1,82 @@ +import { expect } from 'chai'; +import { h, render } from 'preact'; +import BlacklistForm from 'settings/components/form/blacklist-form' + +describe("settings/form/BlacklistForm", () => { +  beforeEach(() => { +    document.body.innerHTML = ''; +  }); + +  describe('render', () => { +    it('renders BlacklistForm', () => { +      render(<BlacklistForm value={['*.slack.com', 'www.google.com/maps']} />, document.body); + +      let inputs = document.querySelectorAll('input[type=text]'); +      expect(inputs).to.have.lengthOf(2); +      expect(inputs[0].value).to.equal('*.slack.com'); +      expect(inputs[1].value).to.equal('www.google.com/maps'); +    }); + +    it('renders blank value', () => { +      render(<BlacklistForm />, document.body); + +      let inputs = document.querySelectorAll('input[type=text]'); +      expect(inputs).to.be.empty; +    }); + +    it('renders blank value', () => { +      render(<BlacklistForm />, document.body); + +      let inputs = document.querySelectorAll('input[type=text]'); +      expect(inputs).to.be.empty; +    }); +  }); + +  describe('onChange', () => { +    it('invokes onChange event on edit', (done) => { +      render(<BlacklistForm +        value={['*.slack.com', 'www.google.com/maps*']} +        onChange={value => { +          expect(value).to.have.lengthOf(2) +            .and.have.members(['gitter.im', 'www.google.com/maps*']); + +          done(); +        }} +      />, document.body); + +      let input = document.querySelectorAll('input[type=text]')[0]; +      input.value = 'gitter.im'; +      input.dispatchEvent(new Event('change')) +    }); + +    it('invokes onChange event on delete', (done) => { +      render(<BlacklistForm +        value={['*.slack.com', 'www.google.com/maps*']} +        onChange={value => { +          expect(value).to.have.lengthOf(1) +            .and.have.members(['www.google.com/maps*']); + +          done(); +        }} +      />, document.body); + +      let button = document.querySelectorAll('input[type=button]')[0]; +      button.click(); +    }); + +    it('invokes onChange event on add', (done) => { +      render(<BlacklistForm +        value={['*.slack.com']} +        onChange={value => { +          expect(value).to.have.lengthOf(2) +            .and.have.members(['*.slack.com', '']); + +          done(); +        }} +      />, document.body); + +      let button = document.querySelector('input[type=button].ui-add-button'); +      button.click(); +    }); +  }); +}); diff --git a/test/settings/components/form/keymaps-form.test.jsx b/test/settings/components/form/keymaps-form.test.jsx new file mode 100644 index 0000000..e9f9359 --- /dev/null +++ b/test/settings/components/form/keymaps-form.test.jsx @@ -0,0 +1,53 @@ +import { expect } from 'chai'; +import { h, render } from 'preact'; +import KeymapsForm from 'settings/components/form/keymaps-form' + +describe("settings/form/KeymapsForm", () => { +  beforeEach(() => { +    document.body.innerHTML = ''; +  }); + +  describe('render', () => { +    it('renders KeymapsForm', () => { +      render(<KeymapsForm value={{ +        'scroll.vertically?{"count":1}': 'j', +        'scroll.vertically?{"count":-1}': 'k', +      }} />, document.body); + +      let inputj = document.getElementById('scroll.vertically?{"count":1}'); +      let inputk = document.getElementById('scroll.vertically?{"count":-1}'); + +      expect(inputj.value).to.equal('j'); +      expect(inputk.value).to.equal('k'); +    }); + +    it('renders blank value', () => { +      render(<KeymapsForm />, document.body); + +      let inputj = document.getElementById('scroll.vertically?{"count":1}'); +      let inputk = document.getElementById('scroll.vertically?{"count":-1}'); + +      expect(inputj.value).to.be.empty; +      expect(inputk.value).to.be.empty; +    }); +  }); + +  describe('onChange event', () => { +    it('invokes onChange event on edit', (done) => { +      render(<KeymapsForm +        value={{ +          'scroll.vertically?{"count":1}': 'j', +          'scroll.vertically?{"count":-1}': 'k', +        }} +        onChange={value => { +          expect(value['scroll.vertically?{"count":1}']).to.equal('jjj'); + +          done(); +        }} />, document.body); + +      let input = document.getElementById('scroll.vertically?{"count":1}'); +      input.value = 'jjj'; +      input.dispatchEvent(new Event('change')) +    }); +  }); +}); diff --git a/test/settings/components/form/properties-form.test.jsx b/test/settings/components/form/properties-form.test.jsx new file mode 100644 index 0000000..4807361 --- /dev/null +++ b/test/settings/components/form/properties-form.test.jsx @@ -0,0 +1,86 @@ +import { expect } from 'chai'; +import { h, render } from 'preact'; +import PropertiesForm from 'settings/components/form/properties-form' + +describe("settings/form/PropertiesForm", () => { +  beforeEach(() => { +    document.body.innerHTML = ''; +  }); + +  describe('render', () => { +    it('renders PropertiesForm', () => { +      let types = { +        mystr: 'string', +        mynum: 'number', +        mybool: 'boolean', +        empty: 'string', +      } +      let value = { +        mystr: 'abc', +        mynum: 123, +        mybool: true, +      }; +      render(<PropertiesForm types={types} value={value} />, document.body); + +      let strInput = document.querySelector('input[name=mystr]'); +      let numInput = document.querySelector('input[name=mynum]'); +      let boolInput = document.querySelector('input[name=mybool]'); +      let emptyInput = document.querySelector('input[name=empty]'); + +      expect(strInput.type).to.equals('text'); +      expect(strInput.value).to.equal('abc'); +      expect(numInput.type).to.equals('number'); +      expect(numInput.value).to.equal('123'); +      expect(boolInput.type).to.equals('checkbox'); +      expect(boolInput.checked).to.be.true; +      expect(emptyInput.type).to.equals('text'); +      expect(emptyInput.value).to.be.empty; +    }); +  }); + +  describe('onChange', () => { +    it('invokes onChange event on text changed', (done) => { +      render(<PropertiesForm +        types={{ 'myvalue': 'string' }} +        value={{ 'myvalue': 'abc' }} +        onChange={value => { +          expect(value).to.have.property('myvalue', 'abcd'); +          done(); +        }} +      />, document.body); + +      let input = document.querySelector('input[name=myvalue]'); +      input.value = 'abcd' +      input.dispatchEvent(new Event('change')) +    }); + +    it('invokes onChange event on number changeed', (done) => { +      render(<PropertiesForm +        types={{ 'myvalue': 'number' }} +        value={{ '': 123 }} +        onChange={value => { +          expect(value).to.have.property('myvalue', 1234); +          done(); +        }} +      />, document.body); + +      let input = document.querySelector('input[name=myvalue]'); +      input.value = '1234' +      input.dispatchEvent(new Event('change')) +    }); + +    it('invokes onChange event on checkbox changed', (done) => { +      render(<PropertiesForm +        types={{ 'myvalue': 'boolean' }} +        value={{ 'myvalue': false }} +        onChange={value => { +          expect(value).to.have.property('myvalue', true); +          done(); +        }} +      />, document.body); + +      let input = document.querySelector('input[name=myvalue]'); +      input.click(); +    }); +  }); +}); diff --git a/test/settings/components/form/search-engine-form.test.jsx b/test/settings/components/form/search-engine-form.test.jsx new file mode 100644 index 0000000..9600cae --- /dev/null +++ b/test/settings/components/form/search-engine-form.test.jsx @@ -0,0 +1,104 @@ +import { expect } from 'chai'; +import { h, render } from 'preact'; +import SearchForm from 'settings/components/form/search-form' + +describe("settings/form/SearchForm", () => { +  beforeEach(() => { +    document.body.innerHTML = ''; +  }); + +  describe('render', () => { +    it('renders SearchForm', () => { +      render(<SearchForm value={{ +        default: 'google', +        engines: [['google', 'google.com'], ['yahoo', 'yahoo.com']], +      }} />, document.body); + +      let names = document.querySelectorAll('input[name=name]'); +      expect(names).to.have.lengthOf(2); +      expect(names[0].value).to.equal('google'); +      expect(names[1].value).to.equal('yahoo'); + +      let urls = document.querySelectorAll('input[name=url]'); +      expect(urls).to.have.lengthOf(2); +      expect(urls[0].value).to.equal('google.com'); +      expect(urls[1].value).to.equal('yahoo.com'); +    }); + +    it('renders blank value', () => { +      render(<SearchForm />, document.body); + +      let names = document.querySelectorAll('input[name=name]'); +      let urls = document.querySelectorAll('input[name=url]'); +      expect(names).to.have.lengthOf(0); +      expect(urls).to.have.lengthOf(0); +    }); + +    it('renders blank engines', () => { +      render(<SearchForm value={{ default: 'google' }} />, document.body); + +      let names = document.querySelectorAll('input[name=name]'); +      let urls = document.querySelectorAll('input[name=url]'); +      expect(names).to.have.lengthOf(0); +      expect(urls).to.have.lengthOf(0); +    }); +  }); + +  describe('onChange event', () => { +    it('invokes onChange event on edit', (done) => { +      render(<SearchForm +        value={{ +          default: 'google', +          engines: [['google', 'google.com'], ['yahoo', 'yahoo.com']] +        }} +        onChange={value => { +          expect(value.default).to.equal('louvre'); +          expect(value.engines).to.have.lengthOf(2) +            .and.have.deep.members([['louvre', 'google.com'], ['yahoo', 'yahoo.com']]) + +          done(); +        }} />, document.body); + +      let radio = document.querySelectorAll('input[type=radio]'); +      radio.checked = true; + +      let name = document.querySelector('input[name=name]'); +      name.value = 'louvre'; +      name.dispatchEvent(new Event('change')) +    }); + +    it('invokes onChange event on delete', (done) => { +      render(<SearchForm value={{ +          default: 'yahoo', +          engines: [['louvre', 'google.com'], ['yahoo', 'yahoo.com']] +        }} +        onChange={value => { +          expect(value.default).to.equal('yahoo'); +          expect(value.engines).to.have.lengthOf(1) +            .and.have.deep.members([['yahoo', 'yahoo.com']]) + +          done(); +        }} />, document.body); + +      let button = document.querySelector('input[type=button]'); +      button.click(); +    }); + +    it('invokes onChange event on add', (done) => { +      render(<SearchForm value={{ +          default: 'yahoo', +          engines: [['google', 'google.com']] +        }} +        onChange={value => { +          expect(value.default).to.equal('yahoo'); +          expect(value.engines).to.have.lengthOf(2) +            .and.have.deep.members([['google', 'google.com'], ['', '']]) + +          done(); +        }} />, document.body); + +      let button = document.querySelector('input[type=button].ui-add-button'); +      button.click(); +    }); +  }); +}); diff --git a/test/settings/components/ui/input.test.jsx b/test/settings/components/ui/input.test.jsx new file mode 100644 index 0000000..98f2cef --- /dev/null +++ b/test/settings/components/ui/input.test.jsx @@ -0,0 +1,83 @@ +import { expect } from 'chai'; +import { h, render } from 'preact'; +import Input from 'settings/components/ui/input' + +describe("settings/ui/Input", () => { +  beforeEach(() => { +    document.body.innerHTML = ''; +  }); + +  context("type=text", () => { +    it('renders text input', () => { +      render(<Input type='text' name='myname' label='myfield' value='myvalue'/>, document.body) + +      let label = document.querySelector('label'); +      let input = document.querySelector('input'); +      expect(label.textContent).to.contain('myfield'); +      expect(input.type).to.contain('text'); +      expect(input.name).to.contain('myname'); +      expect(input.value).to.contain('myvalue'); +    }); + +    it('invoke onChange', (done) => { +      render(<Input type='text' name='myname' label='myfield' value='myvalue' onChange={(e) => { +        expect(e.target.value).to.equal('newvalue'); +        done(); +      }}/>, document.body); + +      let input = document.querySelector('input'); +      input.value = 'newvalue'; +      input.dispatchEvent(new Event('change')) +    }); +  }); + +  context("type=radio", () => { +    it('renders radio button', () => { +      render(<Input type='radio' name='myname' label='myfield' value='myvalue'/>, document.body) + +      let label = document.querySelector('label'); +      let input = document.querySelector('input'); +      expect(label.textContent).to.contain('myfield'); +      expect(input.type).to.contain('radio'); +      expect(input.name).to.contain('myname'); +      expect(input.value).to.contain('myvalue'); +    }); + +    it('invoke onChange', (done) => { +      render(<Input type='text' name='radio' label='myfield' value='myvalue' onChange={(e) => { +        expect(e.target.checked).to.be.true; +        done(); +      }}/>, document.body); + +      let input = document.querySelector('input'); +      input.checked = true; +      input.dispatchEvent(new Event('change')) +    }); +  }); + +  context("type=textarea", () => { +    it('renders textarea button', () => { +      render(<Input type='textarea' name='myname' label='myfield' value='myvalue' error='myerror' />, document.body) + +      let label = document.querySelector('label'); +      let textarea = document.querySelector('textarea'); +      let error = document.querySelector('.settings-ui-input-error'); +      expect(label.textContent).to.contain('myfield'); +      expect(textarea.nodeName).to.contain('TEXTAREA'); +      expect(textarea.name).to.contain('myname'); +      expect(textarea.value).to.contain('myvalue'); +      expect(error.textContent).to.contain('myerror'); +    }); + +    it('invoke onChange', (done) => { +      render(<Input type='textarea' name='myname' label='myfield' value='myvalue' onChange={(e) => { +        expect(e.target.value).to.equal('newvalue'); +        done(); +      }}/>, document.body); + +      let input = document.querySelector('textarea'); +      input.value = 'newvalue' +      input.dispatchEvent(new Event('change')) +    }); +  }); +}); diff --git a/test/shared/commands/parsers.test.js b/test/shared/commands/parsers.test.js new file mode 100644 index 0000000..0a1960c --- /dev/null +++ b/test/shared/commands/parsers.test.js @@ -0,0 +1,85 @@ +import { expect } from "chai"; +import * as parsers from 'shared/commands/parsers'; + +describe("shared/commands/parsers", () => { +  describe("#parsers.parseSetOption", () => { +    it('parse set string', () => { +      let [key, value] = parsers.parseSetOption('encoding=utf-8', { encoding: 'string' }); +      expect(key).to.equal('encoding'); +      expect(value).to.equal('utf-8'); +    }); + +    it('parse set empty string', () => { +      let [key, value] = parsers.parseSetOption('encoding=', { encoding: 'string' }); +      expect(key).to.equal('encoding'); +      expect(value).to.equal(''); +    }); + +    it('parse set string', () => { +      let [key, value] = parsers.parseSetOption('history=50', { history: 'number' }); +      expect(key).to.equal('history'); +      expect(value).to.equal(50); +    }); + +    it('parse set boolean', () => { +      let [key, value] = parsers.parseSetOption('paste', { paste: 'boolean' }); +      expect(key).to.equal('paste'); +      expect(value).to.be.true; + +      [key, value] = parsers.parseSetOption('nopaste', { paste: 'boolean' }); +      expect(key).to.equal('paste'); +      expect(value).to.be.false; +    }); + +    it('throws error on unknown property', () => { +      expect(() => parsers.parseSetOption('charset=utf-8', {})).to.throw(Error, 'Unknown'); +      expect(() => parsers.parseSetOption('smoothscroll', {})).to.throw(Error, 'Unknown'); +      expect(() => parsers.parseSetOption('nosmoothscroll', {})).to.throw(Error, 'Unknown'); +    }) + +    it('throws error on invalid property', () => { +      expect(() => parsers.parseSetOption('charset=utf-8', { charset: 'number' })).to.throw(Error, 'Not number'); +      expect(() => parsers.parseSetOption('charset=utf-8', { charset: 'boolean' })).to.throw(Error, 'Invalid'); +      expect(() => parsers.parseSetOption('charset=', { charset: 'boolean' })).to.throw(Error, 'Invalid'); +      expect(() => parsers.parseSetOption('smoothscroll', { smoothscroll: 'string' })).to.throw(Error, 'Invalid'); +      expect(() => parsers.parseSetOption('smoothscroll', { smoothscroll: 'number' })).to.throw(Error, 'Invalid'); +    }) +  }); + +  describe('#normalizeUrl', () => { +    const config = { +      default: 'google', +      engines: { +        google: 'https://google.com/search?q={}', +        yahoo: 'https://yahoo.com/search?q={}', +      } +    }; + +    it('convertes search url', () => { +      expect(parsers.normalizeUrl(['google', 'apple'], config)) +        .to.equal('https://google.com/search?q=apple'); +      expect(parsers.normalizeUrl(['yahoo', 'apple'], config)) +        .to.equal('https://yahoo.com/search?q=apple'); +      expect(parsers.normalizeUrl(['google', 'apple', 'banana'], config)) +        .to.equal('https://google.com/search?q=apple%20banana'); +      expect(parsers.normalizeUrl(['yahoo', 'C++CLI'], config)) +        .to.equal('https://yahoo.com/search?q=C%2B%2BCLI'); +    }); + +    it('user default  search engine', () => { +      expect(parsers.normalizeUrl(['apple', 'banana'], config)) +        .to.equal('https://google.com/search?q=apple%20banana'); +    }); +  }); + +  describe('#parseCommandLine', () => { +    it('parse command line as name and args', () => { +      expect(parsers.parseCommandLine('open google apple')).to.deep.equal(['open', ['google', 'apple']]); +      expect(parsers.parseCommandLine('  open  google  apple  ')).to.deep.equal(['open', ['google', 'apple']]); +      expect(parsers.parseCommandLine('')).to.deep.equal(['', []]); +      expect(parsers.parseCommandLine('  ')).to.deep.equal(['', []]); +      expect(parsers.parseCommandLine('exit')).to.deep.equal(['exit', []]); +      expect(parsers.parseCommandLine('  exit  ')).to.deep.equal(['exit', []]); +    }); +  }); +}); diff --git a/test/shared/validators/setting.test.js b/test/shared/settings/validator.test.js index 15d6a10..61d976a 100644 --- a/test/shared/validators/setting.test.js +++ b/test/shared/settings/validator.test.js @@ -1,5 +1,5 @@  import { expect } from "chai"; -import { validate } from 'shared/validators/setting'; +import { validate } from 'shared/settings/validator';  describe("setting validator", () => {    describe("unknown top keys", () => { diff --git a/test/shared/settings/values.test.js b/test/shared/settings/values.test.js new file mode 100644 index 0000000..62cfb5f --- /dev/null +++ b/test/shared/settings/values.test.js @@ -0,0 +1,139 @@ +import { expect } from 'chai'; +import * as values from 'shared/settings/values'; + +describe("settings values", () => { +  describe('valueFromJson', () => { +    it('return object from json string', () => { +      let json = `{ +        "keymaps": { "0": {"type": "scroll.home"}}, +        "search": { "default": "google", "engines": { "google": "https://google.com/search?q={}" }}, +        "blacklist": [ "*.slack.com"], +        "properties": { +          "mystr": "value", +          "mynum": 123, +          "mybool": true +        } +      }`; +      let value = values.valueFromJson(json); + +      expect(value.keymaps).to.deep.equal({ 0: {type: "scroll.home"}}); +      expect(value.search).to.deep.equal({ default: "google", engines: { google: "https://google.com/search?q={}"} }); +      expect(value.blacklist).to.deep.equal(["*.slack.com"]); +      expect(value.properties).to.have.property('mystr', 'value'); +      expect(value.properties).to.have.property('mynum', 123); +      expect(value.properties).to.have.property('mybool', true); +    }); +  }); + +  describe('valueFromForm', () => { +    it('returns value from form', () => { +      let form = { +        keymaps: { +          'scroll.vertically?{"count":1}': 'j', +          'scroll.home': '0', +        }, +        search: { +          default: 'google', +          engines: [['google', 'https://google.com/search?q={}']], +        }, +        blacklist: ['*.slack.com'], +        "properties": { +          "mystr": "value", +          "mynum": 123, +          "mybool": true, +        } +      }; +      let value = values.valueFromForm(form); + +      expect(value.keymaps).to.have.deep.property('j', { type: "scroll.vertically", count: 1 }); +      expect(value.keymaps).to.have.deep.property('0', { type: "scroll.home" }); +      expect(JSON.stringify(value.search)).to.deep.equal(JSON.stringify({ default: "google", engines: { google: "https://google.com/search?q={}"} })); +      expect(value.search).to.deep.equal({ default: "google", engines: { google: "https://google.com/search?q={}"} }); +      expect(value.blacklist).to.deep.equal(["*.slack.com"]); +      expect(value.properties).to.have.property('mystr', 'value'); +      expect(value.properties).to.have.property('mynum', 123); +      expect(value.properties).to.have.property('mybool', true); +    }); + +    it('convert from empty form', () => { +      let form = {}; +      let value = values.valueFromForm(form); +      expect(value).to.not.have.key('keymaps'); +      expect(value).to.not.have.key('search'); +      expect(value).to.not.have.key('blacklist'); +      expect(value).to.not.have.key('properties'); +    }); + +    it('override keymaps', () => { +      let form = { +        keymaps: { +          'scroll.vertically?{"count":1}': 'j', +          'scroll.vertically?{"count":-1}': 'j', +        } +      }; +      let value = values.valueFromForm(form); + +      expect(value.keymaps).to.have.key('j'); +    }); + +    it('override search engine', () => { +      let form = { +        search: { +          default: 'google', +          engines: [ +            ['google', 'https://google.com/search?q={}'], +            ['google', 'https://google.co.jp/search?q={}'], +          ] +        } +      }; +      let value = values.valueFromForm(form); + +      expect(value.search.engines).to.have.property('google', 'https://google.co.jp/search?q={}'); +    }); +  }); + +  describe('jsonFromValue', () => { +  }); + +  describe('formFromValue', () => { +    it('convert empty value to form', () => { +      let value = {}; +      let form = values.formFromValue(value); + +      expect(value).to.not.have.key('keymaps'); +      expect(value).to.not.have.key('search'); +      expect(value).to.not.have.key('blacklist'); +    }); + +    it('convert value to form', () => { +      let value = { +        keymaps: { +          j: { type: 'scroll.vertically', count: 1 }, +          JJ: { type: 'scroll.vertically', count: 100 }, +          0: { type: 'scroll.home' }, +        }, +        search: { default: 'google', engines: { google: 'https://google.com/search?q={}' }}, +        blacklist: [ '*.slack.com'], +        properties: { +          "mystr": "value", +          "mynum": 123, +          "mybool": true, +        } +      }; +      let allowed = ['scroll.vertically?{"count":1}', 'scroll.home' ]; +      let form = values.formFromValue(value, allowed); + +      expect(form.keymaps).to.have.property('scroll.vertically?{"count":1}', 'j'); +      expect(form.keymaps).to.not.have.property('scroll.vertically?{"count":100}'); +      expect(form.keymaps).to.have.property('scroll.home', '0'); +      expect(Object.keys(form.keymaps)).to.have.lengthOf(2); +      expect(form.search).to.have.property('default', 'google'); +      expect(form.search).to.have.deep.property('engines', [['google', 'https://google.com/search?q={}']]); +      expect(form.blacklist).to.have.lengthOf(1); +      expect(form.blacklist).to.include('*.slack.com'); +      expect(form.properties).to.have.property('mystr', 'value'); +      expect(form.properties).to.have.property('mynum', 123); +      expect(form.properties).to.have.property('mybool', true); +    }); +  }); +}); | 
