UNPKG

url-state

Version:

Minimalist history API abstraction for building URL driven browser applications

174 lines (162 loc) 4.13 kB
import url from 'url-state' import tap from 'tap-esm' var pre = document.createElement('pre') document.body.appendChild(pre) tap('initial state', t => { t.plan(1) pre.textContent = JSON.stringify(url, null, 2) t.equal(url.pathname, '/') }) tap('handle push', t => { t.plan(4) var n = 0 url.addEventListener('change', onchange) function onchange () { if (n === 0) { t.equal(url.pathname, '/a') url.push({ pathname: '/b', query: { x: 42 }, hash: '#ish', replace: true }) n++ } else { t.equal(url.pathname, '/b') t.equal(url.params.x, '42') t.equal(url.hash, '#ish') url.removeEventListener('change', onchange) } } url.push('/a') }) tap('handle replace', t => { t.plan(2) const state = window.history.state url.addEventListener('change', () => { t.equal(url.pathname, '/b') t.equal(window.history.state, state) }, { once: true }) url.replace('/b') }) tap('handle pop', t => { t.plan(1) url.addEventListener('change', () => { t.equal(url.pathname, '/') }, { once: true }) url.pop() }) tap('handle forward', t => { t.plan(1) url.addEventListener('change', () => { t.equal(url.pathname, '/b') }, { once: true }) url.push() }) tap('handle nested back', t => { t.plan(3) var n = 0 url.addEventListener('change', onchange) function onchange () { if (n === 0) { t.equal(url.pathname, '/c') url.pop() url.pop() n++ } else if (n === 1) { t.equal(url.pathname, '/b') n++ } else { t.equal(url.pathname, '/') url.removeEventListener('change', onchange) } } url.push('/c') }) tap('query', t => { t.plan(21) var n = 0 url.addEventListener('change', onchange) function onchange () { if (n === 0) { t.equal(1, Object.keys(url.params).length) t.equal('bar', url.params.foo) t.equal('?foo=bar', url.search) url.query({ beep: 'boop' }) n++ } else if (n === 1) { t.equal(Object.keys(url.params).length, 2) t.equal(url.params.foo, 'bar') t.equal(url.params.beep, 'boop') t.equal(url.search, '?foo=bar&beep=boop') url.query({ foo: null, beep: '42' }) n++ } else if (n === 2) { t.equal(Object.keys(url.params).length, 1) t.equal(url.params.beep, '42') t.equal(url.search, '?beep=42') url.query({ beep: [ 42, 43, 44 ] }) n++ } else if (n === 3) { t.equal(Object.keys(url.params).length, 1) t.equal(url.params.beep[0], '42') t.equal(url.params.beep[1], '43') t.equal(url.params.beep[2], '44') t.equal(url.search, '?beep=42&beep=43&beep=44') url.query({ beep: '' }) n++ } else if (n === 4) { t.equal(Object.keys(url.params).length, 1) t.equal(url.params.beep, '') t.equal(url.search, '?beep') url.query({ beep: null }) n++ } else { t.equal(Object.keys(url.params).length, 0) t.equal(url.search, '') t.notEqual(window.location.href.slice(-1)[0], '?') url.removeEventListener('change', onchange) } } url.query({ foo: 'bar' }) }) tap('handle url hash', t => { t.plan(3) var n = 0 url.addEventListener('change', onchange) function onchange () { if (n === 0) { t.equal(url.hash, '#ish') url.push('#') n++ } else { t.equal(url.hash, '') t.notEqual(window.location.href.slice(-1)[0], '#') url.removeEventListener('change', onchange) } } url.push('#ish') }) tap('virtual', t => { t.plan(2) const start = window.history.state url.addEventListener('change', evt => { const end = window.history.state t.equal(start, end) url.addEventListener('change', () => t.pass(), { once: true }) url.pop() url.virtual = false }, { once: true }) url.virtual = true url.push('/x') }) tap('virtual forbidden methods', t => { t.plan(2) url.virtual = true try { url.pop() } catch (err) { t.ok(err.message.indexOf('virtual') > -1) } try { url.push() } catch (err) { t.ok(err.message.indexOf('virtual') > -1) } url.virtual = false })