m.fragment docs
public api tests
This commit is contained in:
parent
53a83a58f2
commit
ec07d76fcd
9 changed files with 291 additions and 18 deletions
|
|
@ -6,14 +6,18 @@
|
||||||
<body>
|
<body>
|
||||||
<script src="../../module/module.js"></script>
|
<script src="../../module/module.js"></script>
|
||||||
<script src="../../ospec/ospec.js"></script>
|
<script src="../../ospec/ospec.js"></script>
|
||||||
|
<script src="../../querystring/parse.js"></script>
|
||||||
<script src="../../test-utils/callAsync.js"></script>
|
<script src="../../test-utils/callAsync.js"></script>
|
||||||
<script src="../../test-utils/parseURL.js"></script>
|
<script src="../../test-utils/parseURL.js"></script>
|
||||||
<script src="../../test-utils/domMock.js"></script>
|
<script src="../../test-utils/domMock.js"></script>
|
||||||
<script src="../../test-utils/pushStateMock.js"></script>
|
<script src="../../test-utils/pushStateMock.js"></script>
|
||||||
|
<script src="../../test-utils/xhrMock.js"></script>
|
||||||
|
<script src="../../test-utils/browserMock.js"></script>
|
||||||
|
|
||||||
<script src="../../util/stream.js"></script>
|
<script src="../../util/stream.js"></script>
|
||||||
<script src="../../render/vnode.js"></script>
|
<script src="../../render/vnode.js"></script>
|
||||||
<script src="../../render/trust.js"></script>
|
<script src="../../render/trust.js"></script>
|
||||||
|
<script src="../../render/fragment.js"></script>
|
||||||
<script src="../../render/hyperscript.js"></script>
|
<script src="../../render/hyperscript.js"></script>
|
||||||
<script src="../../render/render.js"></script>
|
<script src="../../render/render.js"></script>
|
||||||
<script src="../../querystring/build.js"></script>
|
<script src="../../querystring/build.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
var o = require("../../ospec/ospec")
|
var o = require("../../ospec/ospec")
|
||||||
var callAsync = require("../../test-utils/callAsync")
|
var callAsync = require("../../test-utils/callAsync")
|
||||||
var pushStateMock = require("../../test-utils/pushStateMock")
|
var browserMock = require("../../test-utils/browserMock")
|
||||||
var domMock = require("../../test-utils/domMock")
|
|
||||||
|
|
||||||
var m = require("../../render/hyperscript")
|
var m = require("../../render/hyperscript")
|
||||||
var coreRenderer = require("../../render/render")
|
var coreRenderer = require("../../render/render")
|
||||||
|
|
@ -18,13 +17,7 @@ o.spec("route", function() {
|
||||||
var $window, root, redraw, route
|
var $window, root, redraw, route
|
||||||
|
|
||||||
o.beforeEach(function() {
|
o.beforeEach(function() {
|
||||||
$window = {}
|
$window = browserMock(env)
|
||||||
|
|
||||||
var dom = domMock()
|
|
||||||
for (var key in dom) $window[key] = dom[key]
|
|
||||||
|
|
||||||
var loc = pushStateMock(env)
|
|
||||||
for (var key in loc) $window[key] = loc[key]
|
|
||||||
|
|
||||||
root = $window.document.body
|
root = $window.document.body
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,15 +88,7 @@ function traverseDirectory(pathname, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//init mocks
|
//init mocks
|
||||||
var domMock = require("../test-utils/domMock")()
|
global.window = require("../test-utils/browserMock")()
|
||||||
var xhrMock = require("../test-utils/xhrMock")()
|
|
||||||
var pushStateMock = require("../test-utils/pushStateMock")()
|
|
||||||
|
|
||||||
global.window = {}
|
|
||||||
for (var key in domMock) if (!window[key]) window[key] = domMock[key]
|
|
||||||
for (var key in xhrMock) if (!window[key]) window[key] = xhrMock[key]
|
|
||||||
for (var key in pushStateMock) if (!window[key]) window[key] = pushStateMock[key]
|
|
||||||
|
|
||||||
global.document = window.document
|
global.document = window.document
|
||||||
global.m = require("../index")
|
global.m = require("../index")
|
||||||
|
|
||||||
|
|
|
||||||
43
docs/fragment.md
Normal file
43
docs/fragment.md
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# fragment(html)
|
||||||
|
|
||||||
|
- [API](#api)
|
||||||
|
- [How it works](#how-it-works)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
Generates a trusted HTML [vnode](vnodes.md)
|
||||||
|
|
||||||
|
`vnode = m.fragment(attrs, children)`
|
||||||
|
|
||||||
|
Argument | Type | Required | Description
|
||||||
|
----------- | -------------------- | -------- | ---
|
||||||
|
`attrs` | `Object` | Yes | A map of attributes
|
||||||
|
`children` | `Array<Vnode>` | Yes | A list of vnodes
|
||||||
|
**returns** | `Vnode` | | A fragment [vnode](vnodes.md)
|
||||||
|
|
||||||
|
[How to read signatures](signatures.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### How it works
|
||||||
|
|
||||||
|
`m.fragment()` creates a [fragment vnode](vnodes.md) with attributes. It is meant for advanced use cases involving keys or lifecyle methods.
|
||||||
|
|
||||||
|
Normally you can use simple arrays instead to denote a list of child nodes or a range of nodes within a node list:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var groupVisible = true
|
||||||
|
|
||||||
|
m("ul", [
|
||||||
|
m("li", "child 1"),
|
||||||
|
m("li", "child 2"),
|
||||||
|
groupVisible ? [
|
||||||
|
m("li", "child 3"),
|
||||||
|
m("li", "child 4"),
|
||||||
|
] : null
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
There are a few benefits that come from using `m.fragment` instead of handwriting a vnode object structure: m.fragment creates [monomorphic objects](vnodes.md#monomorphic-objects), which have better performance characteristics than creating objects dynamically. In addition, using `m.fragment` makes your intentions clear, and it makes it less likely that you'll mistakenly set attributes on the vnode object rather than on the attrs object.
|
||||||
|
|
@ -65,4 +65,7 @@ function hyperscript(selector) {
|
||||||
return Vnode(selector, attrs && attrs.key, attrs || {}, Vnode.normalizeChildren(children), undefined, undefined)
|
return Vnode(selector, attrs && attrs.key, attrs || {}, Vnode.normalizeChildren(children), undefined, undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hyperscript.trust = require("./trust")
|
||||||
|
hyperscript.fragment = require("./fragment")
|
||||||
|
|
||||||
module.exports = hyperscript
|
module.exports = hyperscript
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,12 @@
|
||||||
|
|
||||||
<script src="../../render/vnode.js"></script>
|
<script src="../../render/vnode.js"></script>
|
||||||
<script src="../../render/trust.js"></script>
|
<script src="../../render/trust.js"></script>
|
||||||
|
<script src="../../render/fragment.js"></script>
|
||||||
<script src="../../render/hyperscript.js"></script>
|
<script src="../../render/hyperscript.js"></script>
|
||||||
<script src="../../render/render.js"></script>
|
<script src="../../render/render.js"></script>
|
||||||
<script src="test-hyperscript.js"></script>
|
<script src="test-hyperscript.js"></script>
|
||||||
<script src="test-trust.js"></script>
|
<script src="test-trust.js"></script>
|
||||||
|
<script src="test-fragment.js"></script>
|
||||||
<script src="test-normalize.js"></script>
|
<script src="test-normalize.js"></script>
|
||||||
<script src="test-normalizeChildren.js"></script>
|
<script src="test-normalizeChildren.js"></script>
|
||||||
<script src="test-createText.js"></script>
|
<script src="test-createText.js"></script>
|
||||||
|
|
|
||||||
18
test-utils/browserMock.js
Normal file
18
test-utils/browserMock.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
var pushStateMock = require("./pushStateMock")
|
||||||
|
var domMock = require("./domMock")
|
||||||
|
var xhrMock = require("./xhrMock")
|
||||||
|
|
||||||
|
module.exports = function(env) {
|
||||||
|
var $window = {}
|
||||||
|
|
||||||
|
var dom = domMock()
|
||||||
|
var xhr = xhrMock()
|
||||||
|
var ps = pushStateMock(env)
|
||||||
|
for (var key in dom) if (!$window[key]) $window[key] = dom[key]
|
||||||
|
for (var key in xhr) if (!$window[key]) $window[key] = xhr[key]
|
||||||
|
for (var key in ps) if (!$window[key]) $window[key] = ps[key]
|
||||||
|
|
||||||
|
return $window
|
||||||
|
}
|
||||||
21
tests/index.html
Normal file
21
tests/index.html
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="../module/module.js"></script>
|
||||||
|
<script src="../ospec/ospec.js"></script>
|
||||||
|
<script src="../querystring/parse.js"></script>
|
||||||
|
<script src="../test-utils/parseURL.js"></script>
|
||||||
|
<script src="../test-utils/callAsync.js"></script>
|
||||||
|
<script src="../test-utils/domMock.js"></script>
|
||||||
|
<script src="../test-utils/pushStateMock.js"></script>
|
||||||
|
<script src="../test-utils/xhrMock.js"></script>
|
||||||
|
<script src="../test-utils/browserMock.js"></script>
|
||||||
|
<script src="../mithril.js"></script>
|
||||||
|
<script src="test-api.js"></script>
|
||||||
|
|
||||||
|
<script>require("../ospec/ospec").run()</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
197
tests/test-api.js
Normal file
197
tests/test-api.js
Normal file
|
|
@ -0,0 +1,197 @@
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
var o = require("../ospec/ospec")
|
||||||
|
var browserMock = require("../test-utils/browserMock")
|
||||||
|
|
||||||
|
o.spec("api", function() {
|
||||||
|
var m
|
||||||
|
var FRAME_BUDGET = Math.floor(1000 / 60)
|
||||||
|
o.beforeEach(function() {
|
||||||
|
var mock = browserMock()
|
||||||
|
if (typeof global !== "undefined") global.window = mock, global.document = mock.document
|
||||||
|
m = require("../mithril")
|
||||||
|
})
|
||||||
|
|
||||||
|
o.spec("m", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var vnode = m("div")
|
||||||
|
|
||||||
|
o(vnode.tag).equals("div")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.version", function() {
|
||||||
|
o("works", function() {
|
||||||
|
o(typeof m.version).equals("string")
|
||||||
|
o(m.version.indexOf(".") > -1).equals(true)
|
||||||
|
o(/\d/.test(m.version)).equals(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.trust", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var vnode = m.trust("<br>")
|
||||||
|
|
||||||
|
o(vnode.tag).equals("<")
|
||||||
|
o(vnode.children).equals("<br>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.fragment", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var vnode = m.fragment({key: 123}, [m("div")])
|
||||||
|
|
||||||
|
o(vnode.tag).equals("[")
|
||||||
|
o(vnode.key).equals(123)
|
||||||
|
o(vnode.children.length).equals(1)
|
||||||
|
o(vnode.children[0].tag).equals("div")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.prop", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var stream = m.prop(5)
|
||||||
|
var doubled = stream.run(function(value) {return value * 2})
|
||||||
|
|
||||||
|
o(doubled()).equals(10)
|
||||||
|
})
|
||||||
|
o("m.prop.combine works", function() {
|
||||||
|
var added = m.prop.combine(function(a, b) {return a() + b()}, [
|
||||||
|
m.prop(1),
|
||||||
|
m.prop(2),
|
||||||
|
])
|
||||||
|
|
||||||
|
o(added()).equals(3)
|
||||||
|
})
|
||||||
|
o("m.prop.merge works", function() {
|
||||||
|
var added = m.prop.merge([
|
||||||
|
m.prop(1),
|
||||||
|
m.prop(2),
|
||||||
|
])
|
||||||
|
.run(function(values) {return values[0] + values[1]})
|
||||||
|
|
||||||
|
o(added()).equals(3)
|
||||||
|
})
|
||||||
|
o("m.prop.reject works", function() {
|
||||||
|
var stream = m.prop.reject(new Error("error"))
|
||||||
|
|
||||||
|
o(stream.error().message).equals("error")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.withAttr", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var spy = o.spy()
|
||||||
|
var handler = m.withAttr("value", spy)
|
||||||
|
|
||||||
|
handler({currentTarget: {value: 10}})
|
||||||
|
|
||||||
|
o(spy.args[0]).equals(10)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.parseQueryString", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var query = m.parseQueryString("?a=1&b=2")
|
||||||
|
|
||||||
|
o(query).deepEquals({a: 1, b: 2})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.buildQueryString", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var query = m.buildQueryString({a: 1, b: 2})
|
||||||
|
|
||||||
|
o(query).equals("a=1&b=2")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.render", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.render(root, m("div"))
|
||||||
|
|
||||||
|
o(root.childNodes.length).equals(1)
|
||||||
|
o(root.firstChild.nodeName).equals("DIV")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.mount", function() {
|
||||||
|
o("works", function() {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.mount(root, {view: function() {return m("div")}})
|
||||||
|
|
||||||
|
o(root.childNodes.length).equals(1)
|
||||||
|
o(root.firstChild.nodeName).equals("DIV")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.route", function() {
|
||||||
|
o("works", function(done) {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.route(root, "/a", {
|
||||||
|
"/a": {view: function() {return m("div")}}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
o(root.childNodes.length).equals(1)
|
||||||
|
o(root.firstChild.nodeName).equals("DIV")
|
||||||
|
|
||||||
|
done()
|
||||||
|
}, FRAME_BUDGET)
|
||||||
|
})
|
||||||
|
o("m.route.prefix", function(done) {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.route.prefix("#")
|
||||||
|
m.route(root, "/a", {
|
||||||
|
"/a": {view: function() {return m("div")}}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
o(root.childNodes.length).equals(1)
|
||||||
|
o(root.firstChild.nodeName).equals("DIV")
|
||||||
|
|
||||||
|
done()
|
||||||
|
}, FRAME_BUDGET)
|
||||||
|
})
|
||||||
|
o("m.route.get", function(done) {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.route(root, "/a", {
|
||||||
|
"/a": {view: function() {return m("div")}}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
o(m.route.get()).equals("/a")
|
||||||
|
|
||||||
|
done()
|
||||||
|
}, FRAME_BUDGET)
|
||||||
|
})
|
||||||
|
o("m.route.set", function(done) {
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.route(root, "/a", {
|
||||||
|
"/:id": {view: function() {return m("div")}}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
m.route.set("/b")
|
||||||
|
o(m.route.get()).equals("/b")
|
||||||
|
|
||||||
|
done()
|
||||||
|
}, FRAME_BUDGET)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.redraw", function() {
|
||||||
|
o("works", function(done) {
|
||||||
|
var count = 0
|
||||||
|
var root = window.document.createElement("div")
|
||||||
|
m.mount(root, {view: function() {count++}})
|
||||||
|
setTimeout(function() {
|
||||||
|
m.redraw()
|
||||||
|
|
||||||
|
o(count).equals(2)
|
||||||
|
|
||||||
|
done()
|
||||||
|
}, FRAME_BUDGET)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.request", function() {
|
||||||
|
o("works", function() {
|
||||||
|
o(typeof m.request).equals("function") // TODO improve
|
||||||
|
})
|
||||||
|
})
|
||||||
|
o.spec("m.jsonp", function() {
|
||||||
|
o("works", function() {
|
||||||
|
o(typeof m.jsonp).equals("function") // TODO improve
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue