/*\ title: test-widget.js type: application/javascript tags: [[$:/tags/test-spec]] Tests the wikitext rendering pipeline end-to-end. We also need tests that individually test parsers, rendertreenodes etc., but this gets us started. \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; describe("Widget module", function() { var widget = require("$:/core/modules/widgets/widget.js"); function createWidgetNode(parseTreeNode,wiki,variables) { return new widget.widget(parseTreeNode,{ wiki: wiki, variables: variables || {}, document: $tw.document }); } function parseText(text,wiki,options) { var parser = wiki.parseText("text/vnd.tiddlywiki",text,options); return parser ? {type: "widget", children: parser.tree} : undefined; } function renderWidgetNode(widgetNode) { $tw.document.setSequenceNumber(0); var wrapper = $tw.document.createElement("div"); widgetNode.render(wrapper,null); // console.log(require("util").inspect(wrapper,{depth: 8})); return wrapper; } function refreshWidgetNode(widgetNode,wrapper,changes) { var changedTiddlers = {}; if(changes) { $tw.utils.each(changes,function(title) { changedTiddlers[title] = true; }); } widgetNode.refresh(changedTiddlers,wrapper,null); // console.log(require("util").inspect(wrapper,{depth: 8})); } it("should deal with text nodes and HTML elements", function() { var wiki = new $tw.Wiki(); // Test parse tree var parseTreeNode = {type: "widget", children: [ {type: "text", text: "A text node"}, {type: "element", tag: "div", attributes: { "class": {type: "string", value: "myClass"}, "title": {type: "string", value: "myTitle"} }, children: [ {type: "text", text: " and the content of a DIV"}, {type: "element", tag: "div", children: [ {type: "text", text: " and an inner DIV"}, ]}, {type: "text", text: " and back in the outer DIV"} ]} ]}; // Construct the widget node var widgetNode = createWidgetNode(parseTreeNode,wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); describe("should render", function() { // Test the rendering expect(wrapper.innerHTML).toBe("A text node
My Jolly Old World is Jolly
"); }); it("should render the view widget", function() { var wiki = new $tw.Wiki(); // Add a tiddler wiki.addTiddlers([ {title: "TiddlerOne", text: "Jolly Old World"} ]); // Construct the widget node var text = "<$view tiddler='TiddlerOne'/>"; var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering expect(wrapper.innerHTML).toBe("Jolly Old World
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(2); // Change the transcluded tiddler wiki.addTiddler({title: "TiddlerOne", text: "World-wide Jelly"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerOne"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("World-wide Jelly
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(3); }); }); it("should deal with the setvariable widget", function() { var wiki = new $tw.Wiki(); // Add some tiddlers wiki.addTiddlers([ {title: "TiddlerOne", text: "Jolly Old World"}, {title: "TiddlerTwo", text: "<$transclude tiddler={{TiddlerThree}}/>"}, {title: "TiddlerThree", text: "TiddlerOne"}, {title: "TiddlerFour", text: "TiddlerTwo"} ]); // Construct the widget node var text = "My <$setvariable name='currentTiddler' value={{TiddlerFour}}><$transclude tiddler={{!!title}}/>$setvariable> is Jolly" var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering expect(wrapper.innerHTML).toBe("My Jolly Old World is Jolly
"); // Change the transcluded tiddler wiki.addTiddler({title: "TiddlerFour", text: "TiddlerOne"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerFour"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("My Jolly Old World is Jolly
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(2); expect(wrapper.children[0].children[1].sequenceNumber).toBe(5); expect(wrapper.children[0].children[2].sequenceNumber).toBe(4); }); }); it("should deal with attributes specified as macro invocations", function() { var wiki = new $tw.Wiki(); // Construct the widget node var text = "TiddlerFourTiddlerOneTiddlerThreeTiddlerTwo
"); // Add another tiddler wiki.addTiddler({title: "TiddlerFive", text: "Jalapeno Peppers"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerFive"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwo
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(6); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(4); expect(wrapper.children[0].children[4].sequenceNumber).toBe(5); }); // Remove a tiddler wiki.deleteTiddler("TiddlerThree"); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerTwo
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(6); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(5); }); // Add it back a tiddler wiki.addTiddler({title: "TiddlerThree", text: "Something"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwo
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(6); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(7); expect(wrapper.children[0].children[4].sequenceNumber).toBe(5); }); }); it("should deal with the list widget followed by other widgets", function() { var wiki = new $tw.Wiki(); // Add some tiddlers wiki.addTiddlers([ {title: "TiddlerOne", text: "Jolly Old World"}, {title: "TiddlerTwo", text: "Worldly Old Jelly"}, {title: "TiddlerThree", text: "Golly Gosh"}, {title: "TiddlerFour", text: "Lemon Squash"} ]); // Construct the widget node var text = "<$list><$view field='title'/>$list>Something"; var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering expect(wrapper.innerHTML).toBe("TiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething
"); // Check the next siblings of each of the list elements var listWidget = widgetNode.children[0].children[0]; // Add another tiddler wiki.addTiddler({title: "TiddlerFive", text: "Jalapeno Peppers"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerFive"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(7); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(4); expect(wrapper.children[0].children[4].sequenceNumber).toBe(5); }); // Remove a tiddler wiki.deleteTiddler("TiddlerThree"); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerTwoSomething
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(7); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(5); }); // Add it back a tiddler wiki.addTiddler({title: "TiddlerThree", text: "Something"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(7); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(8); expect(wrapper.children[0].children[4].sequenceNumber).toBe(5); }); // Add another a tiddler to the end of the list wiki.addTiddler({title: "YetAnotherTiddler", text: "Something"}); // Refresh refreshWidgetNode(widgetNode,wrapper,["YetAnotherTiddler"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoYetAnotherTiddlerSomething
"); // Test the sequence numbers in the DOM expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].children[0].sequenceNumber).toBe(7); expect(wrapper.children[0].children[1].sequenceNumber).toBe(2); expect(wrapper.children[0].children[2].sequenceNumber).toBe(3); expect(wrapper.children[0].children[3].sequenceNumber).toBe(8); expect(wrapper.children[0].children[4].sequenceNumber).toBe(5); }); }); it("should deal with the list widget and external templates", function() { var wiki = new $tw.Wiki(); // Add some tiddlers wiki.addTiddlers([ {title: "$:/myTemplate", text: "(<$view field='title'/>)"}, {title: "TiddlerOne", text: "Jolly Old World"}, {title: "TiddlerTwo", text: "Worldly Old Jelly"}, {title: "TiddlerThree", text: "Golly Gosh"}, {title: "TiddlerFour", text: "Lemon Squash"} ]); // Construct the widget node var text = "<$list template='$:/myTemplate'>$list>"; var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); //console.log(require("util").inspect(widgetNode,{depth:8,colors:true})); // Test the rendering expect(wrapper.innerHTML).toBe("(TiddlerFour)(TiddlerOne)(TiddlerThree)(TiddlerTwo)
"); }); it("should deal with the list widget and empty lists", function() { var wiki = new $tw.Wiki(); // Construct the widget node var text = "<$list emptyMessage='nothing'><$view field='title'/>$list>"; var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering expect(wrapper.innerHTML).toBe("nothing
"); }); it("should refresh lists that become empty", function() { var wiki = new $tw.Wiki(); // Add some tiddlers wiki.addTiddlers([ {title: "TiddlerOne", text: "Jolly Old World"}, {title: "TiddlerTwo", text: "Worldly Old Jelly"}, {title: "TiddlerThree", text: "Golly Gosh"}, {title: "TiddlerFour", text: "Lemon Squash"} ]); // Construct the widget node var text = "<$list emptyMessage='nothing'><$view field='title'/>$list>"; var widgetNode = createWidgetNode(parseText(text,wiki),wiki); // Render the widget node to the DOM var wrapper = renderWidgetNode(widgetNode); // Test the rendering expect(wrapper.innerHTML).toBe("TiddlerFourTiddlerOneTiddlerThreeTiddlerTwo
"); // Get rid of the tiddlers wiki.deleteTiddler("TiddlerOne"); wiki.deleteTiddler("TiddlerTwo"); wiki.deleteTiddler("TiddlerThree"); wiki.deleteTiddler("TiddlerFour"); // Refresh refreshWidgetNode(widgetNode,wrapper,["TiddlerOne","TiddlerTwo","TiddlerThree","TiddlerFour"]); describe("should refresh", function() { // Test the refreshing expect(wrapper.innerHTML).toBe("nothing
"); }); }); }); })();