2013-10-12 16:05:13 +00:00
/ * \
title : test - widget . js
type : application / javascript
tags : [ [ $ : / t a g s / t e s t - s p e c ] ]
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 ( ) {
2013-11-08 08:47:00 +00:00
var widget = require ( "$:/core/modules/widgets/widget.js" ) ;
2013-10-12 16:05:13 +00:00
2013-11-13 21:26:13 +00:00
function createWidgetNode ( parseTreeNode , wiki ) {
2013-10-12 16:05:13 +00:00
return new widget . widget ( parseTreeNode , {
wiki : wiki ,
2014-01-15 14:57:35 +00:00
document : $tw . fakeDocument
2013-10-12 16:05:13 +00:00
} ) ;
}
2013-10-13 19:14:31 +00:00
function parseText ( text , wiki , options ) {
2013-11-08 08:51:14 +00:00
var parser = wiki . parseText ( "text/vnd.tiddlywiki" , text , options ) ;
2013-10-12 16:05:13 +00:00
return parser ? { type : "widget" , children : parser . tree } : undefined ;
}
function renderWidgetNode ( widgetNode ) {
2014-01-15 14:57:35 +00:00
$tw . fakeDocument . setSequenceNumber ( 0 ) ;
var wrapper = $tw . fakeDocument . createElement ( "div" ) ;
2013-10-12 16:05:13 +00:00
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 ) ;
2019-11-12 21:42:38 +00:00
// Test the rendering
expect ( wrapper . innerHTML ) . toBe ( "A text node<div class=\"myClass\" title=\"myTitle\"> and the content of a DIV<div> and an inner DIV</div> and back in the outer DIV</div>" ) ;
// Test the sequence numbers in the DOM
expect ( wrapper . sequenceNumber ) . toBe ( 0 ) ;
expect ( wrapper . children [ 0 ] . sequenceNumber ) . toBe ( 1 ) ;
expect ( wrapper . children [ 1 ] . sequenceNumber ) . toBe ( 2 ) ;
expect ( wrapper . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 3 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . sequenceNumber ) . toBe ( 4 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 5 ) ;
expect ( wrapper . children [ 1 ] . children [ 2 ] . sequenceNumber ) . toBe ( 6 ) ;
2013-10-12 16:05:13 +00:00
} ) ;
it ( "should deal with transclude widgets and indirect attributes" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add a tiddler
wiki . addTiddlers ( [
{ title : "TiddlerOne" , text : "the quick brown fox" }
] ) ;
// 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 : "indirect" , textReference : "TiddlerOne" }
} , 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" } ,
{ type : "transclude" , attributes : {
2013-10-30 13:36:44 +00:00
"tiddler" : { type : "string" , value : "TiddlerOne" }
2013-10-12 16:05:13 +00:00
} }
] } ,
{ type : "transclude" , attributes : {
2013-10-30 13:36:44 +00:00
"tiddler" : { type : "string" , value : "TiddlerOne" }
2013-10-12 16:05:13 +00:00
} }
] } ;
// Construct the widget node
var widgetNode = createWidgetNode ( parseTreeNode , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
2019-11-12 21:42:38 +00:00
// Test the rendering
expect ( wrapper . innerHTML ) . toBe ( "A text node<div class=\"myClass\" title=\"the quick brown fox\"> and the content of a DIV<div> and an inner DIV</div> and back in the outer DIVthe quick brown fox</div>the quick brown fox" ) ;
// Test the sequence numbers in the DOM
expect ( wrapper . sequenceNumber ) . toBe ( 0 ) ;
expect ( wrapper . children [ 0 ] . sequenceNumber ) . toBe ( 1 ) ;
expect ( wrapper . children [ 1 ] . sequenceNumber ) . toBe ( 2 ) ;
expect ( wrapper . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 3 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . sequenceNumber ) . toBe ( 4 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 5 ) ;
expect ( wrapper . children [ 1 ] . children [ 2 ] . sequenceNumber ) . toBe ( 6 ) ;
expect ( wrapper . children [ 1 ] . children [ 3 ] . sequenceNumber ) . toBe ( 7 ) ;
expect ( wrapper . children [ 2 ] . sequenceNumber ) . toBe ( 8 ) ;
2013-10-12 16:05:13 +00:00
// Change the transcluded tiddler
wiki . addTiddler ( { title : "TiddlerOne" , text : "jumps over the lazy dog" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerOne" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "A text node<div class=\"myClass\" title=\"jumps over the lazy dog\"> and the content of a DIV<div> and an inner DIV</div> and back in the outer DIVjumps over the lazy dog</div>jumps over the lazy dog" ) ;
// Test the sequence numbers in the DOM
expect ( wrapper . sequenceNumber ) . toBe ( 0 ) ;
expect ( wrapper . children [ 0 ] . sequenceNumber ) . toBe ( 1 ) ;
expect ( wrapper . children [ 1 ] . sequenceNumber ) . toBe ( 2 ) ;
expect ( wrapper . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 3 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . sequenceNumber ) . toBe ( 4 ) ;
expect ( wrapper . children [ 1 ] . children [ 1 ] . children [ 0 ] . sequenceNumber ) . toBe ( 5 ) ;
expect ( wrapper . children [ 1 ] . children [ 2 ] . sequenceNumber ) . toBe ( 6 ) ;
expect ( wrapper . children [ 1 ] . children [ 3 ] . sequenceNumber ) . toBe ( 9 ) ;
expect ( wrapper . children [ 2 ] . sequenceNumber ) . toBe ( 10 ) ;
2013-10-12 16:05:13 +00:00
} ) ;
it ( "should detect recursion of the transclude macro" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add a tiddler
wiki . addTiddlers ( [
2013-10-30 13:36:44 +00:00
{ title : "TiddlerOne" , text : "<$transclude tiddler='TiddlerOne'/>\n" }
2013-10-12 16:05:13 +00:00
] ) ;
// Test parse tree
var parseTreeNode = { type : "widget" , children : [
{ type : "transclude" , attributes : {
2013-10-30 13:36:44 +00:00
"tiddler" : { type : "string" , value : "TiddlerOne" }
2013-10-12 16:05:13 +00:00
} }
] } ;
// Construct the widget node
var widgetNode = createWidgetNode ( parseTreeNode , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
2019-11-12 21:42:38 +00:00
// Test the rendering
expect ( wrapper . innerHTML ) . toBe ( "<span class=\"tc-error\">Recursive transclusion error in transclude widget</span>\n" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
2013-10-13 19:14:31 +00:00
it ( "should deal with SVG elements" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Construct the widget node
2015-03-21 14:17:42 +00:00
var text = "<svg class=\"tv-image-new-button\" viewBox=\"83 81 50 50\" width=\"22pt\" height=\"22pt\"><path d=\"M 101.25 112.5 L 101.25 127.5 C 101.25 127.5 101.25 127.5 101.25 127.5 L 101.25 127.5 C 101.25 129.156855 102.593146 130.5 104.25 130.5 L 111.75 130.5 C 113.406854 130.5 114.75 129.156854 114.75 127.5 L 114.75 112.5 L 129.75 112.5 C 131.406854 112.5 132.75 111.156854 132.75 109.5 L 132.75 102 C 132.75 100.343146 131.406854 99 129.75 99 L 114.75 99 L 114.75 84 C 114.75 82.343146 113.406854 81 111.75 81 L 104.25 81 C 104.25 81 104.25 81 104.25 81 C 102.593146 81 101.25 82.343146 101.25 84 L 101.25 99 L 86.25 99 C 86.25 99 86.25 99 86.25 99 C 84.593146 99 83.25 100.343146 83.25 102 L 83.25 109.5 C 83.25 109.5 83.25 109.5 83.25 109.5 L 83.25 109.5 C 83.25 111.156855 84.593146 112.5 86.25 112.5 Z\"/></svg>\n" ;
2013-10-13 19:14:31 +00:00
var widgetNode = createWidgetNode ( parseText ( text , wiki , { parseAsInline : true } ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2015-03-21 14:17:42 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<svg class=\"tv-image-new-button\" height=\"22pt\" viewBox=\"83 81 50 50\" width=\"22pt\"><path d=\"M 101.25 112.5 L 101.25 127.5 C 101.25 127.5 101.25 127.5 101.25 127.5 L 101.25 127.5 C 101.25 129.156855 102.593146 130.5 104.25 130.5 L 111.75 130.5 C 113.406854 130.5 114.75 129.156854 114.75 127.5 L 114.75 112.5 L 129.75 112.5 C 131.406854 112.5 132.75 111.156854 132.75 109.5 L 132.75 102 C 132.75 100.343146 131.406854 99 129.75 99 L 114.75 99 L 114.75 84 C 114.75 82.343146 113.406854 81 111.75 81 L 104.25 81 C 104.25 81 104.25 81 104.25 81 C 102.593146 81 101.25 82.343146 101.25 84 L 101.25 99 L 86.25 99 C 86.25 99 86.25 99 86.25 99 C 84.593146 99 83.25 100.343146 83.25 102 L 83.25 109.5 C 83.25 109.5 83.25 109.5 83.25 109.5 L 83.25 109.5 C 83.25 111.156855 84.593146 112.5 86.25 112.5 Z\"></path></svg>\n" ) ;
2013-10-13 19:14:31 +00:00
expect ( wrapper . firstChild . namespaceURI ) . toBe ( "http://www.w3.org/2000/svg" ) ;
} ) ;
2013-10-12 16:05:13 +00:00
it ( "should parse and render transclusions" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add a tiddler
wiki . addTiddlers ( [
{ title : "TiddlerOne" , text : "Jolly Old World" } ,
2013-10-30 13:36:44 +00:00
{ title : "TiddlerTwo" , text : "<$transclude tiddler={{TiddlerThree}}/>" } ,
2013-10-12 16:05:13 +00:00
{ title : "TiddlerThree" , text : "TiddlerOne" }
] ) ;
// Construct the widget node
2013-10-30 13:36:44 +00:00
var text = "My <$transclude tiddler='TiddlerTwo'/> is Jolly"
2013-10-12 16:05:13 +00:00
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>My Jolly Old World is Jolly</p>" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
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
2013-10-30 13:36:44 +00:00
var text = "<$view tiddler='TiddlerOne'/>" ;
2013-10-12 16:05:13 +00:00
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>Jolly Old World</p>" ) ;
2013-10-12 16:05:13 +00:00
// 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" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>World-wide Jelly</p>" ) ;
// 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 ) ;
2013-10-12 16:05:13 +00:00
} ) ;
2013-11-15 18:31:39 +00:00
it ( "should deal with the set widget" , function ( ) {
2013-10-12 16:05:13 +00:00
var wiki = new $tw . Wiki ( ) ;
// Add some tiddlers
wiki . addTiddlers ( [
{ title : "TiddlerOne" , text : "Jolly Old World" } ,
2013-10-30 13:36:44 +00:00
{ title : "TiddlerTwo" , text : "<$transclude tiddler={{TiddlerThree}}/>" } ,
2013-10-12 16:05:13 +00:00
{ title : "TiddlerThree" , text : "TiddlerOne" } ,
{ title : "TiddlerFour" , text : "TiddlerTwo" }
] ) ;
// Construct the widget node
2013-11-15 18:31:39 +00:00
var text = "My <$set name='currentTiddler' value={{TiddlerFour}}><$transclude tiddler={{!!title}}/></$set> is Jolly"
2013-10-12 16:05:13 +00:00
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>My Jolly Old World is Jolly</p>" ) ;
2013-10-12 16:05:13 +00:00
// Change the transcluded tiddler
wiki . addTiddler ( { title : "TiddlerFour" , text : "TiddlerOne" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerFour" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>My Jolly Old World is Jolly</p>" ) ;
// 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 ) ;
2013-10-12 16:05:13 +00:00
} ) ;
it ( "should deal with attributes specified as macro invocations" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Construct the widget node
2013-11-13 21:26:13 +00:00
var text = "\\define myMacro(one:\"paramOne\",two,three:\"paramTwo\")\nMy something $one$, $two$ or other $three$\n\\end\n<div class=<<myMacro 'something' three:'thing'>>>Content</div>" ;
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
2013-10-12 16:05:13 +00:00
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2015-03-21 14:17:42 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p><div class=\"My something something, or other thing\">Content</div></p>" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
2013-10-17 15:57:07 +00:00
it ( "should deal with built-in macros" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add some tiddlers
wiki . addTiddlers ( [
{ title : "TiddlerOne" , text : "Jolly Old World" , type : "text/vnd.tiddlywiki" }
] ) ;
// Construct the widget node
var text = "\\define makelink(text,type)\n<a href=<<makedatauri text:\"$text$\" type:\"$type$\">>>My linky link</a>\n\\end\n\n<$macrocall $name=\"makelink\" text={{TiddlerOne}} type={{TiddlerOne!!type}}/>" ;
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2015-03-21 14:17:42 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p><a href=\"data:text/vnd.tiddlywiki,Jolly%20Old%20World\">My linky link</a></p>" ) ;
2013-10-17 15:57:07 +00:00
} ) ;
2020-07-31 07:25:15 +00:00
/* This test reproduces issue #4693. */
it ( "should render the entity widget" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Construct the widget node
var text = "\n\n<$entity entity=' ' />\n\n<$entity entity='✓' />\n" ;
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 ( " ✓" ) ;
// Test the sequence numbers in the DOM
expect ( wrapper . sequenceNumber ) . toBe ( 0 ) ;
expect ( wrapper . children [ 0 ] . sequenceNumber ) . toBe ( 1 ) ;
expect ( wrapper . children [ 0 ] . nodeType ) . toBe ( wrapper . children [ 0 ] . TEXT _NODE ) ;
expect ( wrapper . children [ 1 ] . sequenceNumber ) . toBe ( 2 ) ;
expect ( wrapper . children [ 1 ] . nodeType ) . toBe ( wrapper . children [ 1 ] . TEXT _NODE ) ;
} ) ;
2013-10-12 16:05:13 +00:00
it ( "should deal with the list widget" , 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>" ;
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
var wrapper = renderWidgetNode ( widgetNode ) ;
// Test the rendering
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFourTiddlerOneTiddlerThreeTiddlerTwo</p>" ) ;
2013-10-12 16:05:13 +00:00
// Add another tiddler
wiki . addTiddler ( { title : "TiddlerFive" , text : "Jalapeno Peppers" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerFive" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwo</p>" ) ;
// 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 ) ;
2013-10-12 16:05:13 +00:00
// Remove a tiddler
wiki . deleteTiddler ( "TiddlerThree" ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerThree" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerTwo</p>" ) ;
// 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 ) ;
2013-10-12 16:05:13 +00:00
// Add it back a tiddler
wiki . addTiddler ( { title : "TiddlerThree" , text : "Something" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerThree" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwo</p>" ) ;
// 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 ) ;
2013-10-12 16:05:13 +00:00
} ) ;
2013-10-21 21:27:12 +00:00
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
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething</p>" ) ;
2013-10-21 21:27:12 +00:00
// 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" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething</p>" ) ;
// 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 ) ;
2013-10-21 21:27:12 +00:00
// Remove a tiddler
wiki . deleteTiddler ( "TiddlerThree" ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerThree" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerTwoSomething</p>" ) ;
// 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 ) ;
2013-10-21 21:27:12 +00:00
// Add it back a tiddler
wiki . addTiddler ( { title : "TiddlerThree" , text : "Something" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "TiddlerThree" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoSomething</p>" ) ;
// 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 ) ;
2013-10-21 21:27:12 +00:00
// Add another a tiddler to the end of the list
wiki . addTiddler ( { title : "YetAnotherTiddler" , text : "Something" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "YetAnotherTiddler" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFiveTiddlerFourTiddlerOneTiddlerThreeTiddlerTwoYetAnotherTiddlerSomething</p>" ) ;
// 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 ) ;
2013-10-21 21:27:12 +00:00
} ) ;
2013-10-12 16:05:13 +00:00
it ( "should deal with the list widget and external templates" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add some tiddlers
wiki . addTiddlers ( [
2013-11-02 10:12:55 +00:00
{ title : "$:/myTemplate" , text : "(<$view field='title'/>)" } ,
2013-10-12 16:05:13 +00:00
{ 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 ) ;
2013-11-01 16:03:37 +00:00
//console.log(require("util").inspect(widgetNode,{depth:8,colors:true}));
2013-10-12 16:05:13 +00:00
// Test the rendering
2013-11-02 10:12:55 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>(TiddlerFour)(TiddlerOne)(TiddlerThree)(TiddlerTwo)</p>" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
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
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>nothing</p>" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
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
2013-10-29 14:52:12 +00:00
expect ( wrapper . innerHTML ) . toBe ( "<p>TiddlerFourTiddlerOneTiddlerThreeTiddlerTwo</p>" ) ;
2013-10-12 16:05:13 +00:00
// 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" ] ) ;
2019-11-12 21:42:38 +00:00
// Test the refreshing
expect ( wrapper . innerHTML ) . toBe ( "<p>nothing</p>" ) ;
2013-10-12 16:05:13 +00:00
} ) ;
2020-01-30 12:53:26 +00:00
/ * * T h i s t e s t c o n f i r m s t h a t i m p o r t e d s e t v a r i a b l e s p r o p e r l y r e f r e s h
* if they use transclusion for their value . This relates to PR # 4108.
* /
it ( "should refresh imported <$set> widgets" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add some tiddlers
wiki . addTiddlers ( [
{ title : "Raw" , text : "Initial value" } ,
{ title : "Macro" , text : "<$set name='test' value={{Raw}}>\n\ndummy text</$set>" } ,
{ title : "Caller" , text : text }
] ) ;
var text = "\\import Macro\n<<test>>" ;
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 ( "<p>Initial value</p>" ) ;
wiki . addTiddler ( { title : "Raw" , text : "New value" } ) ;
// Refresh
refreshWidgetNode ( widgetNode , wrapper , [ "Raw" ] ) ;
expect ( wrapper . innerHTML ) . toBe ( "<p>New value</p>" ) ;
} ) ;
it ( "should can mix setWidgets and macros when importing" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
// Add some tiddlers
wiki . addTiddlers ( [
{ title : "A" , text : "\\define A() Aval" } ,
{ title : "B" , text : "<$set name='B' value='Bval'>\n\ndummy text</$set>" } ,
{ title : "C" , text : "\\define C() Cval" }
] ) ;
var text = "\\import A B C\n<<A>> <<B>> <<C>>" ;
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 ( "<p>Aval Bval Cval</p>" ) ;
} ) ;
2020-04-23 08:10:52 +00:00
it ( "can have more than one macroDef variable imported" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
wiki . addTiddlers ( [
{ title : "ABC" , text : "<$set name=A value=A>\n\n<$set name=B value=B>\n\n<$set name=C value=C>\n\ndummy text</$set></$set></$set>" } ,
{ title : "D" , text : "\\define D() D" } ] ) ;
// A and B shouldn't chew up C just cause it's a macroDef
var text = "\\import ABC D\n<<A>> <<B>> <<C>> <<D>>" ;
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 ( "<p>A B C D</p>" ) ;
} ) ;
it ( "import doesn't hold onto dead variables" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
wiki . addTiddlers ( [
{ title : "ABC" , text : "\\define A() A\n\\define B() B\n<$set name=C value=C>\n\n</$set>" } ,
{ title : "DE" , text : "\\define D() D\n\\define E() E" } ] ) ;
var text = "\\import ABC DE\ncontent" ;
var widgetNode = createWidgetNode ( parseText ( text , wiki ) , wiki ) ;
// Render the widget node to the DOM
renderWidgetNode ( widgetNode ) ;
var childNode = widgetNode ;
while ( childNode . children . length > 0 ) {
childNode = childNode . children [ 0 ] ;
}
// First make sure A and B imported
expect ( childNode . getVariable ( "A" ) ) . toBe ( "A" ) ;
expect ( childNode . getVariable ( "B" ) ) . toBe ( "B" ) ;
expect ( childNode . getVariable ( "C" ) ) . toBe ( "C" ) ;
expect ( childNode . getVariable ( "D" ) ) . toBe ( "D" ) ;
expect ( childNode . getVariable ( "E" ) ) . toBe ( "E" ) ;
// Then change A and remove B
wiki . addTiddler ( { title : "ABC" , text : "\\define A() A2\n<$set name=C value=C2>\n\n</$set>" } ) ;
wiki . addTiddler ( { title : "DE" , text : "\\define D() D2" } ) ;
widgetNode . refresh ( { "ABC" : { modified : true } , "DE" : { modified : true } } ) ;
var childNode = widgetNode ;
while ( childNode . children . length > 0 ) {
childNode = childNode . children [ 0 ] ;
}
// Make sure \import recognized changes and deletions
expect ( childNode . getVariable ( "A" ) ) . toBe ( "A2" ) ;
expect ( childNode . getVariable ( "B" ) ) . toBe ( undefined ) ;
expect ( childNode . getVariable ( "C" ) ) . toBe ( "C2" ) ;
expect ( childNode . getVariable ( "D" ) ) . toBe ( "D2" ) ;
expect ( childNode . getVariable ( "E" ) ) . toBe ( undefined ) ;
} ) ;
2020-01-30 12:53:26 +00:00
/ * * S p e c i a l c a s e . < $ i m p o r t v a r i a b l e s > h a s d i f f e r e n t h a n d l i n g i f
* it doesn ' t end up importing any variables . Make sure it
* doesn ' t forget its childrenNodes .
* /
it ( "should work when import widget imports nothing" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
var text = "\\import [prefix[XXX]]\nDon't forget me." ;
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 ( "<p>Don't forget me.</p>" ) ;
} ) ;
2020-03-19 20:32:51 +00:00
/ * * T h i s t e s t r e p r o d u c e s i s s u e # 4 5 0 4 .
*
* The importvariable widget was creating redundant copies into
* itself of variables in widgets higher up in the tree . Normally ,
* this caused no errors , but it would mess up qualify - macros .
* They would find multiple instances of the same transclusion
* variable if a transclusion occured higher up in the widget tree
* than an importvariables AND that importvariables was importing
* at least ONE variable .
* /
it ( "adding imported variables doesn't change qualifyers" , function ( ) {
var wiki = new $tw . Wiki ( ) ;
function wikiparse ( text ) {
var tree = parseText ( text , wiki ) ;
var widgetNode = createWidgetNode ( tree , wiki ) ;
var wrapper = renderWidgetNode ( widgetNode ) ;
return wrapper . innerHTML ;
} ;
wiki . addTiddlers ( [
{ title : "body" , text : "\\import A\n<<qualify this>>" } ,
{ title : "A" , text : "\\define unused() ignored" }
] ) ;
// This transclude wraps "body", which has an
// importvariable widget in it.
var withA = wikiparse ( "{{body}}" ) ;
wiki . addTiddler ( { title : "A" , text : "" } ) ;
var withoutA = wikiparse ( "{{body}}" ) ;
// Importing two different version of "A" shouldn't cause
// the <<qualify>> widget to spit out something different.
expect ( withA ) . toBe ( withoutA ) ;
} ) ;
2013-10-12 16:05:13 +00:00
} ) ;
} ) ( ) ;