Skip to content

Instantly share code, notes, and snippets.

@git-toni
Created March 25, 2016 20:50
Show Gist options
  • Save git-toni/a3e2658fb97fd8b02121 to your computer and use it in GitHub Desktop.
Save git-toni/a3e2658fb97fd8b02121 to your computer and use it in GitHub Desktop.
Testing a mithril.js module
mock = (function () {
"use strict"
var window = {}
window.window = window
var document = window.document = {
// FIXME: add document.createRange().createContextualFragment()
childNodes: [],
createElement: function (tag) {
return {
style: {},
childNodes: [],
nodeType: 1,
nodeName: tag.toUpperCase(),
appendChild: document.appendChild,
removeChild: document.removeChild,
replaceChild: document.replaceChild,
insertBefore: function (node, reference) {
node.parentNode = this
var referenceIndex = this.childNodes.indexOf(reference)
var index = this.childNodes.indexOf(node)
if (index > -1) this.childNodes.splice(index, 1)
if (referenceIndex < 0) this.childNodes.push(node)
else this.childNodes.splice(referenceIndex, 0, node)
},
insertAdjacentHTML: function (position, html) {
// TODO: accept markup
if (position === "beforebegin") {
this.parentNode.insertBefore(
document.createTextNode(html),
this)
} else if (position === "beforeend") {
this.appendChild(document.createTextNode(html))
}
},
setAttribute: function (name, value) {
this[name] = value.toString()
},
setAttributeNS: function (namespace, name, value) {
this.namespaceURI = namespace
this[name] = value.toString()
},
getAttribute: function (name) {
return this[name]
},
addEventListener: function () {},
removeEventListener: function () {}
}
},
createElementNS: function (namespace, tag) {
var element = document.createElement(tag)
element.namespaceURI = namespace
return element
},
createTextNode: function (text) {
return {nodeValue: text.toString()}
},
replaceChild: function (newChild, oldChild) {
var index = this.childNodes.indexOf(oldChild)
if (index > -1) this.childNodes.splice(index, 1, newChild)
else this.childNodes.push(newChild)
newChild.parentNode = this
oldChild.parentNode = null
},
appendChild: function (child) {
var index = this.childNodes.indexOf(child)
if (index > -1) this.childNodes.splice(index, 1)
this.childNodes.push(child)
child.parentNode = this
},
removeChild: function (child) {
var index = this.childNodes.indexOf(child)
this.childNodes.splice(index, 1)
child.parentNode = null
},
// getElementsByTagName is only used by JSONP tests, it's not required
// by Mithril
getElementsByTagName: function (name) {
name = name.toLowerCase()
var out = []
function traverse(node) {
if (node.childNodes && node.childNodes.length > 0) {
node.childNodes.forEach(function (curr) {
if (curr.nodeName.toLowerCase() === name) {
out.push(curr)
}
traverse(curr)
})
}
}
traverse(document)
return out
}
}
document.documentElement = document.createElement("html")
window.scrollTo = function () {}
;(function () {
// This is an actual conforming implementation of the
// requestAnimationFrame spec, with the nonstandard extension of
// rAF.$resolve for running the callbacks. It works in Node and the
// browser.
// https://html.spec.whatwg.org/multipage/#animation-frames
//
// Adding and removing callbacks run in constant time. Please don't
// modify this unless it actually has an edge case bug. It will break
// other tests
var callbacks = []
var id = 0
var indices = {}
function requestAnimationFrame(callback) {
id++
indices[id] = callbacks.length
callbacks.push({
callback: callback,
id: id
})
return id
}
window.cancelAnimationFrame = function (id) {
var index = indices[id]
if (index !== 0) {
indices[id] = 0
callbacks[index] = undefined
}
}
var nanotime = typeof process === "object" ? function () {
var time = process.hrtime() // eslint-disable-line no-undef
return time[0] * 1e9 + time[1]
} : typeof performance === "object" ? function () {
return performance.now()
} : function () {
// PhantomJS 1 doesn't have the Performance API implemented.
return +new Date()
}
requestAnimationFrame.$resolve = function () {
var list = callbacks
callbacks = []
indices = {}
for (var i = 0; i < list.length; i++) {
var data = list[i]
if (data !== undefined) {
data.callback.call(data.id, nanotime())
}
}
}
window.requestAnimationFrame = requestAnimationFrame
})()
window.XMLHttpRequest = (function () {
function Request() {
this.$headers = {}
this.$resolve = function (data, status) {
if (data === undefined) data = this // eslint-disable-line
this.responseText = JSON.stringify(data)
this.readyState = 4
this.status = status || 200
return this
}
this.setRequestHeader = function (key, value) {
this.$headers[key] = value
}
this.open = function (method, url) {
this.method = method
this.url = url
}
this.send = function () {
Request.$instances.push(this)
}
}
Request.$instances = []
return Request
})()
var location = window.location = {search: "", pathname: "", hash: ""}
window.history = {
$$length: 0,
pushState: function (data, title, url) {
window.history.$$length++
location.pathname = location.search = location.hash = url
},
replaceState: function (data, title, url) {
location.pathname = location.search = location.hash = url
}
}
return window
})()
module.exports=mock;
'use strict';
var m = require('mithril');
var Module={};
Module.controller = function(args){
var ctrl = this;
ctrl.url = args.resource.url;
ctrl.title = args.resource.title;
}
module.exports = Module;
;(function(){
var mock = require('./mock.js');
var m = require('mithril');
var test = require('tape');
var Module = require('../module.js');
m.deps(mock.window);
var config={
url:'/urltoken',
title:'Module title'
}
var modu=m.component(Module,{resource:config});
test('constructor ',function(t){
t.equal(modu.controller().url,config.url);
t.end();
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment