mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-02-20 04:50:03 +00:00
Checkbox widget should not affect date fields (#7448)
* Checkbox widget should not affect date fields If a date field like `created` or `modified` is passed as the listField attribute of the checkbox widget, it will be left unchanged and actions on the checkbox widget will *not* fire. Includes unit tests to ensure that the "created" and "modified" fields will not be touched by checkboxes and will continue to be Date objects. * Replace const with var in checkbox tests
This commit is contained in:
parent
576d476a21
commit
fb10b1ee91
@ -112,7 +112,7 @@ CheckboxWidget.prototype.getValue = function() {
|
|||||||
var list;
|
var list;
|
||||||
if(this.checkboxListField) {
|
if(this.checkboxListField) {
|
||||||
if($tw.utils.hop(tiddler.fields,this.checkboxListField)) {
|
if($tw.utils.hop(tiddler.fields,this.checkboxListField)) {
|
||||||
list = tiddler.getFieldList(this.checkboxListField);
|
list = tiddler.getFieldList(this.checkboxListField) || [];
|
||||||
} else {
|
} else {
|
||||||
list = $tw.utils.parseStringArray(this.checkboxDefault || "") || [];
|
list = $tw.utils.parseStringArray(this.checkboxDefault || "") || [];
|
||||||
}
|
}
|
||||||
@ -208,16 +208,20 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
|
|||||||
if(this.checkboxListField || this.checkboxListIndex) {
|
if(this.checkboxListField || this.checkboxListIndex) {
|
||||||
var fieldContents, listContents, oldPos, newPos;
|
var fieldContents, listContents, oldPos, newPos;
|
||||||
if(this.checkboxListField) {
|
if(this.checkboxListField) {
|
||||||
fieldContents = tiddler ? tiddler.fields[this.checkboxListField] : undefined;
|
fieldContents = (tiddler ? tiddler.fields[this.checkboxListField] : undefined) || [];
|
||||||
} else {
|
} else {
|
||||||
fieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex);
|
fieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex);
|
||||||
}
|
}
|
||||||
if($tw.utils.isArray(fieldContents)) {
|
if($tw.utils.isArray(fieldContents)) {
|
||||||
// Make a copy so we can modify it without changing original that's refrenced elsewhere
|
// Make a copy so we can modify it without changing original that's refrenced elsewhere
|
||||||
listContents = fieldContents.slice(0);
|
listContents = fieldContents.slice(0);
|
||||||
} else {
|
} else if(typeof fieldContents === "string") {
|
||||||
listContents = $tw.utils.parseStringArray(fieldContents) || [];
|
listContents = $tw.utils.parseStringArray(fieldContents);
|
||||||
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
|
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
|
||||||
|
} else {
|
||||||
|
// Field was neither an array nor a string; it's probably something that shouldn't become
|
||||||
|
// an array (such as a date field), so bail out *without* triggering actions
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
oldPos = notValue ? listContents.indexOf(notValue) : -1;
|
oldPos = notValue ? listContents.indexOf(notValue) : -1;
|
||||||
newPos = value ? listContents.indexOf(value) : -1;
|
newPos = value ? listContents.indexOf(value) : -1;
|
||||||
|
@ -56,7 +56,7 @@ Tests the checkbox widget thoroughly.
|
|||||||
* Test data for checkbox widget tests
|
* Test data for checkbox widget tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fieldModeTests = [
|
var fieldModeTests = [
|
||||||
{
|
{
|
||||||
testName: "field mode checked",
|
testName: "field mode checked",
|
||||||
tiddlers: [{title: "TiddlerOne", text: "Jolly Old World", expand: "yes"}],
|
tiddlers: [{title: "TiddlerOne", text: "Jolly Old World", expand: "yes"}],
|
||||||
@ -95,16 +95,16 @@ Tests the checkbox widget thoroughly.
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const indexModeTests = fieldModeTests.map(data => {
|
var indexModeTests = fieldModeTests.map(data => {
|
||||||
const newData = {...data};
|
var newData = {...data};
|
||||||
const newName = data.testName.replace('field mode', 'index mode');
|
var newName = data.testName.replace('field mode', 'index mode');
|
||||||
const newTiddlers = data.tiddlers.map(tiddler => {
|
var newTiddlers = data.tiddlers.map(tiddler => {
|
||||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nexpand: ${tiddler.expand}\ntwo: b`}
|
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nexpand: ${tiddler.expand}\ntwo: b`}
|
||||||
});
|
});
|
||||||
const newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
|
var newWidgetText = data.widgetText.replace("field='expand'", "index='expand'");
|
||||||
const newChange = {};
|
var newChange = {};
|
||||||
for (const key of Object.keys(data.expectedChange)) {
|
for (var key of Object.keys(data.expectedChange)) {
|
||||||
const oldChange = data.expectedChange[key];
|
var oldChange = data.expectedChange[key];
|
||||||
if (oldChange.expand) {
|
if (oldChange.expand) {
|
||||||
newChange[key] = { text: `one: a\nexpand: ${oldChange.expand}\ntwo: b` }
|
newChange[key] = { text: `one: a\nexpand: ${oldChange.expand}\ntwo: b` }
|
||||||
} else {
|
} else {
|
||||||
@ -119,7 +119,26 @@ Tests the checkbox widget thoroughly.
|
|||||||
return newData;
|
return newData;
|
||||||
});
|
});
|
||||||
|
|
||||||
const listModeTests = [
|
var listModeTestsForDateFields = [
|
||||||
|
{
|
||||||
|
testName: "list mode created date field",
|
||||||
|
tiddlers: [{title: "Colors", created: "201304152222", modified: "202301022222"}],
|
||||||
|
widgetText: "<$checkbox tiddler='Colors' listField='created' checked='green' />",
|
||||||
|
startsOutChecked: false,
|
||||||
|
finalValue: false,
|
||||||
|
expectedChange: { "Colors": { created: new Date("2013-04-15T22:22:00Z")}} // created field should *not* be touched by a listField checkbox
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "list mode modified date field",
|
||||||
|
tiddlers: [{title: "Colors", created: "201304152222", modified: "202301022222"}],
|
||||||
|
widgetText: "<$checkbox tiddler='Colors' listField='modified' checked='green' />",
|
||||||
|
startsOutChecked: false,
|
||||||
|
finalValue: false,
|
||||||
|
expectedChange: { "Colors": { modified: new Date("2023-01-02T22:22:00Z")}} // modified field should *not* be touched by a listField checkbox
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
var listModeTests = [
|
||||||
{
|
{
|
||||||
testName: "list mode add",
|
testName: "list mode add",
|
||||||
tiddlers: [{title: "Colors", colors: "orange yellow"}],
|
tiddlers: [{title: "Colors", colors: "orange yellow"}],
|
||||||
@ -235,11 +254,11 @@ Tests the checkbox widget thoroughly.
|
|||||||
];
|
];
|
||||||
|
|
||||||
// https://github.com/Jermolene/TiddlyWiki5/issues/6871
|
// https://github.com/Jermolene/TiddlyWiki5/issues/6871
|
||||||
const listModeTestsWithListField = (
|
var listModeTestsWithListField = (
|
||||||
listModeTests
|
listModeTests
|
||||||
.filter(data => data.widgetText.includes("listField='colors'"))
|
.filter(data => data.widgetText.includes("listField='colors'"))
|
||||||
.map(data => {
|
.map(data => {
|
||||||
const newData = {
|
var newData = {
|
||||||
...data,
|
...data,
|
||||||
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, list: tiddler.colors, colors: undefined})),
|
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, list: tiddler.colors, colors: undefined})),
|
||||||
widgetText: data.widgetText.replace("listField='colors'", "listField='list'"),
|
widgetText: data.widgetText.replace("listField='colors'", "listField='list'"),
|
||||||
@ -250,11 +269,11 @@ Tests the checkbox widget thoroughly.
|
|||||||
return newData;
|
return newData;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const listModeTestsWithTagsField = (
|
var listModeTestsWithTagsField = (
|
||||||
listModeTests
|
listModeTests
|
||||||
.filter(data => data.widgetText.includes("listField='colors'"))
|
.filter(data => data.widgetText.includes("listField='colors'"))
|
||||||
.map(data => {
|
.map(data => {
|
||||||
const newData = {
|
var newData = {
|
||||||
...data,
|
...data,
|
||||||
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, tags: tiddler.colors, colors: undefined})),
|
tiddlers: data.tiddlers.map(tiddler => ({...tiddler, tags: tiddler.colors, colors: undefined})),
|
||||||
widgetText: data.widgetText.replace("listField='colors'", "listField='tags'"),
|
widgetText: data.widgetText.replace("listField='colors'", "listField='tags'"),
|
||||||
@ -266,20 +285,20 @@ Tests the checkbox widget thoroughly.
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const indexListModeTests = listModeTests.map(data => {
|
var indexListModeTests = listModeTests.map(data => {
|
||||||
const newData = {...data};
|
var newData = {...data};
|
||||||
const newName = data.testName.replace('list mode', 'index list mode');
|
var newName = data.testName.replace('list mode', 'index list mode');
|
||||||
const newTiddlers = data.tiddlers.map(tiddler => {
|
var newTiddlers = data.tiddlers.map(tiddler => {
|
||||||
if (tiddler.hasOwnProperty('colors')) {
|
if (tiddler.hasOwnProperty('colors')) {
|
||||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\ncolors: ${tiddler.colors}\ntwo: b`}
|
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\ncolors: ${tiddler.colors}\ntwo: b`}
|
||||||
} else if (tiddler.hasOwnProperty('someField')) {
|
} else if (tiddler.hasOwnProperty('someField')) {
|
||||||
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nsomeField: ${tiddler.someField}\ntwo: b`}
|
return {title: tiddler.title, type: "application/x-tiddler-dictionary", text: `one: a\nsomeField: ${tiddler.someField}\ntwo: b`}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const newWidgetText = data.widgetText.replace("listField='colors'", "listIndex='colors'").replace(/\$field/g, '$index').replace("listField='someField'", "listIndex='someField'");
|
var newWidgetText = data.widgetText.replace("listField='colors'", "listIndex='colors'").replace(/\$field/g, '$index').replace("listField='someField'", "listIndex='someField'");
|
||||||
const newChange = {};
|
var newChange = {};
|
||||||
for (const key of Object.keys(data.expectedChange)) {
|
for (var key of Object.keys(data.expectedChange)) {
|
||||||
const oldChange = data.expectedChange[key];
|
var oldChange = data.expectedChange[key];
|
||||||
if (oldChange.colors) {
|
if (oldChange.colors) {
|
||||||
newChange[key] = { text: `one: a\ncolors: ${oldChange.colors}\ntwo: b` }
|
newChange[key] = { text: `one: a\ncolors: ${oldChange.colors}\ntwo: b` }
|
||||||
} else if (oldChange.someField !== undefined) {
|
} else if (oldChange.someField !== undefined) {
|
||||||
@ -296,7 +315,7 @@ Tests the checkbox widget thoroughly.
|
|||||||
return newData;
|
return newData;
|
||||||
});
|
});
|
||||||
|
|
||||||
const filterModeTests = [
|
var filterModeTests = [
|
||||||
{
|
{
|
||||||
testName: "filter mode false -> true",
|
testName: "filter mode false -> true",
|
||||||
tiddlers: [{title: "Colors", colors: "red orange yellow"}],
|
tiddlers: [{title: "Colors", colors: "red orange yellow"}],
|
||||||
@ -482,9 +501,10 @@ Tests the checkbox widget thoroughly.
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const checkboxTestData = fieldModeTests.concat(
|
var checkboxTestData = fieldModeTests.concat(
|
||||||
indexModeTests,
|
indexModeTests,
|
||||||
listModeTests,
|
listModeTests,
|
||||||
|
listModeTestsForDateFields,
|
||||||
listModeTestsWithListField,
|
listModeTestsWithListField,
|
||||||
listModeTestsWithTagsField,
|
listModeTestsWithTagsField,
|
||||||
indexListModeTests,
|
indexListModeTests,
|
||||||
@ -494,7 +514,7 @@ Tests the checkbox widget thoroughly.
|
|||||||
/*
|
/*
|
||||||
* Checkbox widget tests using the test data above
|
* Checkbox widget tests using the test data above
|
||||||
*/
|
*/
|
||||||
for (const data of checkboxTestData) {
|
for (var data of checkboxTestData) {
|
||||||
it('checkbox widget test: ' + data.testName, function() {
|
it('checkbox widget test: ' + data.testName, function() {
|
||||||
// Setup
|
// Setup
|
||||||
|
|
||||||
@ -505,7 +525,7 @@ Tests the checkbox widget thoroughly.
|
|||||||
|
|
||||||
// Check initial state
|
// Check initial state
|
||||||
|
|
||||||
const widget = findNodeOfType('checkbox', widgetNode);
|
var widget = findNodeOfType('checkbox', widgetNode);
|
||||||
// Verify that the widget is or is not checked as expected
|
// Verify that the widget is or is not checked as expected
|
||||||
expect(widget.getValue()).toBe(data.startsOutChecked);
|
expect(widget.getValue()).toBe(data.startsOutChecked);
|
||||||
|
|
||||||
@ -519,16 +539,16 @@ Tests the checkbox widget thoroughly.
|
|||||||
widget.handleChangeEvent(null);
|
widget.handleChangeEvent(null);
|
||||||
|
|
||||||
// Check state again: in most tests, checkbox should be inverse of what it was
|
// Check state again: in most tests, checkbox should be inverse of what it was
|
||||||
const finalValue = data.hasOwnProperty('finalValue') ? data.finalValue : !data.startsOutChecked;
|
var finalValue = data.hasOwnProperty('finalValue') ? data.finalValue : !data.startsOutChecked;
|
||||||
expect(widget.getValue()).toBe(finalValue);
|
expect(widget.getValue()).toBe(finalValue);
|
||||||
|
|
||||||
// Check that tiddler(s) has/have gone through expected change(s)
|
// Check that tiddler(s) has/have gone through expected change(s)
|
||||||
for (const key of Object.keys(data.expectedChange)) {
|
for (var key of Object.keys(data.expectedChange)) {
|
||||||
const tiddler = wiki.getTiddler(key);
|
var tiddler = wiki.getTiddler(key);
|
||||||
const change = data.expectedChange[key];
|
var change = data.expectedChange[key];
|
||||||
for (const fieldName of Object.keys(change)) {
|
for (var fieldName of Object.keys(change)) {
|
||||||
const expectedValue = change[fieldName];
|
var expectedValue = change[fieldName];
|
||||||
const fieldValue = tiddler.fields[fieldName];
|
var fieldValue = tiddler.fields[fieldName];
|
||||||
expect(fieldValue).toEqual(expectedValue);
|
expect(fieldValue).toEqual(expectedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user