mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-30 05:19:57 +00:00
Refactor compound tiddler handling into data widget
And add some tests for the data widget
This commit is contained in:
parent
6c9b8116bd
commit
683ec33004
@ -31,7 +31,12 @@ DataWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
var domNode = this.document.createTextNode("");
|
||||
parent.insertBefore(domNode,nextSibling);
|
||||
this.renderChildren(parent,nextSibling);
|
||||
// Children must have been rendered before we can read the data values
|
||||
domNode.textContent = JSON.stringify(this.readDataTiddlerValues());
|
||||
this.domNodes.push(domNode);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -52,29 +57,75 @@ DataWidget.prototype.readDataTiddlerValues = function() {
|
||||
// Read any attributes not prefixed with $
|
||||
$tw.utils.each(this.attributes,function(value,name) {
|
||||
if(name.charAt(0) !== "$") {
|
||||
item[name] = value;
|
||||
item[name] = value;
|
||||
}
|
||||
});
|
||||
// Deal with $tiddler or $filter attributes
|
||||
var titles;
|
||||
item = new $tw.Tiddler(item);
|
||||
// Deal with $tiddler, $filter or $compound-tiddler attributes
|
||||
var tiddlers = [],title;
|
||||
if(this.hasAttribute("$tiddler")) {
|
||||
titles = [this.getAttribute("$tiddler")];
|
||||
} else if(this.hasAttribute("$filter")) {
|
||||
titles = this.wiki.filterTiddlers(this.getAttribute("$filter"));
|
||||
title = this.getAttribute("$tiddler");
|
||||
if(title) {
|
||||
tiddlers.push(this.wiki.getTiddler(title));
|
||||
}
|
||||
}
|
||||
if(titles) {
|
||||
var results = [];
|
||||
$tw.utils.each(titles,function(title,index) {
|
||||
var tiddler = self.wiki.getTiddler(title),
|
||||
fields;
|
||||
if(tiddler) {
|
||||
fields = tiddler.getFieldStrings();
|
||||
}
|
||||
results.push($tw.utils.extend({},fields,item));
|
||||
})
|
||||
return results;
|
||||
if(this.hasAttribute("$filter")) {
|
||||
var filter = this.getAttribute("$filter");
|
||||
if(filter) {
|
||||
var titles = this.wiki.filterTiddlers(filter);
|
||||
$tw.utils.each(titles,function(title) {
|
||||
var tiddler = self.wiki.getTiddler(title);
|
||||
tiddlers.push(tiddler);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(this.hasAttribute("$compound-tiddler")) {
|
||||
title = this.getAttribute("$compound-tiddler");
|
||||
if(title) {
|
||||
tiddlers.push.apply(tiddlers,this.extractCompoundTiddler(title));
|
||||
}
|
||||
}
|
||||
// Convert the literal item to field strings
|
||||
item = item.getFieldStrings();
|
||||
if(tiddlers.length === 0) {
|
||||
if(Object.keys(item).length > 0 && !!item.title) {
|
||||
return [item];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return [item];
|
||||
var results = [];
|
||||
$tw.utils.each(tiddlers,function(tiddler,index) {
|
||||
var fields = tiddler.getFieldStrings();
|
||||
results.push($tw.utils.extend({},fields,item));
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Helper to extract tiddlers from text/vnd.tiddlywiki-multiple tiddlers
|
||||
*/
|
||||
DataWidget.prototype.extractCompoundTiddler = function(title) {
|
||||
var tiddler = this.wiki.getTiddler(title);
|
||||
if(tiddler && tiddler.fields.type === "text/vnd.tiddlywiki-multiple") {
|
||||
var text = tiddler.fields.text || "",
|
||||
rawTiddlers = text.split("\n+\n"),
|
||||
tiddlers = [];
|
||||
$tw.utils.each(rawTiddlers,function(rawTiddler) {
|
||||
var fields = Object.create(null),
|
||||
split = rawTiddler.split(/\r?\n\r?\n/mg);
|
||||
if(split.length >= 1) {
|
||||
fields = $tw.utils.parseFields(split[0],fields);
|
||||
}
|
||||
if(split.length >= 2) {
|
||||
fields.text = split.slice(1).join("\n\n");
|
||||
}
|
||||
tiddlers.push(new $tw.Tiddler(fields));
|
||||
});
|
||||
return tiddlers;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -53,20 +53,12 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
|
||||
Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues());
|
||||
});
|
||||
this.testcaseWiki.addTiddlers(tiddlers);
|
||||
// Load tiddlers from the optional testcaseTiddler
|
||||
if(this.testcaseTiddler) {
|
||||
var tiddler = this.wiki.getTiddler(this.testcaseTiddler);
|
||||
if(tiddler && tiddler.fields.type === "text/vnd.tiddlywiki-multiple") {
|
||||
var tiddlers = this.extractMultipleTiddlers(tiddler.fields.text);
|
||||
this.testcaseWiki.addTiddlers(tiddlers);
|
||||
}
|
||||
}
|
||||
// Unpack plugin tiddlers
|
||||
this.testcaseWiki.readPluginInfo();
|
||||
this.testcaseWiki.registerPluginTiddlers("plugin");
|
||||
this.testcaseWiki.unpackPluginTiddlers();
|
||||
this.testcaseWiki.addIndexersToWiki();
|
||||
// Gemerate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers
|
||||
// Generate a `transclusion` variable that depends on the values of the payload tiddlers so that the template can easily make unique state tiddlers
|
||||
this.setVariable("transclusion",$tw.utils.hashString(this.testcaseWiki.getTiddlersAsJson("[all[tiddlers]]")));
|
||||
// Generate a `testcaseInfo` variable that contains information about the subwiki in JSON format
|
||||
var testcaseInfoData = {
|
||||
@ -80,24 +72,6 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
TestCaseWidget.prototype.extractMultipleTiddlers = function(text) {
|
||||
// Duplicates code found in $:/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js
|
||||
var rawTiddlers = text.split("\n+\n"),
|
||||
tiddlers = [];
|
||||
$tw.utils.each(rawTiddlers,function(rawTiddler) {
|
||||
var fields = Object.create(null),
|
||||
split = rawTiddler.split(/\r?\n\r?\n/mg);
|
||||
if(split.length >= 1) {
|
||||
fields = $tw.utils.parseFields(split[0],fields);
|
||||
}
|
||||
if(split.length >= 2) {
|
||||
fields.text = split.slice(1).join("\n\n");
|
||||
}
|
||||
tiddlers.push(fields);
|
||||
});
|
||||
return tiddlers;
|
||||
};
|
||||
|
||||
/*
|
||||
Render a test case
|
||||
*/
|
||||
@ -126,7 +100,6 @@ TestCaseWidget.prototype.testcaseRawTiddler = function(parent,nextSibling,title,
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
TestCaseWidget.prototype.execute = function() {
|
||||
this.testcaseTiddler = this.getAttribute("testcase-tiddler");
|
||||
this.testcaseTemplate = this.getAttribute("template","$:/core/ui/testcases/DefaultTemplate");
|
||||
// Make child widgets
|
||||
var parseTreeNodes = [{
|
||||
|
@ -0,0 +1,25 @@
|
||||
title: Data/ImportCompound
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Importing a compound payload tiddler and adding custom fields
|
||||
|
||||
title: Description
|
||||
text: Importing a compound payload tiddler and adding custom fields
|
||||
+
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$data $compound-tiddler="Compound" custom="Alpha"/>
|
||||
+
|
||||
title: Compound
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Payload Tiddler
|
||||
tags: Alpha Beta Gamma
|
||||
|
||||
This is a payload tiddler from a compound tiddler
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[{"title":"Payload Tiddler","tags":"Alpha Beta Gamma","text":"This is a payload tiddler from a compound tiddler","custom":"Alpha"}]</p>
|
@ -0,0 +1,26 @@
|
||||
title: Data/ImportFilter
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Importing a payload filter and adding custom fields
|
||||
|
||||
title: Description
|
||||
text: Importing a payload filter and adding custom fields
|
||||
+
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$data $filter="[tag[Definitions]]" custom="Alpha"/>
|
||||
+
|
||||
title: HelloThere
|
||||
tags: Definitions
|
||||
|
||||
This is the tiddler HelloThere
|
||||
+
|
||||
title: AnotherDefinition
|
||||
tags: Definitions
|
||||
|
||||
This is the tiddler AnotherDefinition
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[{"title":"AnotherDefinition","tags":"Definitions","text":"This is the tiddler AnotherDefinition","custom":"Alpha"},{"title":"HelloThere","tags":"Definitions","text":"This is the tiddler HelloThere","custom":"Alpha"}]</p>
|
@ -0,0 +1,21 @@
|
||||
title: Data/ImportTiddler
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Importing a payload tiddler and adding custom fields
|
||||
|
||||
title: Description
|
||||
text: Importing a payload tiddler and adding custom fields
|
||||
+
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$data $tiddler="HelloThere" custom="Alpha"/>
|
||||
+
|
||||
title: HelloThere
|
||||
tags: Definitions
|
||||
|
||||
This is the tiddler HelloThere
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[{"title":"HelloThere","tags":"Definitions","text":"This is the tiddler HelloThere","custom":"Alpha"}]</p>
|
16
editions/test/tiddlers/tests/data/data-widget/Simple.tid
Normal file
16
editions/test/tiddlers/tests/data/data-widget/Simple.tid
Normal file
@ -0,0 +1,16 @@
|
||||
title: Data/Simple
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
description: Standalone data widget to create individual tiddlers
|
||||
|
||||
title: Description
|
||||
text: Standalone data widget to create individual tiddlers
|
||||
+
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$data title="Epsilon" text="Theta"/>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>[{"title":"Epsilon","text":"Theta"}]</p>
|
@ -16,6 +16,7 @@ A demo of the geospatial functionality is [ext[available here|./plugins/tiddlywi
|
||||
It also includes a number of new features that are intended for eventual inclusion in the core:
|
||||
|
||||
* TestCaseWidget, TestCaseTranscludeWidget and TestCaseViewWidget
|
||||
* Enhancements to the existing DataWidget
|
||||
* [[jsonset Operator]]
|
||||
* [[setquerystring Operator]]
|
||||
* [[WidgetMessage: tm-http-request]]
|
||||
|
@ -14,23 +14,22 @@ The data widget is used with the <<.wlink TestCaseWidget>> widget and the [[Inne
|
||||
The content of the data widget is rendered as if the data widget were not present. It supports the following attributes:
|
||||
|
||||
|!Attribute |!Description |
|
||||
|<<.attr $tiddler>> |The title of a tiddler to be used as a payload tiddler (optional) |
|
||||
|<<.attr $filter>> |A filter string identifying tiddlers to be used as payload tiddlers (optional) |
|
||||
|<<.attr $tiddler>> |Optional title of a tiddler to be used as a payload tiddler (optional) |
|
||||
|<<.attr $filter>> |Optional filter string identifying tiddlers to be used as payload tiddlers (optional) |
|
||||
|<<.attr $compound-tiddler>> |Optional title of a tiddler containing payload tiddlers in `text/vnd.tiddlywiki-multiple` format (see below) |
|
||||
|//any attribute<br>not starting<br>with $// |Field values to be assigned to the payload tiddler(s) |
|
||||
|
||||
The data widget can be used in three different ways:
|
||||
The data widget is not rendered when used within the <<.wlink TestCaseWidget>> widget or the [[Innerwiki Plugin]] but for ease of testing, when used elsewhere it renders a JSON representation of the payload tiddlers.
|
||||
|
||||
* Without the `$tiddler` or `$filter` attributes, the remaining attributes provide the fields for a single payload tiddler
|
||||
* With the `$tiddler` attribute present, the payload tiddler takes its fields from that tiddler with the remaining attributes overriding those fields
|
||||
* With the `$filter` attribute present, the payload is a copy of all of the tiddlers identified by the filter, with the remaining attributes overriding those fields of each one
|
||||
|
||||
This example injects a tiddler with the title "Epsilon" and the text "Theta":
|
||||
Without any of the attributes <<.attr $tiddler>>, <<.attr $filter>> or <<.attr $compound-tiddler>>, any attributes whose name does not start with $ are used as the field values for creating a single new tiddler. For example, here a tiddler with the title "Epsilon" and the text "Theta" is created:
|
||||
|
||||
```
|
||||
<$data title="Epsilon" text="Theta"/>
|
||||
```
|
||||
|
||||
This example injects a copy of the "HelloThere" tiddler with the addition of the field "custom" set to "Alpha":
|
||||
If any of the attributes <<.attr $tiddler>>, <<.attr $filter>> or <<.attr $compound-tiddler>> are specified then they are used to generate base tiddlers that are then modified with the addition of fields derived from any attributes whose name does not start with $.
|
||||
|
||||
This example, here we specify a copy of the "HelloThere" tiddler with the addition of the field "custom" set to "Alpha":
|
||||
|
||||
```
|
||||
<$data $tiddler="HelloThere" custom="Alpha"/>
|
||||
@ -41,3 +40,26 @@ This example injects all image tiddlers with the addition of the field "custom"
|
||||
```
|
||||
<$data $filter="[is[image]]" custom="Beta"/>
|
||||
```
|
||||
|
||||
! Compound Tiddlers
|
||||
|
||||
Compound tiddlers provide a way to easily create multiple tiddlers from within a single tiddler. They are contained in tiddlers of type `text/vnd.tiddlywiki-multiple`. The text field consists of a series of tiddlers in the same format as `.tid` files, each separated by a line containing a single `+` character.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
title: First
|
||||
tags: one two
|
||||
|
||||
This is the first tiddler
|
||||
+
|
||||
title: Second
|
||||
tags: three four
|
||||
|
||||
This is the second tiddler
|
||||
+
|
||||
title: third
|
||||
tags: five six
|
||||
|
||||
This is the third tiddler
|
||||
```
|
@ -14,38 +14,15 @@ The testcase widget creates an independent subwiki loaded with specified tiddler
|
||||
The content of the `<$testcase>` widget is not displayed but instead is scanned for <<.wlink DataWidget>> widgets that define the payload tiddlers to be included in the test case.
|
||||
|
||||
|!Attribute |!Description |
|
||||
|<<.attr testcase-tiddler>> |Optional title of a tiddler containing a test case in `text/vnd.tiddlywiki-multiple` format (see below) |
|
||||
|<<.attr template>> |Optional title of the template used to display the testcase (defaults to $:/core/ui/testcases/DefaultTemplate) |
|
||||
|
||||
! State Handling
|
||||
|
||||
The `<$testcase>` widget sets the variable `transclusion` to a hash that reflects the names and values of all the payload tiddlers. This makes easier for test case templates to create unique state tiddler titles using the [[qualify Macro]] or QualifyWidget.
|
||||
|
||||
! Payload Tiddlers
|
||||
|
||||
The payload tiddlers are the tiddler values that are loaded into the subwiki that is created to run the tests.
|
||||
|
||||
The payload tiddlers can be created in two different ways:
|
||||
|
||||
* Tiddlers values specfied via <<.wlink DataWidget>> widgets within the body of the `<$testcase>` widget
|
||||
* As multiple tiddlers embedded within a single tiddler of type `text/vnd.tiddlywiki-multiple` whose title is given in the <<.attr testcase-tiddler>> attribute
|
||||
|
||||
The special tiddler type `text/vnd.tiddlywiki-multiple` is intended to simplify creating test cases that require several tiddlers. The text field consists of a series of tiddlers in the same format as `.tid` files, each separated by a line containing a single `+` character.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
title: First
|
||||
tags: one two
|
||||
|
||||
This is the first tiddler
|
||||
+
|
||||
title: Second
|
||||
tags: three four
|
||||
|
||||
This is the second tiddler
|
||||
+
|
||||
title: third
|
||||
tags: five six
|
||||
|
||||
This is the third tiddler
|
||||
```
|
||||
The payload tiddlers are the tiddler values that are loaded into the subwiki that is created to run the tests. They are created via <<.wlink DataWidget>> widgets within the body of the `<$testcase>` widget.
|
||||
|
||||
! Test Case Templates
|
||||
|
||||
@ -55,9 +32,11 @@ The default test case template $:/core/ui/testcases/DefaultTemplate displays a s
|
||||
|
||||
The `<$testcase>` widget assigns a value to the `transclusion` variable that depends on the combined values of all the payload tiddlers. This means that using the `<<qualify>>` macro within a test case template will generate a unique value for each of multiple test cases within the same tiddler.
|
||||
|
||||
! Test Case Variables
|
||||
|
||||
The `<$testcase>` widget also assigns a block of information about the subwiki in JSON format to a the variable `testcaseInfo`. It contains the following properties:
|
||||
|
||||
* ''titles'': an array of the titles of all the tiddlers in the subwiki (excluding shadow tiddlers)
|
||||
* ''tiddlers'': a hashmap by title of an array of all the field names of each tiddler in the subwiki (does not include shadow tiddlers unless they have been overridden)
|
||||
|
||||
! Test Case Conventions
|
||||
|
||||
|
@ -8,6 +8,7 @@ The `geodistance` operator calculates the distance between two points in [[GeoJS
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geodistance">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geodistance"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
@ -10,6 +10,7 @@ Each input list item is interpreted as a [[GeoJSON Point Feature]] and the opera
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geolookup">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geolookup"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
@ -8,6 +8,7 @@ The `geonearestpoint` operator determines the point in a list that is nearest to
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geonearestpoint">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geonearestpoint"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
@ -16,6 +16,7 @@ Any operands that cannot be interpreted as a valid number will be interpreted as
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geopoint">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/geopoint"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
||||
|
@ -8,6 +8,7 @@ The `olc-decode` operator converts an [[OpenLocationCode|https://github.com/goog
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/olc-decode">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/olc-decode"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
@ -8,6 +8,7 @@ The `old-encode` operator converts separate latitude and longitude numbers into
|
||||
|
||||
!! Examples
|
||||
|
||||
<$testcase testcase-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/olc-encode">
|
||||
<$testcase>
|
||||
<$data $compound-tiddler="$:/plugins/tiddlywiki/geospatial/tests/operators/olc-encode"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/geospatial"/>
|
||||
</$testcase>
|
Loading…
Reference in New Issue
Block a user