UNPKG

neft

Version:

Universal Platform

596 lines (449 loc) 19.6 kB
'use strict' {unit, assert, utils, Document, Renderer, styles} = Neft {createView} = require '../document/utils' {describe, it} = unit {Element} = Document testViews = [] render = (opts) -> doc = createView opts.html {path} = doc Style = styles styles: opts.styles or {} queries: opts.queries or {} windowStyle: opts.windowStyle or {objects: {}} for key, subfile of Document._files if key.indexOf(path) is 0 testViews.push subfile Style.extendDocumentByStyles subfile clone = doc.render() clone.destroy() doc.render() describe 'src/styles', -> describe 'n-style', -> it 'can be a Renderer.Item instance', -> # item = Renderer.Rectangle.New() # node = new Element.Tag # node.props['n-style'] = item # doc = render # node: node # assert.is doc.styles.length, 1 # assert.isDefined style = doc.styles[0] # assert.is style.item, item it "accepts 'renderer:' prefix", -> doc = render html: '<b n-style="renderer:Rectangle" />' assert.is doc.styles.length, 1 assert.instanceOf (style = doc.styles[0]).item, Renderer.Rectangle it "accepts 'styles:file' syntax", -> doc = render html: '<b n-style="styles:file" />' styles: file: _main: getComponent: -> item: Renderer.Rectangle.New() assert.is doc.styles.length, 1 assert.instanceOf (item = doc.styles[0].item), Renderer.Rectangle it "accepts 'styles:file:style' syntax", -> doc = render html: '<b n-style="styles:file:style" />' styles: file: style: getComponent: -> item: Renderer.Rectangle.New() assert.is doc.styles.length, 1 assert.instanceOf (item = doc.styles[0].item), Renderer.Rectangle it "accepts 'styles:file:style:subid' syntax", -> doc = render html: '''<b n-style="styles:file:style"> <div n-style="renderer:Item"> <i n-style="styles:file:style:subid" /> </div> </b>''' styles: file: style: getComponent: -> item: Renderer.Rectangle.New() objects: subid: Renderer.Text.New() bNode = doc.node.query 'b' iNode = doc.node.query 'i' assert.is doc.styles.length, 1 assert.instanceOf bNode.style, Renderer.Rectangle assert.instanceOf iNode.style, Renderer.Text it "accepts 'styles:view:style:subid' syntax", -> doc = render html: '<b n-style="styles:view:style:subid" />' windowStyle: objects: subid: Renderer.Text.New() assert.is doc.styles.length, 1 assert.instanceOf doc.styles[0].item, Renderer.Text it 'created style is accessible in node', -> doc = render html: '<b n-style="renderer:Item" />' assert.is (node = doc.styles[0].node).name, 'b' assert.instanceOf node.style, Renderer.Item it 'node is accessible in created style document', -> doc = render html: '<b n-style="renderer:Item" />' bNode = doc.node.query 'b' assert.is bNode.style.document.node, bNode it 'must be specify to create a style', -> doc = render html: '<b />' node = doc.node.query 'b' assert.is doc.styles.length, 0 assert.isNotDefined node.style describe 'Renderer.Text::text', -> it 'is always equal of stringified node children', -> doc = render html: '<b n-style="renderer:Text">ab<i>c</i></b>' node = doc.node.query 'b' item = doc.styles[0].item assert.is item.text, node.stringifyChildren() node.children[0].text = '123' assert.is item.text, node.stringifyChildren() it 'is always equal of stringified visible node children', -> doc = render html: ''' <b n-style="renderer:Text">ab<i visible="false">c</i></b> ''' bNode = doc.node.query 'b' iNode = doc.node.query 'i' item = doc.styles[0].item assert.is item.text, bNode.stringifyChildren() iNode.props.set 'visible', true assert.is item.text, bNode.stringifyChildren() describe 'Renderer.Item::$.text', -> it 'is always equal stringified node children', -> doc = render html: '<b n-style="styles:file">ab<i>c</i></b>' styles: file: _main: getComponent: -> item = Renderer.Item.New() item.$.text = 'debug' item: item node = doc.node.query 'b' item = doc.styles[0].item assert.is item.$.text, node.stringifyChildren() node.children[0].text = '123' assert.is item.$.text, node.stringifyChildren() it 'is more important than ::text property', -> doc = render html: '<b n-style="styles:file">ab<i>c</i></b>' styles: file: _main: getComponent: -> item = Renderer.Text.New() item.$.text = 'debug' item: item node = doc.node.query 'b' item = doc.styles[0].item assert.is item.text, '' assert.is item.$.text, node.stringifyChildren() node.children[0].text = '123' assert.is item.text, '' assert.is item.$.text, node.stringifyChildren() describe 'Element.Text', -> it 'is rendered as Renderer.Text', -> doc = render html: '<b>abc</b>' assert.is doc.styles.length, 1 assert.instanceOf node = (style = doc.styles[0]).node, Element.Text assert.is node.text, 'abc' assert.instanceOf item = style.item, Renderer.Text it 'text is properly synchronized', -> doc = render html: '<b>abc</b>' node = doc.node.query '#text' item = doc.styles[0].item assert.is item.text, node.text node.text = '123' assert.is item.text, node.text it 'is not created if has a text parent', -> doc = render html: '<b n-style="styles:file">ab</b>' styles: file: _main: getComponent: -> item = Renderer.Text.New() item: item node = doc.node.query 'b' textNode = node.query '#text' item = doc.styles[0].item assert.instanceOf item, Renderer.Text assert.isNotDefined textNode.style describe 'a[href]', -> it 'sets style linkUri', -> doc = render html: '<a href="/abc" n-style="renderer:Item"></a>' node = doc.node.query 'a' assert.is doc.styles.length, 1 assert.instanceOf style = node.style, Renderer.Item assert.is style.linkUri, node.props.href it 'sets child node style linkUri', -> doc = render html: '<a href="/abc"><b n-style="renderer:Item" /></a>' aNode = doc.node.query 'a' bNode = doc.node.query 'b' assert.is doc.styles.length, 1 assert.instanceOf style = bNode.style, Renderer.Item assert.is style.linkUri, aNode.props.href it "doesn't set child node style linkUri if the parent node is styled", -> doc = render html: '''<a href="/abc" n-style="renderer:Item"> <b n-style="renderer:Item" /> </a>''' aNode = doc.node.query 'a' bNode = doc.node.query 'b' assert.is bNode.style.linkUri, '' it 'updates style linkUri on attr change', -> doc = render html: '<a href="/abc" n-style="renderer:Item"></a>' node = doc.node.query 'a' node.props.set 'href', '/123' assert.is node.style.linkUri, node.props.href it 'updates style linkUri on parent change', -> doc = render html: '<a href="/abc"><div /></a><b n-style="renderer:Item" />' aNode = doc.node.query 'a' divNode = doc.node.query 'div' bNode = doc.node.query 'b' assert.is bNode.style.linkUri, '' bNode.parent = divNode assert.is bNode.style.linkUri, aNode.props.href bNode.parent = null assert.is bNode.style.linkUri, '' it 'updates child style linkUri on attr change', -> doc = render html: ''' <a href="/abc"><div><b n-style="renderer:Item" /></div></a> ''' aNode = doc.node.query 'a' bNode = doc.node.query 'b' aNode.props.set 'href', '/123' assert.is bNode.style.linkUri, aNode.props.href it 'updates n-each styles', -> test = -> for child in ulNode.children assert.is child.query('#text').style?.linkUri, child.query('a').props.href return doc = render html: '''<ul n-each="[1,2]"> <a href="/${props.item}">${props.item}</a> </ul>''' ulNode = doc.node.query 'ul' test() ulNode.props.set 'n-each', [5, 6, 7] test() describe "'n-style:' attributes", -> it 'are set on a style item', -> doc = render html: '<b n-style="renderer:Item" n-style:x="50" />' {node, item} = doc.styles[0] assert.instanceOf item, Renderer.Item assert.is item.x, node.props['n-style:x'] it 'on change are set on a style item', -> doc = render html: '<b n-style="renderer:Item" n-style:x="50" />' {node, item} = doc.styles[0] node.props.set 'style:x', 70 assert.is item.x, node.props['n-style:x'] it "'null' value is not set for non-object properties", -> doc = render html: '<b n-style="renderer:Item" n-style:x="null" />' {node, item} = doc.styles[0] assert.is item.x, 0 node.props.set 'n-style:x', 4 node.props.set 'n-style:x', null assert.is item.x, 4 describe "'class' attribute", -> it 'sets item classes', -> doc = render html: '<b n-style="renderer:Item" class="a b c" />' {node, item} = doc.styles[0] assert.isEqual item.classes.toArray(), node.props.class.split(' ') it 'synchronizes item classes on add and remove', -> doc = render html: '<b n-style="renderer:Item" class="a b c" />' {node, item} = doc.styles[0] node.props.set 'class', 'g a c' assert.isEqual item.classes.toArray(), node.props.class.split(' ') describe 'Style item visible', -> it "is 'true' by default", -> doc = render html: '<b n-style="renderer:Item" />' assert.is doc.styles[0].item.visible, true it "is 'false' if the style node is invisible", -> doc = render html: '<b n-style="renderer:Item" visible="false" />' assert.is doc.styles[0].item.visible, false it "is 'false' if the style node comes invisible", -> doc = render html: '<b n-style="renderer:Item" />' node = doc.node.query 'b' node.visible = false assert.is doc.styles[0].item.visible, false it "is 'true' if the style node comes visible", -> doc = render html: '<b n-style="renderer:Item" visible="false" />' node = doc.node.query 'b' node.visible = true assert.is doc.styles[0].item.visible, true it "is 'false' if the not-styled node parent is invisible", -> doc = render html: '''<div visible="false"> <div><b n-style="renderer:Item" /></div> </div>''' assert.is doc.styles[0].item.visible, false it "is 'false' if the not-styled node parent comes invisible", -> doc = render html: """<div> <div><b n-style="renderer:Item" /></div> </div>""" node = doc.node.query 'div' node.visible = false assert.is doc.styles[0].item.visible, false it "is 'true' if the styled node parent is invisible", -> doc = render html: """<div n-style="renderer:Rectangle" visible="false"> <div><b n-style="renderer:Item" /></div> </div>""" bNode = doc.node.query 'b' assert.is bNode.style.visible, true it "is 'true' if the styled node parent comes invisible", -> doc = render html: """<div n-style="renderer:Rectangle"> <div><b n-style="renderer:Item" /></div> </div>""" divNode = doc.node.query 'div' bNode = doc.node.query 'b' divNode.visible = false assert.is bNode.style.visible, true describe "Style item parent", -> it "refers to the first styled parent style", -> doc = render html: """<div n-style="renderer:Item"> <b n-style="renderer:Item" /> </div>""" divNode = doc.node.query 'div' bNode = doc.node.query 'b' assert.is bNode.style.parent, divNode.style it "refers to the first styled parent style after the parent change", -> doc = render html: """<div n-style="renderer:Item"> <i /> </div> <b n-style="renderer:Item" />""" divNode = doc.node.query 'div' iNode = doc.node.query 'i' bNode = doc.node.query 'b' bNode.parent = iNode assert.is bNode.style.parent, divNode.style it "is properly synchronized on 'use'", -> doc = render html: '''<component name="a"> <b n-style="renderer:Item" /> <i n-style="renderer:Item" /> </component> <div n-style="renderer:Item"> <use component="a" /> </div>''' divNode = doc.node.query 'div' bNode = doc.node.query 'b' iNode = doc.node.query 'i' assert.is bNode.style.parent, divNode.style assert.is iNode.style.parent, divNode.style it "doesn't change if the item has a parent", -> doc = render html: """<div n-style="renderer:Item"></div> <b n-style="styles:file:style" />""" styles: file: style: getComponent: -> parent = Renderer.Item.New() item = Renderer.Item.New() item.parent = parent item: item divNode = doc.node.query 'div' bNode = doc.node.query 'b' bNode.parent = divNode assert.isDefined bNode.style.parent assert.isNot bNode.style.parent, divNode.style describe "Style item index", -> describe "is valid on", -> it "index change", -> doc = render html: """<div n-style="renderer:Item"> <em n-style="renderer:Item" /> <b n-style="renderer:Item" /> <i n-style="renderer:Item" /> </div>""" divNode = doc.node.query 'div' emNode = doc.node.query 'em' bNode = doc.node.query 'b' iNode = doc.node.query 'i' iNode.index = 1 assert.is iNode.style.previousSibling, emNode.style assert.is iNode.style.nextSibling, bNode.style it "parent change", -> doc = render html: """<div n-style="renderer:Item"> <em /> <b n-style="renderer:Item" /> </div> <i n-style="renderer:Item" />""" divNode = doc.node.query 'div' emNode = doc.node.query 'em' bNode = doc.node.query 'b' iNode = doc.node.query 'i' iNode.parent = emNode assert.is iNode.style.nextSibling, bNode.style it "is valid in n-each", -> test = -> childItem = divNode.style.children.firstChild for item in divNode.props['n-each'] assert.is childItem.text, item+'' childItem = childItem.nextSibling return doc = render html: """<div n-style="renderer:Item" n-each="[1,2,3]"> <b>${props.item}</b> </div>""" divNode = doc.node.query 'div' test() divNode.props.set 'n-each', [5,6,7,8] test() return it "is valid for fixed item parent", -> doc = render html: """<b n-style="styles:file:style"> <em n-style="renderer:Item" /> <i n-style="styles:file:style:subid" /> </b>""" styles: file: style: getComponent: -> item = Renderer.Rectangle.New() subid = Renderer.Text.New() subid.parent = item item: item objects: subid: subid bNode = doc.node.query 'b' emNode = doc.node.query 'em' iNode = doc.node.query 'i' assert.is emNode.style.nextSibling, iNode.style it '', -> for view in testViews utils.clear view.styles return