UNPKG

manuel

Version:

A super customizable VDOM autocomplete with *production ready* defaults.

226 lines (188 loc) 3.9 kB
/* eslint-disable fp/no-mutating-methods */ const test = require('tape') const manuel = require('../') const m = require('mithril') const mithrilQuery = require('mithril-query') const UNUSED_KEY_CODE = 1 const KEY_UP = 38 const KEY_DOWN = 40 const { compose , append , prepend , split , join } = require('ramda') const render = require('mithril-node-render') const renderStdout = compose( console.log , join('\n') , prepend('--HTML-BEGIN--') , append('--HTML-END--') , split('\n') , render ) function query(app){ const context = mithrilQuery(app) const { first: $ , find: $$ } = context return { context, $, $$ } } function Model(){ return { model: { list: [[]] ,input: [''] ,chosen: [null] ,open: [false] ,highlighted: [null] } ,modelKeys: { list: 'list' ,input: 'input' ,chosen: 'chosen' ,open: 'open' ,highlighted: 'highlighted' } } } function mithrilAutocomplete({model, modelKeys}){ return { autocomplete: manuel({ hyperscript: m ,get: k => model[k][0] ,set: (k,v) => model[k].unshift(v) }) ,model ,modelKeys } } test('Mithril v0.2.x', function(t){ const { model, modelKeys, autocomplete } = mithrilAutocomplete( Model() ) const App = { controller: function Controller(){ return function view(){ return autocomplete(modelKeys) } } ,view: f => f() } const { $, $$, context } = query(App) t.equals( render( m('.manuel-complete' ,m('input', { value: "" }) ,m('ul') ) ) , render(context.rootEl) , 'Basic structure renders' ) model.input.unshift('Che'); context.redraw() t.equals( render( m('.manuel-complete.not-empty' ,m('input', { value: model.input[0]}) ,m('ul') ) ) , render(context.rootEl) , 'Autocomplete updates to reflect model, not-empty classes added' ) $('input').attrs.oninput({ currentTarget: { value: 'Cher' } }) context.redraw() t.equals( model.input[0] , 'Cher' , 'Input event updated model' ) t.equals( context.rootEl.attrs.className ,'manuel-complete not-empty' ,`Typing with an empty list did not show the drawer but did add not-empty class to input ` ) t.equals( model.open[0] , true ,'Typing set open to true, even though the list is empty' ) model.list.unshift([ 'Cher' ,'Cherry' ,'Cherries' ,'Chereth Cutestory' ]) context.redraw() t.equals( render( m('.manuel-complete.open.not-empty.loaded' ,m('input', { value: model.input[0]}) ,m('ul', model.list[0].map( x => m( 'li', { class: ""}, [ m('mark', 'Cher') , x.slice(4) ] ) ) ) ) ) , render(context.rootEl) , `After adding items to the list: open and loaded are both added to the root classnames and matching text is highlighted ` ) context.redraw() const prevented = [] context.rootEl.attrs.onkeydown({ keyCode: UNUSED_KEY_CODE ,preventDefault(){ prevented.unshift(UNUSED_KEY_CODE) } }) t.equals( prevented.length , 0 , 'Pressing an unsed key does not e.preventDefault(' ) context.rootEl.attrs.onkeydown({ keyCode: KEY_DOWN ,preventDefault(){ prevented.unshift(KEY_DOWN) } }) t.deepEquals( prevented ,[KEY_DOWN] ,'Pressing a used key (KEY_DOWN) did prevent default' ) t.equals( model.list[0][0] ,model.highlighted[0] ,'First item on a KEY DOWN led to the first item being highlighted' ) context.redraw() t.equals( render($('.highlight')) ,render( m('li.highlight' ,m('mark', model.highlighted[0] ) ) ) ,'Highlight class added to element' ) t.end() }) process.on('unhandledRejection', r => console.error(r));