UNPKG

neft

Version:

Universal Platform

433 lines (351 loc) 12.9 kB
'use strict' {assert, Dict, List, unit} = Neft {describe, it} = unit {createView, renderParse} = require './utils' describe 'src/document string interpolation', -> describe '`props`', -> it 'lookup component', -> source = createView ''' <component name="a" x="2">${props.x}</component> <use component="a" /> ''' view = source.clone() renderParse view assert.is view.node.stringify(), '2' it 'is accessible by scope', -> source = createView ''' <component name="a" x="2"> ${this.props.x} </component> <use component="a" /> ''' view = source.clone() renderParse view assert.is view.node.stringify(), '2' it 'lookup use', -> source = createView ''' <component name="a" x="1">${props.x}</component> <use component="a" x="2" /> ''' view = source.clone() renderParse view assert.is view.node.stringify(), '2' it 'always keeps proper sources order', -> source = createView ''' <component name="a" x="1"> <component name="b" x="1"> ${props.x} </component> <use component="b" x="4" /> </component> <use component="a" x="3" /> ''' view = source.clone() renderParse view useA = view.node.children[0] componentA = useA.children[0] useB = componentA.children[0] componentB = useB.children[0] assert.is view.node.stringify(), '4' componentA.props.set 'x', -1 useA.props.set 'x', -1 componentB.props.set 'x', -1 assert.is view.node.stringify(), '4' componentA.props.set 'x', 1 useA.props.set 'x', 3 componentB.props.set 'x', 1 useB.props.set 'x', undefined assert.is view.node.stringify(), '1' useA.props.set 'x', undefined assert.is view.node.stringify(), '1' componentB.props.set 'x', 2 assert.is view.node.stringify(), '2' componentA.props.set 'x', 3 assert.is view.node.stringify(), '2' componentA.props.set 'x', undefined assert.is view.node.stringify(), '2' describe '`refs`', -> it 'refers to nodes', -> source = createView ''' <a ref="first" label="12" visible="false" /> ${refs.first.props.label} ''' view = source.clone() renderParse view assert.is view.node.stringify(), '12' view.node.children[0].props.set 'label', 23 assert.is view.node.stringify(), '23' it 'are accessible by scope', -> source = createView ''' <a ref="first" label="12" visible="false" /> ${this.refs.first.props.label} ''' view = source.clone() renderParse view assert.is view.node.stringify(), '12' view.node.children[0].props.set 'label', 23 assert.is view.node.stringify(), '23' it 'refers to used components', -> source = createView ''' <component name="a"> <script> this.onRender(function () { this.state.set('name', 'a'); }); this.update = function () { this.state.set('name', 'b'); }; </script> </component> <a ref="first" /> ${refs.first.state.name} ''' view = source.clone() renderParse view assert.is view.node.stringify(), 'a' view.inputRefs.first.update() assert.is view.node.stringify(), 'b' it 'file `refs` are not accessed in components', -> source = createView ''' <a ref="first" label="12" visible="false" /> <component name="a"> ${typeof refs.first} </component> <use component="a" /> ''' view = source.clone() renderParse view assert.is view.node.stringify(), 'undefined' describe '`context`', -> it 'is accessed in rendered file', -> source = createView ''' ${context.a} ''' view = source.clone() renderParse view, storage: a: '1' assert.is view.node.stringify(), '1' view.revert() renderParse view, storage: a: '2' assert.is view.node.stringify(), '2' it 'is accesible by scope', -> source = createView ''' ${this.context.a} ''' view = source.clone() renderParse view, storage: a: '1' assert.is view.node.stringify(), '1' view.revert() renderParse view, storage: a: '2' assert.is view.node.stringify(), '2' it 'lookup use', -> source = createView ''' <component name="a">${context.a}</component> <use component="a" /> ''' view = source.clone() renderParse view, storage: a: '1' assert.is view.node.stringify(), '1' view.revert() renderParse view, storage: a: '2' assert.is view.node.stringify(), '2' it 'lookup n-each', -> source = createView ''' <blank n-each="[1]"> ${context.a} </blank> ''' view = source.clone() renderParse view, storage: a: '1' assert.is view.node.stringify(), '1' view.revert() renderParse view, storage: a: '2' assert.is view.node.stringify(), '2' describe '`state`', -> it 'is accessed in rendered file', -> source = createView ''' <script> this.onRender(function(){ this.state.set('a', 1); }); </script> ${state.a} ''' view = source.clone() renderParse view assert.is view.node.stringify(), '1' it 'is accessible by scope', -> source = createView ''' <script> this.onRender(function(){ this.state.set('a', 1); }); </script> ${this.state.a} ''' view = source.clone() renderParse view assert.is view.node.stringify(), '1' it 'is cleared on revert', -> source = createView ''' <script> this.onRender(function(){ this.state.set('a', (this.state.a || 0) + 1); }); </script> ${state.a} ''' view = source.clone() renderParse view assert.is view.node.stringify(), '1' view.revert() renderParse view assert.is view.node.stringify(), '1' it 'is not accessible in not rendered document', -> source = createView ''' <script> this.onCreate(function(){ this.a = !!this.state; }); </script> ${this.a} ''' view = source.clone() renderParse view assert.is view.node.stringify(), 'false' it 'binding is not updated on reverted component', -> source = createView ''' <script> this.onRender(function(){ this.state.set('obj', { a: 1 }); }); </script> ${state.obj.a || '0'} ''' view = source.clone() renderParse view view.revert() assert.is view.node.stringify(), '1' view.render() assert.is view.node.stringify(), '1' it 'handler is called on signal', -> source = createView ''' <span x="1" onPropsChange="${context.onPropsChange(2)}" /> ''' view = source.clone() calls = 0 renderParse view, storage: onPropsChange: (val) -> calls += 1 assert.is val, 2 view.node.children[0].props.set 'x', 2 assert.is calls, 1 it 'returned handler is called on signal with scope and parameters', -> source = createView ''' <span x="1" onPropsChange="${context.onPropsChange}" /> ''' view = source.clone() calls = 0 renderParse view, storage: onPropsChange: (prop, oldVal) -> calls += 1 assert.is @, view.node.children[0] assert.is prop, 'x' assert.is oldVal, 1 view.node.children[0].props.set 'x', 2 assert.is calls, 1 describe 'prop handler', -> it 'is called with proper scope and parameters', -> source = createView ''' <prop name="y" value="3" /> <span x="1" ref="a1" onPropsChange="${context.test(refs.a1.props.x, props.y)}" /> ''' view = source.clone() calls = 0 renderParse view, storage: test: (x, y) -> calls += 1 assert.is x, 2 assert.is y, 3 view.node.query('span').props.set 'x', 2 assert.is calls, 1 it 'is not called if the document is not rendered', -> source = createView ''' <prop name="y" value="3" /> <span x="1" ref="a1" onPropsChange="${context.onPropsChange()}" /> ''' view = source.clone() calls = 0 renderParse view, storage: onPropsChange: (x, y) -> calls += 1 view.node.query('span').props.set 'x', 4 assert.is calls, 1 view.revert() view.node.query('span').props.set 'x', 2 assert.is calls, 1 describe 'support real-time changes', -> it 'on `props`', -> source = createView ''' <component name="a">${props.x}</component> <use component="a" x="2" y="1" /> ''' view = source.clone() elem = view.node.children[0] renderParse view elem.props.set 'x', 1 assert.is view.node.stringify(), '1' it 'on `context`', -> source = createView '${context.x}' view = source.clone() storage = new Dict x: 1 renderParse view, storage: storage assert.is view.node.stringify(), '1' storage.set 'x', 2 assert.is view.node.stringify(), '2' it 'on `context` property', -> source = createView '${context.dict.x}' view = source.clone() storage = dict: new Dict x: 1 renderParse view, storage: storage assert.is view.node.stringify(), '1' storage.dict.set 'x', 2 assert.is view.node.stringify(), '2' it 'on `context` use', -> source = createView ''' <component name="a">${context.a}</component> <use component="a" /> ''' view = source.clone() renderParse view, storage: storage = new Dict a: '1' storage.set 'a', 2 assert.is view.node.stringify(), '2' it 'on `context` n-each', -> source = createView ''' <blank n-each="[1]"> ${context.a} </blank> ''' view = source.clone() renderParse view, storage: storage = new Dict a: '1' storage.set 'a', 2 assert.is view.node.stringify(), '2'