Fix for tag ordering issue #6382 (#6383)

* Failing test

* Fix underlying problem

* Less naive fix

Now we make sure we maintain the sort order of the titles array when adding a new tiddler

* Fix failing tests

* Refactor filter tests to repeat them with different store orderings

* Revert "Fix failing tests"

This reverts commit ee03ee57f5.

* Refine fix to retain stylesheet ordering

The order of tiddlers in the HTML file uses localeCompare(), and that determines the insertion order. So if we want to be compatible with older versions we have to use localeCompare() to order tiddlers, not a plain sort()

* Don't sort shadow tiddlers

Instead rely on the existing ordering

* Fix failing tests, take 2

I think that all of these changes are explained by the store no longer retaining insertion order, but now using localecompare ordering

* Fix tests from #6327
This commit is contained in:
Jeremy Ruston 2022-02-21 15:34:05 +00:00 committed by GitHub
parent 82c8fe7fa8
commit 36b162a377
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 159 additions and 69 deletions

View File

@ -68,6 +68,26 @@ $tw.utils.isArrayEqual = function(array1,array2) {
});
};
/*
Add an entry to a sorted array if it doesn't already exist, while maintaining the sort order
*/
$tw.utils.insertSortedArray = function(array,value) {
var low = 0, high = array.length - 1, mid, cmp;
while(low <= high) {
mid = (low + high) >> 1;
cmp = value.localeCompare(array[mid]);
if(cmp > 0) {
low = mid + 1;
} else if(cmp < 0) {
high = mid - 1;
} else {
return array;
}
}
array.splice(low,0,value);
return array;
};
/*
Push entries onto an array, removing them first if they already exist in the array
array: array to modify (assumed to be free of duplicates)
@ -1094,7 +1114,7 @@ $tw.Wiki = function(options) {
tiddlerTitles = null, // Array of tiddler titles
getTiddlerTitles = function() {
if(!tiddlerTitles) {
tiddlerTitles = Object.keys(tiddlers);
tiddlerTitles = Object.keys(tiddlers).sort(function(a,b) {return a.localeCompare(b);});
}
return tiddlerTitles;
},
@ -1147,10 +1167,8 @@ $tw.Wiki = function(options) {
}
// Save the new tiddler
tiddlers[title] = tiddler;
// Check we've got it's title
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
tiddlerTitles.push(title);
}
// Check we've got the title
tiddlerTitles = $tw.utils.insertSortedArray(tiddlerTitles || [],title);
// Record the new tiddler state
updateDescriptor["new"] = {
tiddler: tiddler,

View File

@ -57,8 +57,19 @@ Tests the filtering mechanism.
);
});
describe("With tiddlers in the store unsorted",function() {
testWithAndWithoutIndexers();
});
describe("With tiddlers in the store sorted ascending",function() {
testWithAndWithoutIndexers({sort: "ascending"});
});
describe("With tiddlers in the store sorted descending",function() {
testWithAndWithoutIndexers({sort: "descending"});
});
function testWithAndWithoutIndexers(options) {
describe("With no indexers", function() {
var wiki = setupWiki({enableIndexers: []});
var wiki = setupWiki(Object.assign({},options,{enableIndexers: []}));
it("should not create indexes when requested not to",function() {
expect(wiki.getIndexer("FieldIndexer")).toBe(null);
});
@ -66,14 +77,16 @@ Tests the filtering mechanism.
});
describe("With all indexers", function() {
var wiki = setupWiki();
var wiki = setupWiki(options);
if(wiki.getIndexer("FieldIndexer")) {
wiki.getIndexer("FieldIndexer").setMaxIndexedValueLength(8); // Note that JoeBloggs is 9, and John is 5
}
runTests(wiki);
});
}
function setupWiki(wikiOptions) {
wikiOptions = wikiOptions || {};
// Create a wiki
var wiki = new $tw.Wiki(wikiOptions);
// Add a plugin containing some shadow tiddlers
@ -104,13 +117,12 @@ Tests the filtering mechanism.
}
}
};
wiki.addTiddler({
var tiddlers = [{
title: "$:/ShadowPlugin",
text: JSON.stringify(shadowTiddlers),
"plugin-type": "plugin",
type: "application/json"});
// Add a few tiddlers
wiki.addTiddler({
type: "application/json"
},{
title: "TiddlerOne",
text: "The quick brown fox in $:/TiddlerTwo",
tags: ["one"],
@ -119,8 +131,8 @@ Tests the filtering mechanism.
slug: "tiddler-one",
authors: "Joe Bloggs",
modifier: "JoeBloggs",
modified: "201304152222"});
wiki.addTiddler({
modified: "201304152222"
},{
title: "$:/TiddlerTwo",
text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]",
tags: ["two"],
@ -129,44 +141,75 @@ Tests the filtering mechanism.
slug: "tiddler-two",
authors: "[[John Doe]]",
modifier: "John",
modified: "201304152211"});
wiki.addTiddler({
modified: "201304152211"
},{
title: "Tiddler Three",
text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix",
tags: ["one","two"],
cost: "56",
value: "80",
modifier: "John",
modified: "201304162202"});
wiki.addTiddler({
modified: "201304162202"
},{
title: "a fourth tiddler",
text: "The quality of mercy is not drained by [[Tiddler Three]]",
tags: [],
cost: "82",
value: "72",
empty: "not",
modifier: "John"});
wiki.addTiddler({
modifier: "John"
},{
title: "one",
text: "This is the text of tiddler [[one]]",
list: "[[Tiddler Three]] [[TiddlerOne]]",
empty: "",
modifier: "John"});
wiki.addTiddler({
modifier: "John"
},{
title: "hasList",
text: "This is the text of tiddler [[hasList]]",
list: "[[Tiddler Three]] [[TiddlerOne]]",
modifier: "PMario"});
wiki.addTiddler({
modifier: "PMario"
},{
title: "has filter",
text: "This is the text of tiddler [[has filter]]",
filter: "[[Tiddler Three]] [[TiddlerOne]] [subfilter{hasList!!list}]",
modifier: "PMario"});
wiki.addTiddler({
modifier: "PMario"
},{
title: "filter regexp test",
text: "Those strings have been used to create the `regexp = /[+|\-|~]?([[](?:[^\]])*\]+)|([+|-|~|\S]\S*)/;`",
filter: "+aaa -bbb ~ccc aaaaaabbbbbbbbaa \"bb'b\" 'cc\"c' [[abc]] [[tiddler with spaces]] [is[test]] [is[te st]] a s df [enlist<hugo>] +[enlist:raw{test with spaces}] [enlist:raw{test with spaces}] [[a a]] [[ ] [ ]] [[ [hugo]] [subfilter{Story/Tower of Hanoi/A-C Sequence}]",
modifier: "PMario"});
modifier: "PMario"
}];
// Load the tiddlers in the required order
var fnCompare;
switch(wikiOptions.sort) {
case "ascending":
fnCompare = function(a,b) {
if(a.title < b.title) {
return -1;
} else if(a.title > b.title) {
return +1;
} else {
return 0;
}
};
break;
case "descending":
fnCompare = function(a,b) {
if(a.title < b.title) {
return +1;
} else if(a.title > b.title) {
return -1;
} else {
return 0;
}
};
break;
}
if(fnCompare) {
tiddlers.sort(fnCompare);
}
wiki.addTiddlers(tiddlers);
// Unpack plugin tiddlers
wiki.readPluginInfo();
wiki.registerPluginTiddlers("plugin");
@ -197,7 +240,7 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]then[Susi]]").join(",")).toBe("Susi,Susi,Susi,Susi,Susi,Susi,Susi,Susi");
expect(wiki.filterTiddlers("[modifier[DaveBloggs]then[Susi]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[modifier[JoeBloggs]else[Susi]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]else[Susi]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[modifier[DaveBloggs]else[Susi]]").join(",")).toBe("Susi");
});
@ -221,31 +264,31 @@ Tests the filtering mechanism.
it("should handle the title operator", function() {
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,TiddlerOne");
expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]] [[A Missing Tiddler]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,A Missing Tiddler");
});
it("should handle the field operator", function() {
expect(wiki.filterTiddlers("[modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[field:modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("TiddlerOne,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!field:modifier[JoeBloggs]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[JoeBloggs]]").join(",")).toBe("a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
expect(wiki.filterTiddlers("[!modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[!is[system]!modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[field:modifier[John]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three");
expect(wiki.filterTiddlers("[!field:modifier[John]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[!is[system]!field:modifier[John]]").join(",")).toBe("filter regexp test,has filter,hasList,TiddlerOne");
});
it("should handle the regexp operator", function() {
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[regexp[id]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!regexp[id]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
expect(wiki.filterTiddlers("[regexp[Tid]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[regexp[(?i)Tid]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!regexp[Tid(?i)]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,has filter,hasList,one");
});
// The following 2 tests should write a log -> WARNING: Filter modifier has a deprecated regexp operand XXXX
@ -255,7 +298,7 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[modifier/JoeBloggs/]").join(",")).toBe("TiddlerOne");
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /JoeBloggs/);
console.log.calls.reset();
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one");
expect(wiki.filterTiddlers("[modifier/Jo/]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,one,Tiddler Three,TiddlerOne");
expect(console.log).toHaveBeenCalledWith("WARNING: Filter", "modifier", "has a deprecated regexp operand", /Jo/);
});
@ -270,15 +313,15 @@ Tests the filtering mechanism.
});
it("should handle the prefix operator", function() {
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe("");
});
it("should handle the sort and sortcs operators", function() {
expect(wiki.filterTiddlers("[sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[!sort[title]]").join(",")).toBe("TiddlerOne,Tiddler Three,one,hasList,has filter,filter regexp test,a fourth tiddler,$:/TiddlerTwo,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[sort[modified]]").join(",")).toBe("$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one,$:/TiddlerTwo,TiddlerOne,Tiddler Three");
expect(wiki.filterTiddlers("[!sort[modified]]").join(",")).toBe("Tiddler Three,TiddlerOne,$:/TiddlerTwo,$:/ShadowPlugin,a fourth tiddler,filter regexp test,has filter,hasList,one");
// Temporarily commenting out the following two lines because of platform differences for localeCompare between the browser and Node.js
// expect(wiki.filterTiddlers("[sortcs[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler,one");
// expect(wiki.filterTiddlers("[!sortcs[title]]").join(",")).toBe("one,a fourth tiddler,TiddlerOne,Tiddler Three,$:/TiddlerTwo");
@ -328,10 +371,10 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[all[shadows]tag[two]]").join(",")).toBe("$:/TiddlerFive");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerFive,$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,$:/TiddlerFive");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
expect(wiki.filterTiddlers("[all[shadows+tiddlers]]").join(",")).toBe("$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8,$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[all[tiddlers+shadows]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne,$:/TiddlerFive,TiddlerSix,TiddlerSeventh,Tiddler8");
expect(wiki.filterTiddlers("[all[tiddlers]tag[two]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,hasList,has filter,filter regexp test,two,one");
expect(wiki.filterTiddlers("[all[orphans+tiddlers+tags]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,Tiddler Three,TiddlerOne,two,one");
});
it("should handle the tags operator", function() {
@ -342,11 +385,11 @@ Tests the filtering mechanism.
it("should handle the match operator", function() {
expect(wiki.filterTiddlers("[match[TiddlerOne]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("TiddlerOne TiddlerOne =[match[TiddlerOne]]").join(",")).toBe("TiddlerOne,TiddlerOne");
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match[TiddlerOne]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[match:casesensitive[tiddlerone]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match:casesensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[match:caseinsensitive[tiddlerone]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[!match:caseinsensitive[tiddlerone]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three");
});
it("should handle the tagging operator", function() {
@ -397,7 +440,7 @@ Tests the filtering mechanism.
});
it("should handle the listed operator", function() {
expect(wiki.filterTiddlers("TiddlerOne MissingTiddler +[listed[]]").join(",")).toBe('one,hasList');
expect(wiki.filterTiddlers("TiddlerOne MissingTiddler +[listed[]]").join(",")).toBe('hasList,one');
expect(wiki.filterTiddlers("one two +[listed[tags]]").join(",")).toBe('TiddlerOne,$:/TiddlerTwo,Tiddler Three');
});
@ -421,7 +464,7 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[search:modifier:regexp[(d|bl)o(ggs|e)]sort[title]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[search:-modifier,authors:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three");
expect(wiki.filterTiddlers("[search:*:[g]sort[title]]").join(",")).toBe("$:/ShadowPlugin,filter regexp test,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler");
expect(wiki.filterTiddlers("[search:text:anchored[the]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne");
});
it("should yield search results where 'default' search finds at least 1 token", function() {
@ -462,13 +505,13 @@ Tests the filtering mechanism.
});
it("should handle the each operator", function() {
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,hasList,TiddlerOne");
expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[each:list-item[tags]sort[title]]").join(",")).toBe("one,two");
expect(wiki.filterTiddlers("[each:list-item[authors]sort[title]]").join(",")).toBe("Bloggs,Joe,John Doe");
});
it("should handle the eachday operator", function() {
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[eachday[modified]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three");
});
it("should handle the sameday operator", function() {
@ -496,7 +539,7 @@ Tests the filtering mechanism.
});
it("should handle the '[is[missing]]' operator", function() {
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,TiddlerOne,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,one,hasList,has filter,filter regexp test");
expect(wiki.filterTiddlers("[all[]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[all[missing]]").join(",")).toBe("TiddlerZero");
expect(wiki.filterTiddlers("[!is[missing]sort[title]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,a fourth tiddler,filter regexp test,has filter,hasList,one,Tiddler Three,TiddlerOne");
expect(wiki.filterTiddlers("[[TiddlerOne]is[missing]]").join(",")).toBe("");
@ -507,11 +550,11 @@ Tests the filtering mechanism.
it("should handle the '[is[orphan]]' operator", function() {
expect(wiki.filterTiddlers("[is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,one,hasList,has filter");
expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one,Tiddler Three");
expect(wiki.filterTiddlers("[[TiddlerOne]is[orphan]]").join(",")).toBe("TiddlerOne");
expect(wiki.filterTiddlers("[[TiddlerOne]!is[orphan]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[!title[Tiddler Three]is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,filter regexp test,TiddlerOne");
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,one,hasList,has filter");
expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/ShadowPlugin,$:/TiddlerTwo,has filter,hasList,one");
});
});
@ -825,10 +868,10 @@ Tests the filtering mechanism.
rootWidget.setVariable("sort2","[get[text]else[]length[]]");
rootWidget.setVariable("sort3","[{!!value}divide{!!cost}]");
rootWidget.setVariable("sort4","[{!!title}]");
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter,hasList,one");
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("TiddlerOne,has filter,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,TiddlerOne,has filter");
expect(wiki.filterTiddlers("[sortsub:number<sort1>]",anchorWidget).join(",")).toBe("one,hasList,has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test");
expect(wiki.filterTiddlers("[!sortsub:number<sort1>]",anchorWidget).join(",")).toBe("filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne,hasList,one");
expect(wiki.filterTiddlers("[sortsub:string<sort1>]",anchorWidget).join(",")).toBe("has filter,TiddlerOne,$:/TiddlerTwo,Tiddler Three,$:/ShadowPlugin,a fourth tiddler,filter regexp test,one,hasList");
expect(wiki.filterTiddlers("[!sortsub:string<sort1>]",anchorWidget).join(",")).toBe("hasList,one,filter regexp test,a fourth tiddler,$:/ShadowPlugin,$:/TiddlerTwo,Tiddler Three,has filter,TiddlerOne");
expect(wiki.filterTiddlers("[sortsub:number<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test,$:/ShadowPlugin");
expect(wiki.filterTiddlers("[!sortsub:number<sort2>]",anchorWidget).join(",")).toBe("$:/ShadowPlugin,filter regexp test,$:/TiddlerTwo,Tiddler Three,a fourth tiddler,has filter,hasList,TiddlerOne,one");
expect(wiki.filterTiddlers("[sortsub:string<sort2>]",anchorWidget).join(",")).toBe("one,TiddlerOne,hasList,has filter,$:/ShadowPlugin,a fourth tiddler,Tiddler Three,$:/TiddlerTwo,filter regexp test");

View File

@ -392,10 +392,10 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
rootWidget.setVariable("larger-than-18","[get[text]length[]compare:integer:gteq[18]]");
rootWidget.setVariable("nr","18");
rootWidget.setVariable("larger-than-18-with-var","[get[text]length[]compare:integer:gteq<nr>]");
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Sparkling water,Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Red wine,Cheesecake,Chocolate Cake");
expect(wiki.filterTiddlers("[tag[textexample]] :filter[get[text]length[]compare:integer:gteq[18]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
expect(wiki.filterTiddlers("[tag[textexample]]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine,Sparkling water");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
expect(wiki.filterTiddlers("[tag[textexample]filter<larger-than-18-with-var>]",anchorWidget).join(",")).toBe("Cheesecake,Chocolate Cake,Red wine");
});
it("should handle the :sort prefix", function() {
@ -405,7 +405,7 @@ describe("'reduce' and 'intersection' filter prefix tests", function() {
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:[get[text]length[]]").join(",")).toBe("Sparkling water,Chocolate Cake,Red wine,Cheesecake");
expect(wiki.filterTiddlers("[tag[textexample]] :sort:number:reverse[get[text]length[]]").join(",")).toBe("Cheesecake,Red wine,Chocolate Cake,Sparkling water");
expect(wiki.filterTiddlers("[tag[notatag]] :sort:number[get[price]]").join(",")).toBe("");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("Cheesecake,cheesecake,Chocolate Cake,chocolate cake,Persian love cake,Pound cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string[{!!title}]").join(",")).toBe("cheesecake,Cheesecake,chocolate cake,Chocolate Cake,Persian love cake,Pound cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive[{!!title}]").join(",")).toBe("Cheesecake,Chocolate Cake,Persian love cake,Pound cake,cheesecake,chocolate cake");
expect(wiki.filterTiddlers("[tag[cakes]] :sort:string:casesensitive,reverse[{!!title}]").join(",")).toBe("chocolate cake,cheesecake,Pound cake,Persian love cake,Chocolate Cake,Cheesecake");
});

View File

@ -102,6 +102,25 @@ function runTests(wiki,wikiOptions) {
expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler");
});
it("should apply identical tag ordering irrespective of tag creation order", function () {
var wiki;
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
wiki = new $tw.Wiki(wikiOptions);
wiki.addTiddler({ title: "C", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "B", text: "", tags: "sortTag"});
wiki.addTiddler({ title: "A", text: "", tags: "sortTag"});
expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C");
});
// Tests for issue (#3296)
it("should apply tag ordering in order of dependency", function () {
var wiki = new $tw.Wiki(wikiOptions);

View File

@ -169,6 +169,16 @@ describe("Utility tests", function() {
expect(cv("1.1.1","1.1.2")).toEqual(-1);
});
it("should insert strings into sorted arrays", function() {
expect($tw.utils.insertSortedArray([],"a").join(",")).toEqual("a");
expect($tw.utils.insertSortedArray(["b","c","d"],"a").join(",")).toEqual("a,b,c,d");
expect($tw.utils.insertSortedArray(["b","c","d"],"d").join(",")).toEqual("b,c,d");
expect($tw.utils.insertSortedArray(["b","c","d"],"f").join(",")).toEqual("b,c,d,f");
expect($tw.utils.insertSortedArray(["b","c","d","e"],"f").join(",")).toEqual("b,c,d,e,f");
expect($tw.utils.insertSortedArray(["b","c","g"],"f").join(",")).toEqual("b,c,f,g");
expect($tw.utils.insertSortedArray(["b","c","d"],"ccc").join(",")).toEqual("b,c,ccc,d");
});
});
})();