mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Bug fixes and integration tests for cli
This commit is contained in:
parent
8c5f0622a2
commit
d1fecfde57
3
CliClient/.gitignore
vendored
3
CliClient/.gitignore
vendored
@ -11,4 +11,5 @@ tests/fuzzing/client2
|
||||
tests/fuzzing/sync
|
||||
tests/fuzzing.*
|
||||
tests/fuzzing -*
|
||||
tests/logs/*
|
||||
tests/logs/*
|
||||
tests/cli-integration/
|
179
CliClient/app/cli-integration-tests.js
Normal file
179
CliClient/app/cli-integration-tests.js
Normal file
@ -0,0 +1,179 @@
|
||||
"use strict"
|
||||
|
||||
require('source-map-support').install();
|
||||
require('babel-plugin-transform-runtime');
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import { Logger } from 'lib/logger.js';
|
||||
import { dirname } from 'lib/path-utils.js';
|
||||
import { DatabaseDriverNode } from 'lib/database-driver-node.js';
|
||||
import { JoplinDatabase } from 'lib/joplin-database.js';
|
||||
import { BaseModel } from 'lib/base-model.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { Setting } from 'lib/models/setting.js';
|
||||
import { sprintf } from 'sprintf-js';
|
||||
const exec = require('child_process').exec
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.error('Unhandled promise rejection', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
const baseDir = dirname(__dirname) + '/tests/cli-integration';
|
||||
const joplinAppPath = __dirname + '/main.js';
|
||||
|
||||
const logger = new Logger();
|
||||
logger.addTarget('console');
|
||||
logger.setLevel(Logger.LEVEL_ERROR);
|
||||
|
||||
const dbLogger = new Logger();
|
||||
dbLogger.addTarget('console');
|
||||
dbLogger.setLevel(Logger.LEVEL_INFO);
|
||||
|
||||
const db = new JoplinDatabase(new DatabaseDriverNode());
|
||||
db.setLogger(dbLogger);
|
||||
|
||||
function createClient(id) {
|
||||
return {
|
||||
'id': id,
|
||||
'profileDir': baseDir + '/client' + id,
|
||||
};
|
||||
}
|
||||
|
||||
const client = createClient(1);
|
||||
|
||||
function execCommand(client, command, options = {}) {
|
||||
let exePath = 'node ' + joplinAppPath;
|
||||
let cmd = exePath + ' --update-geolocation-disabled --env dev --profile ' + client.profileDir + ' ' + command;
|
||||
logger.info(client.id + ': ' + command);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(cmd, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
logger.error(stderr);
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(stdout.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function assertTrue(v) {
|
||||
if (!v) throw new Error(sprintf('Expected "true", got "%s"."', v));
|
||||
process.stdout.write('.');
|
||||
}
|
||||
|
||||
function assertFalse(v) {
|
||||
if (v) throw new Error(sprintf('Expected "false", got "%s"."', v));
|
||||
process.stdout.write('.');
|
||||
}
|
||||
|
||||
function assertEquals(expected, real) {
|
||||
if (expected !== real) throw new Error(sprintf('Expecting "%s", got "%s"', expected, real));
|
||||
process.stdout.write('.');
|
||||
}
|
||||
|
||||
async function clearDatabase() {
|
||||
await db.transactionExecBatch([
|
||||
'DELETE FROM folders',
|
||||
'DELETE FROM notes',
|
||||
'DELETE FROM tags',
|
||||
'DELETE FROM note_tags',
|
||||
'DELETE FROM resources',
|
||||
'DELETE FROM deleted_items',
|
||||
]);
|
||||
}
|
||||
|
||||
const testUnits = {};
|
||||
|
||||
testUnits.testFolders = async () => {
|
||||
await execCommand(client, 'mkbook nb1');
|
||||
|
||||
let folders = await Folder.all();
|
||||
assertEquals(1, folders.length);
|
||||
assertEquals('nb1', folders[0].title);
|
||||
|
||||
await execCommand(client, 'mkbook nb1');
|
||||
|
||||
folders = await Folder.all();
|
||||
assertEquals(1, folders.length);
|
||||
assertEquals('nb1', folders[0].title);
|
||||
|
||||
await execCommand(client, 'rm -r -f nb1');
|
||||
|
||||
folders = await Folder.all();
|
||||
assertEquals(0, folders.length);
|
||||
}
|
||||
|
||||
testUnits.testNotes = async () => {
|
||||
await execCommand(client, 'mkbook nb1');
|
||||
await execCommand(client, 'mknote n1');
|
||||
|
||||
let notes = await Note.all();
|
||||
assertEquals(1, notes.length);
|
||||
assertEquals('n1', notes[0].title);
|
||||
|
||||
await execCommand(client, 'rm -f n1');
|
||||
notes = await Note.all();
|
||||
assertEquals(0, notes.length);
|
||||
|
||||
await execCommand(client, 'mknote n1');
|
||||
await execCommand(client, 'mknote n2');
|
||||
|
||||
notes = await Note.all();
|
||||
assertEquals(2, notes.length);
|
||||
|
||||
await execCommand(client, "rm -f 'blabla*'");
|
||||
|
||||
notes = await Note.all();
|
||||
assertEquals(2, notes.length);
|
||||
|
||||
await execCommand(client, "rm -f 'n*'");
|
||||
|
||||
notes = await Note.all();
|
||||
assertEquals(0, notes.length);
|
||||
}
|
||||
|
||||
testUnits.testCat = async () => {
|
||||
await execCommand(client, 'mkbook nb1');
|
||||
await execCommand(client, 'mknote mynote');
|
||||
|
||||
let folder = await Folder.loadByTitle('nb1');
|
||||
let note = await Note.loadFolderNoteByField(folder.id, 'title', 'mynote');
|
||||
|
||||
let r = await execCommand(client, 'cat mynote');
|
||||
assertTrue(r.indexOf('mynote') >= 0);
|
||||
assertFalse(r.indexOf(note.id) >= 0);
|
||||
|
||||
r = await execCommand(client, 'cat -v mynote');
|
||||
assertTrue(r.indexOf(note.id) >= 0);
|
||||
}
|
||||
|
||||
async function main(argv) {
|
||||
await fs.remove(baseDir);
|
||||
|
||||
logger.info(await execCommand(client, 'version'));
|
||||
|
||||
await db.open({ name: client.profileDir + '/database.sqlite' });
|
||||
BaseModel.db_ = db;
|
||||
await Setting.load();
|
||||
|
||||
let onlyThisTest = 'testCat';
|
||||
onlyThisTest = '';
|
||||
|
||||
for (let n in testUnits) {
|
||||
if (!testUnits.hasOwnProperty(n)) continue;
|
||||
if (onlyThisTest && n != onlyThisTest) continue;
|
||||
|
||||
await clearDatabase();
|
||||
process.stdout.write(n + ': ');
|
||||
await testUnits[n]();
|
||||
console.info('');
|
||||
}
|
||||
}
|
||||
|
||||
main(process.argv).catch((error) => {
|
||||
console.info('');
|
||||
logger.error(error);
|
||||
});
|
@ -16,6 +16,12 @@ class Command extends BaseCommand {
|
||||
return 'Displays the given item data.';
|
||||
}
|
||||
|
||||
options() {
|
||||
return [
|
||||
['-v, --verbose', 'Shows complete information about note.'],
|
||||
];
|
||||
}
|
||||
|
||||
autocomplete() {
|
||||
return { data: autocompleteItems };
|
||||
}
|
||||
@ -26,7 +32,7 @@ class Command extends BaseCommand {
|
||||
let item = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||
if (!item) throw new Error(_('No item "%s" found.', title));
|
||||
|
||||
const content = await Note.serialize(item);
|
||||
const content = args.options.verbose ? await Note.serialize(item) : await Note.serializeForEdit(item);
|
||||
this.log(content);
|
||||
}
|
||||
|
||||
|
3
CliClient/cli-integration.sh
Executable file
3
CliClient/cli-integration.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
./build.sh && NODE_PATH="build/" node build/cli-integration-tests.js
|
@ -99,7 +99,7 @@ class Logger {
|
||||
for (let i = 0; i < this.targets_.length; i++) {
|
||||
let target = this.targets_[i];
|
||||
if (target.type == 'console') {
|
||||
let fn = 'debug';
|
||||
let fn = 'log';
|
||||
if (level == Logger.LEVEL_ERROR) fn = 'error';
|
||||
if (level == Logger.LEVEL_WARN) fn = 'warn';
|
||||
if (level == Logger.LEVEL_INFO) fn = 'info';
|
||||
|
@ -55,6 +55,7 @@ class Note extends BaseItem {
|
||||
}
|
||||
|
||||
static loadFolderNoteByField(folderId, field, value) {
|
||||
if (!folderId) throw new Error('folderId is undefined');
|
||||
return this.modelSelectOne('SELECT * FROM notes WHERE is_conflict = 0 AND `parent_id` = ? AND `' + field + '` = ?', [folderId, value]);
|
||||
}
|
||||
|
||||
@ -124,7 +125,7 @@ class Note extends BaseItem {
|
||||
|
||||
this.logger().info('Updating lat/long of note ' + noteId);
|
||||
|
||||
let note = Note.load(noteId);
|
||||
let note = await Note.load(noteId);
|
||||
if (!note) return; // Race condition - note has been deleted in the meantime
|
||||
|
||||
note.longitude = geoData.coords.longitude;
|
||||
|
Loading…
Reference in New Issue
Block a user