UNPKG

mithril

Version:

A framework for building brilliant applications

157 lines (127 loc) 3.76 kB
"use strict" var o = require("../../ospec/ospec") var domMock = require("../../test-utils/domMock") var vdom = require("../../render/render") // pilfered and adapted from https://github.com/domvm/domvm/blob/7aaec609e4c625b9acf9a22d035d6252a5ca654f/test/src/flat-list-keyed-fuzz.js o.spec("updateNodes keyed list Fuzzer", function() { var i = 0, $window, root, render o.beforeEach(function() { $window = domMock() root = $window.document.createElement("div") render = vdom($window) }) void [ {delMax: 0, movMax: 50, insMax: 9}, {delMax: 3, movMax: 5, insMax: 5}, {delMax: 7, movMax: 15, insMax: 0}, {delMax: 5, movMax: 100, insMax: 3}, {delMax: 5, movMax: 0, insMax: 3}, ].forEach(function(c) { var tests = 250 while (tests--) { var test = fuzzTest(c.delMax, c.movMax, c.insMax) o(i++ + ": " + test.list.join() + " -> " + test.updated.join(), function() { render(root, test.list.map(function(x){return {tag: x, key: x}})) addSpies(root) render(root, test.updated.map(function(x){return {tag: x, key: x}})) if (root.appendChild.callCount + root.insertBefore.callCount !== test.expected.creations + test.expected.moves) console.log(test, {aC: root.appendChild.callCount, iB: root.insertBefore.callCount}, [].map.call(root.childNodes, function(n){return n.nodeName.toLowerCase()})) o(root.appendChild.callCount + root.insertBefore.callCount).equals(test.expected.creations + test.expected.moves)("moves") o(root.removeChild.callCount).equals(test.expected.deletions)("deletions") o([].map.call(root.childNodes, function(n){return n.nodeName.toLowerCase()})).deepEquals(test.updated) }) } }) }) // https://en.wikipedia.org/wiki/Longest_increasing_subsequence // impl borrowed from https://github.com/ivijs/ivi function longestIncreasingSubsequence(a) { var p = a.slice() var result = [] result.push(0) var u var v for (var i = 0, il = a.length; i < il; ++i) { var j = result[result.length - 1] if (a[j] < a[i]) { p[i] = j result.push(i) continue } u = 0 v = result.length - 1 while (u < v) { var c = ((u + v) / 2) | 0 // eslint-disable-line no-bitwise if (a[result[c]] < a[i]) { u = c + 1 } else { v = c } } if (a[i] < a[result[u]]) { if (u > 0) { p[i] = result[u - 1] } result[u] = i } } u = result.length v = result[u - 1] while (u-- > 0) { result[u] = v v = p[v] } return result } function rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min } function ins(arr, qty) { var p = ["a","b","c","d","e","f","g","h","i"] while (qty-- > 0) arr.splice(rand(0, arr.length - 1), 0, p.shift()) } function del(arr, qty) { while (qty-- > 0) arr.splice(rand(0, arr.length - 1), 1) } function mov(arr, qty) { while (qty-- > 0) { var from = rand(0, arr.length - 1) var to = rand(0, arr.length - 1) arr.splice(to, 0, arr.splice(from, 1)[0]) } } function fuzzTest(delMax, movMax, insMax) { var list = ["k0","k1","k2","k3","k4","k5","k6","k7","k8","k9"] var copy = list.slice() var delCount = rand(0, delMax), movCount = rand(0, movMax), insCount = rand(0, insMax) del(copy, delCount) mov(copy, movCount) var expected = { creations: insCount, deletions: delCount, moves: 0 } if (movCount > 0) { var newPos = copy.map(function(v) { return list.indexOf(v) }).filter(function(i) { return i != -1 }) var lis = longestIncreasingSubsequence(newPos) expected.moves = copy.length - lis.length } ins(copy, insCount) return { expected: expected, list: list, updated: copy } } function addSpies(node) { node.appendChild = o.spy(node.appendChild) node.insertBefore = o.spy(node.insertBefore) node.removeChild = o.spy(node.removeChild) }