tests for note properties

This commit is contained in:
zadam 2020-05-23 20:52:55 +02:00
parent bb03a8714a
commit a2e1fb35b8
5 changed files with 151 additions and 4 deletions

View File

@ -312,6 +312,84 @@ describe("Search", () => {
expect(findNoteByTitle(searchResults, "Czech Republic")).toBeTruthy();
expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy();
});
it("test note properties", async () => {
const austria = note("Austria");
austria.relation('myself', austria.note);
austria.label('capital', 'Vienna');
austria.label('population', '8859000');
rootNote
.child(note("Asia"))
.child(note("Europe")
.child(austria
.child(note("Vienna"))
.child(note("Sebastian Kurz"))
)
)
.child(note("Mozart")
.child(austria));
austria.note.type = 'text';
austria.note.mime = 'text/html';
austria.note.isProtected = false;
austria.note.dateCreated = '2020-05-14 12:11:42.001+0200';
austria.note.dateModified = '2020-05-14 13:11:42.001+0200';
austria.note.utcDateCreated = '2020-05-14 10:11:42.001Z';
austria.note.utcDateModified = '2020-05-14 11:11:42.001Z';
austria.note.contentLength = 1001;
const parsingContext = new ParsingContext();
async function test(propertyName, value, expectedResultCount) {
const searchResults = await searchService.findNotesWithQuery(`# note.${propertyName} = ${value}`, parsingContext);
expect(searchResults.length).toEqual(expectedResultCount);
if (expectedResultCount === 1) {
expect(findNoteByTitle(searchResults, "Austria")).toBeTruthy();
}
}
await test("type", "text", 1);
await test("type", "code", 0);
await test("mime", "text/html", 1);
await test("mime", "application/json", 0);
await test("isProtected", "false", 7);
await test("isProtected", "true", 0);
await test("dateCreated", "'2020-05-14 12:11:42.001+0200'", 1);
await test("dateCreated", "wrong", 0);
await test("dateModified", "'2020-05-14 13:11:42.001+0200'", 1);
await test("dateModified", "wrong", 0);
await test("utcDateCreated", "'2020-05-14 10:11:42.001Z'", 1);
await test("utcDateCreated", "wrong", 0);
await test("utcDateModified", "'2020-05-14 11:11:42.001Z'", 1);
await test("utcDateModified", "wrong", 0);
await test("contentLength", "1001", 1);
await test("contentLength", "10010", 0);
await test("parentCount", "2", 1);
await test("parentCount", "3", 0);
await test("childrenCount", "2", 1);
await test("childrenCount", "10", 0);
await test("attributeCount", "3", 1);
await test("attributeCount", "4", 0);
await test("labelCount", "2", 1);
await test("labelCount", "3", 0);
await test("relationCount", "1", 1);
await test("relationCount", "2", 0);
})
});
/** @return {Note} */

View File

@ -10,6 +10,20 @@ class Note {
this.noteId = row.noteId;
/** @param {string} */
this.title = row.title;
/** @param {string} */
this.type = row.type;
/** @param {string} */
this.mime = row.mime;
/** @param {number} */
this.contentLength = row.contentLength;
/** @param {string} */
this.dateCreated = row.dateCreated;
/** @param {string} */
this.dateModified = row.dateModified;
/** @param {string} */
this.utcDateCreated = row.utcDateCreated;
/** @param {string} */
this.utcDateModified = row.utcDateModified;
/** @param {boolean} */
this.isProtected = !!row.isProtected;
/** @param {boolean} */
@ -224,6 +238,26 @@ class Note {
return arr.flat();
}
get parentCount() {
return this.parents.length;
}
get childrenCount() {
return this.children.length;
}
get labelCount() {
return this.attributes.filter(attr => attr.type === 'label').length;
}
get relationCount() {
return this.attributes.filter(attr => attr.type === 'relation').length;
}
get attributeCount() {
return this.attributes.length;
}
/** @return {Note[]} - returns only notes which are templated, does not include their subtrees
* in effect returns notes which are influenced by note's non-inheritable attributes */
get templatedNotes() {

View File

@ -13,7 +13,7 @@ async function load() {
noteCache.reset();
(await sql.getRows(`SELECT noteId, title, isProtected FROM notes WHERE isDeleted = 0`, []))
(await sql.getRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified, contentLength FROM notes WHERE isDeleted = 0`, []))
.map(row => new Note(noteCache, row));
(await sql.getRows(`SELECT branchId, noteId, parentNoteId, prefix FROM branches WHERE isDeleted = 0`, []))

View File

@ -3,11 +3,37 @@
const Expression = require('./expression');
const NoteSet = require('../note_set');
/**
* Search string is lower cased for case insensitive comparison. But when retrieving properties
* we need case sensitive form so we have this translation object.
*/
const PROP_MAPPING = {
"noteid": "noteId",
"title": "title",
"type": "type",
"mime": "mime",
"isprotected": "isProtected",
"datecreated": "dateCreated",
"datemodified": "dateModified",
"utcdatecreated": "utcDateCreated",
"utcdatemodified": "utcDateModified",
"contentlength": "contentLength",
"parentcount": "parentCount",
"childrencount": "childrenCount",
"attributecount": "attributeCount",
"labelcount": "labelCount",
"relationcount": "relationCount"
};
class PropertyComparisonExp extends Expression {
static isProperty(name) {
return name in PROP_MAPPING;
}
constructor(propertyName, comparator) {
super();
this.propertyName = propertyName;
this.propertyName = PROP_MAPPING[propertyName];
this.comparator = comparator;
}
@ -15,8 +41,15 @@ class PropertyComparisonExp extends Expression {
const resNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
const value = note[this.propertyName].toLowerCase();
let value = note[this.propertyName];
if (value !== undefined && value !== null && typeof value !== 'string') {
value = value.toString();
}
if (value) {
value = value.toLowerCase();
}
if (this.comparator(value)) {
resNoteSet.add(note);
}

View File

@ -86,7 +86,7 @@ function getExpression(tokens, parsingContext) {
return parseRelation(tokens[i]);
}
if (tokens[i] === 'title') {
if (PropertyComparisonExp.isProperty(tokens[i])) {
const propertyName = tokens[i];
const operator = tokens[i + 1];
const comparedValue = tokens[i + 2];
@ -101,6 +101,8 @@ function getExpression(tokens, parsingContext) {
return new PropertyComparisonExp(propertyName, comparator);
}
parsingContext.addError(`Unrecognized note property "${tokens[i]}"`);
}
function parseLabel(labelName) {