Skip to content

Commit

Permalink
Add v6 tests (#674)
Browse files Browse the repository at this point in the history
Replaces #528. I was just going off the features listed in the readme. There are a handful more we should test but this is a start.

Note that this includes a readme change for `state.href` that I believe was incorrectly documented. Let me know if I got that wrong.

Also note that we should delete the original `v6-tests` branch once this is merged. Leaving it for now for reference.
  • Loading branch information
timwis authored and goto-bus-stop committed Aug 14, 2018
1 parent 5396036 commit 0e7bd85
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ An object containing the current queryString. `/foo?bin=baz` becomes `{ bin:
'baz' }`.

### `state.href`
An object containing the current href. `/foo?bin=baz` becomes `foo`.
An object containing the current href. `/foo?bin=baz` becomes `/foo`.

### `state.route`
The current name of the route used in the router (e.g. `/foo/:bar`).
Expand Down
183 changes: 183 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,186 @@ tape('should expose a public API', function (t) {

t.end()
})

tape('should enable history and hash by defaut', function (t) {
var app = choo()
t.true(app._historyEnabled, 'history enabled')
t.true(app._hrefEnabled, 'href enabled')
t.end()
})

tape('router should pass state and emit to view', function (t) {
t.plan(2)
var app = choo()
app.route('/', function (state, emit) {
t.equal(typeof state, 'object', 'state is an object')
t.equal(typeof emit, 'function', 'emit is a function')
return html`<div></div>`
})
app.toString('/')
t.end()
})

tape('router should support a default route', function (t) {
t.plan(1)
var app = choo()
app.route('*', function (state, emit) {
t.pass()
return html`<div></div>`
})
app.toString('/random')
t.end()
})

tape('router should treat hashes as slashes by default', function (t) {
t.plan(1)
var app = choo()
app.route('/account/security', function (state, emit) {
t.pass()
return html`<div></div>`
})
app.toString('/account#security')
t.end()
})

tape('router should ignore hashes if hash is disabled', function (t) {
t.plan(1)
var app = choo({ hash: false })
app.route('/account', function (state, emit) {
t.pass()
return html`<div></div>`
})
app.toString('/account#security')
t.end()
})

tape('cache should default to 100 instances', function (t) {
t.plan(1)
var app = choo()
app.route('/', function (state, emit) {
for (var i = 0; i <= 100; i++) state.cache(Component, i)
state.cache(Component, 0)
return html`<div></div>`

function Component (id) {
if (id < i) t.pass('oldest instance was pruned when exceeding 100')
}
})
app.toString('/')
t.end()
})

tape('cache option should override number of max instances', function (t) {
t.plan(1)
var app = choo({ cache: 1 })
app.route('/', function (state, emit) {
var instances = 0
state.cache(Component, instances)
state.cache(Component, instances)
state.cache(Component, 0)
return html`<div></div>`

function Component (id) {
if (id < instances) t.pass('oldest instance was pruned when exceeding 1')
instances++
}
})
app.toString('/')
t.end()
})

tape('cache option should override default LRU cache', function (t) {
t.plan(2)
var cache = {
get (Component, id) {
t.pass('called get')
},
set (Component, id) {
t.pass('called set')
}
}
var app = choo({ cache: cache })
app.route('/', function (state, emit) {
state.cache(Component, 'foo')
return html`<div></div>`
})
app.toString('/')
t.end()

function Component () {}
})

// built-in state

tape('state should include events', function (t) {
t.plan(2)
var app = choo()
app.route('/', function (state, emit) {
t.ok(state.hasOwnProperty('events'), 'state has event property')
t.ok(Object.keys(state.events).length > 0, 'events object has keys')
return html`<div></div>`
})
app.toString('/')
t.end()
})

tape('state should include params', function (t) {
t.plan(4)
var app = choo()
app.route('/:resource/:id/*', function (state, emit) {
t.ok(state.hasOwnProperty('params'), 'state has params property')
t.equal(state.params.resource, 'users', 'resources param is users')
t.equal(state.params.id, '1', 'id param is 1')
t.equal(state.params.wildcard, 'docs/foo.txt', 'wildcard captures what remains')
return html`<div></div>`
})
app.toString('/users/1/docs/foo.txt')
t.end()
})

tape('state should include query', function (t) {
t.plan(2)
var app = choo()
app.route('/', function (state, emit) {
t.ok(state.hasOwnProperty('query'), 'state has query property')
t.equal(state.query.page, '2', 'page querystring is 2')
return html`<div></div>`
})
app.toString('/?page=2')
t.end()
})

tape('state should include href', function (t) {
t.plan(2)
var app = choo()
app.route('/:resource/:id', function (state, emit) {
t.ok(state.hasOwnProperty('href'), 'state has href property')
t.equal(state.href, '/users/1', 'href is users/1')
return html`<div></div>`
})
app.toString('/users/1?page=2') // should ignore query
t.end()
})

// TODO: Implement this using jsdom, as this only works when window is present
tape.skip('state should include title', function (t) {})

tape('state should include cache', function (t) {
t.plan(6)
var app = choo()
app.route('/', function (state, emit) {
t.equal(typeof state.cache, 'function', 'state has cache method')
var cached = state.cache(Component, 'foo', 'arg')
t.equal(cached, state.cache(Component, 'foo'), 'consecutive calls return same instance')
return html`<div></div>`
})
app.toString('/')
t.end()

function Component (id, state, emit, arg) {
t.equal(id, 'foo', 'id was prefixed to constructor args')
t.equal(typeof state, 'object', 'state was prefixed to constructor args')
t.equal(typeof emit, 'function', 'emit was prefixed to constructor args')
t.equal(arg, 'arg', 'constructor args were forwarded')
}
})

0 comments on commit 0e7bd85

Please sign in to comment.