mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
Tools: Replace Jasmine with Jest to run tests
This commit is contained in:
parent
c249333e2a
commit
06f2fda946
@ -169,9 +169,6 @@ packages/app-cli/tests/fsDriver.js.map
|
|||||||
packages/app-cli/tests/models_Setting.d.ts
|
packages/app-cli/tests/models_Setting.d.ts
|
||||||
packages/app-cli/tests/models_Setting.js
|
packages/app-cli/tests/models_Setting.js
|
||||||
packages/app-cli/tests/models_Setting.js.map
|
packages/app-cli/tests/models_Setting.js.map
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.d.ts
|
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.js
|
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.js.map
|
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -161,9 +161,6 @@ packages/app-cli/tests/fsDriver.js.map
|
|||||||
packages/app-cli/tests/models_Setting.d.ts
|
packages/app-cli/tests/models_Setting.d.ts
|
||||||
packages/app-cli/tests/models_Setting.js
|
packages/app-cli/tests/models_Setting.js
|
||||||
packages/app-cli/tests/models_Setting.js.map
|
packages/app-cli/tests/models_Setting.js.map
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.d.ts
|
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.js
|
|
||||||
packages/app-cli/tests/services/plugins/api/JoplinSetting.js.map
|
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
packages/app-cli/tests/services/plugins/sandboxProxy.js
|
||||||
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
|
||||||
|
@ -66,13 +66,11 @@ script:
|
|||||||
# Only do it for pull requests because Travis randomly fails to run them
|
# Only do it for pull requests because Travis randomly fails to run them
|
||||||
# and that would break the desktop release.
|
# and that would break the desktop release.
|
||||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||||
cd packages/app-cli
|
|
||||||
npm run test-ci
|
npm run test-ci
|
||||||
testResult=$?
|
testResult=$?
|
||||||
if [ $testResult -ne 0 ]; then
|
if [ $testResult -ne 0 ]; then
|
||||||
exit $testResult
|
exit $testResult
|
||||||
fi
|
fi
|
||||||
cd ../..
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run linter for pull requests only - this is so that
|
# Run linter for pull requests only - this is so that
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
"releaseDesktop": "node packages/tools/release-electron.js",
|
"releaseDesktop": "node packages/tools/release-electron.js",
|
||||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||||
"tsc": "lerna run tsc --stream --parallel",
|
"tsc": "lerna run tsc --stream --parallel",
|
||||||
|
"test": "lerna run test --stream",
|
||||||
|
"test-ci": "lerna run test-ci --stream",
|
||||||
"updateIgnored": "gulp updateIgnoredTypeScriptBuild",
|
"updateIgnored": "gulp updateIgnoredTypeScriptBuild",
|
||||||
"watch": "lerna run watch --stream --parallel"
|
"watch": "lerna run watch --stream --parallel"
|
||||||
},
|
},
|
||||||
|
46
packages/app-cli/jest.config.js
Normal file
46
packages/app-cli/jest.config.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
module.exports = {
|
||||||
|
testMatch: [
|
||||||
|
'**/tests/**/*.js',
|
||||||
|
// '**/tests/services_keychainService.js',
|
||||||
|
// '**/tests/urlUtils.js',
|
||||||
|
// '**/tests/models_BaseItem.js',
|
||||||
|
// '**/tests/markdownUtils.js',
|
||||||
|
// '**/tests/models_Resource.js',
|
||||||
|
],
|
||||||
|
testPathIgnorePatterns: [
|
||||||
|
'/node_modules/',
|
||||||
|
'tests/support/',
|
||||||
|
'test-utils.js',
|
||||||
|
'file_api_driver.js',
|
||||||
|
],
|
||||||
|
testEnvironment: 'node',
|
||||||
|
setupFilesAfterEnv: ['./jest.setup.js'],
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// PASS tests/services_rest_Api.js (14.705 s)
|
||||||
|
// PASS tests/services_SearchFilter.js (21.203 s)
|
||||||
|
// PASS tests/services_InteropService.js (10.807 s)
|
||||||
|
// PASS tests/reducer.js (17.398 s)
|
||||||
|
// PASS tests/services_Revision.js (17.642 s)
|
||||||
|
// PASS tests/feature_NoteHistory.js (31.448 s)
|
||||||
|
// PASS tests/services_KeymapService.js
|
||||||
|
// PASS tests/services_EncryptionService.js (9.258 s)
|
||||||
|
// PASS tests/models_Note.js (10.59 s)
|
||||||
|
// PASS tests/services_ResourceService.js (13.177 s)
|
||||||
|
// PASS tests/models_Folder.js (11.468 s)
|
||||||
|
// PASS tests/MdToHtml.js (5.242 s)
|
||||||
|
// PASS tests/services_PluginService.js (5.456 s)
|
||||||
|
// PASS tests/models_Note_CustomSortOrder.js (5.52 s)
|
||||||
|
// PASS tests/feature_ShowAllNotes.js (13.567 s)
|
||||||
|
// PASS tests/models_Setting.js
|
||||||
|
// PASS tests/models_Tag.js (6.324 s)
|
||||||
|
// PASS tests/services_keychainService.js
|
||||||
|
// PASS tests/urlUtils.js
|
||||||
|
// PASS tests/models_BaseItem.js
|
||||||
|
// PASS tests/markdownUtils.js
|
||||||
|
// (node:15679) UnhandledPromiseRejectionWarning: Error: {"title":"folder1"}: Fields have not been loaded yet
|
||||||
|
// (node:15679) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To termi$ate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 31)
|
||||||
|
// (node:15679) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
|
||||||
|
// FAIL tests/models_Resource.js
|
5
packages/app-cli/jest.setup.js
Normal file
5
packages/app-cli/jest.setup.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const { afterEachCleanUp } = require('./tests/test-utils.js');
|
||||||
|
|
||||||
|
global.afterEach(async () => {
|
||||||
|
await afterEachCleanUp();
|
||||||
|
});
|
3955
packages/app-cli/package-lock.json
generated
3955
packages/app-cli/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@
|
|||||||
"author": "Laurent Cozic",
|
"author": "Laurent Cozic",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node node_modules/jasmine/bin/jasmine.js --fail-fast=true --config=tests/support/jasmine.json",
|
"test": "jest --config=jest.config.js --runInBand --bail --verbose --forceExit",
|
||||||
"test-ci": "node node_modules/jasmine/bin/jasmine.js --config=tests/support/jasmine.json",
|
"test-ci": "jest --config=jest.config.js --runInBand --forceExit",
|
||||||
"build": "gulp build",
|
"build": "gulp build",
|
||||||
"start": "gulp build -L && node \"build/main.js\" --stack-trace-enabled --log-level debug --env dev",
|
"start": "gulp build -L && node \"build/main.js\" --stack-trace-enabled --log-level debug --env dev",
|
||||||
"tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json",
|
"tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json",
|
||||||
@ -69,6 +69,7 @@
|
|||||||
"@types/node": "^14.14.6",
|
"@types/node": "^14.14.6",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"jasmine": "^3.5.0",
|
"jasmine": "^3.5.0",
|
||||||
|
"jest": "^26.6.3",
|
||||||
"temp": "^0.9.1",
|
"temp": "^0.9.1",
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@ process.on('unhandledRejection', (reason, p) => {
|
|||||||
|
|
||||||
const api = null;
|
const api = null;
|
||||||
|
|
||||||
|
// Adding empty test for Jest
|
||||||
|
it('will pass', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
// NOTE: These tests work with S3 and memory driver, but not
|
// NOTE: These tests work with S3 and memory driver, but not
|
||||||
// with other targets like file system or Nextcloud.
|
// with other targets like file system or Nextcloud.
|
||||||
// All this is tested in an indirect way in tests/synchronizer
|
// All this is tested in an indirect way in tests/synchronizer
|
||||||
|
@ -12,125 +12,125 @@ const makeTerm = (name, value, negated, quoted = false, wildcard = false) => {
|
|||||||
describe('filterParser should be correct filter for keyword', () => {
|
describe('filterParser should be correct filter for keyword', () => {
|
||||||
it('title', () => {
|
it('title', () => {
|
||||||
const searchString = 'title: something';
|
const searchString = 'title: something';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'something', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'something', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('negated title', () => {
|
it('negated title', () => {
|
||||||
const searchString = '-title: something';
|
const searchString = '-title: something';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'something', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'something', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('body', () => {
|
it('body', () => {
|
||||||
const searchString = 'body:something';
|
const searchString = 'body:something';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'something', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'something', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('negated body', () => {
|
it('negated body', () => {
|
||||||
const searchString = '-body:something';
|
const searchString = '-body:something';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'something', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'something', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('title and body', () => {
|
it('title and body', () => {
|
||||||
const searchString = 'title:testTitle body:testBody';
|
const searchString = 'title:testTitle body:testBody';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'testTitle', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'testTitle', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'testBody', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'testBody', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('title with multiple words', () => {
|
it('title with multiple words', () => {
|
||||||
const searchString = 'title:"word1 word2" body:testBody';
|
const searchString = 'title:"word1 word2" body:testBody';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'word1', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'word1', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'word2', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'word2', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'testBody', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'testBody', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('body with multiple words', () => {
|
it('body with multiple words', () => {
|
||||||
const searchString = 'title:testTitle body:"word1 word2"';
|
const searchString = 'title:testTitle body:"word1 word2"';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('title', 'testTitle', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('title', 'testTitle', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'word1', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'word1', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'word2', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'word2', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('single word text', () => {
|
it('single word text', () => {
|
||||||
const searchString = 'joplin';
|
const searchString = 'joplin';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"joplin"', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"joplin"', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi word text', () => {
|
it('multi word text', () => {
|
||||||
const searchString = 'scott joplin';
|
const searchString = 'scott joplin';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"scott"', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"scott"', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"joplin"', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"joplin"', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('negated word text', () => {
|
it('negated word text', () => {
|
||||||
const searchString = 'scott -joplin';
|
const searchString = 'scott -joplin';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"scott"', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"scott"', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"joplin"', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"joplin"', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('phrase text search', () => {
|
it('phrase text search', () => {
|
||||||
const searchString = '"scott joplin"';
|
const searchString = '"scott joplin"';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('text', '"scott joplin"', false, true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('text', '"scott joplin"', false, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multi word body', () => {
|
it('multi word body', () => {
|
||||||
const searchString = 'body:"foo bar"';
|
const searchString = 'body:"foo bar"';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'foo', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'foo', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('body', 'bar', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('body', 'bar', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('negated tag queries', () => {
|
it('negated tag queries', () => {
|
||||||
const searchString = '-tag:mozart';
|
const searchString = '-tag:mozart';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', 'mozart', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', 'mozart', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('created after', () => {
|
it('created after', () => {
|
||||||
const searchString = 'created:20151218'; // YYYYMMDD
|
const searchString = 'created:20151218'; // YYYYMMDD
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('created', '20151218', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('created', '20151218', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('created before', () => {
|
it('created before', () => {
|
||||||
const searchString = '-created:20151218'; // YYYYMMDD
|
const searchString = '-created:20151218'; // YYYYMMDD
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('created', '20151218', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('created', '20151218', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('any', () => {
|
it('any', () => {
|
||||||
const searchString = 'any:1 tag:123';
|
const searchString = 'any:1 tag:123';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('any', '1', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('any', '1', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', '123', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', '123', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wildcard tags', () => {
|
it('wildcard tags', () => {
|
||||||
let searchString = 'tag:*';
|
let searchString = 'tag:*';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', '%', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', '%', false));
|
||||||
|
|
||||||
searchString = '-tag:*';
|
searchString = '-tag:*';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', '%', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', '%', true));
|
||||||
|
|
||||||
searchString = 'tag:bl*sphemy';
|
searchString = 'tag:bl*sphemy';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', 'bl%sphemy', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', 'bl%sphemy', false));
|
||||||
|
|
||||||
searchString = 'tag:"space travel"';
|
searchString = 'tag:"space travel"';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('tag', 'space travel', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('tag', 'space travel', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wildcard notebooks', () => {
|
it('wildcard notebooks', () => {
|
||||||
const searchString = 'notebook:my*notebook';
|
const searchString = 'notebook:my*notebook';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('notebook', 'my%notebook', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('notebook', 'my%notebook', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wildcard MIME types', () => {
|
it('wildcard MIME types', () => {
|
||||||
const searchString = 'resource:image/*';
|
const searchString = 'resource:image/*';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('resource', 'image/%', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('resource', 'image/%', false));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sourceurl', () => {
|
it('sourceurl', () => {
|
||||||
let searchString = 'sourceurl:https://www.google.com';
|
let searchString = 'sourceurl:https://www.google.com';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('sourceurl', 'https://www.google.com', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('sourceurl', 'https://www.google.com', false));
|
||||||
|
|
||||||
searchString = 'sourceurl:https://www.google.com -sourceurl:https://www.facebook.com';
|
searchString = 'sourceurl:https://www.google.com -sourceurl:https://www.facebook.com';
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('sourceurl', 'https://www.google.com', false));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('sourceurl', 'https://www.google.com', false));
|
||||||
expect(filterParser(searchString)).toContain(makeTerm('sourceurl', 'https://www.facebook.com', true));
|
expect(filterParser(searchString)).toContainEqual(makeTerm('sourceurl', 'https://www.facebook.com', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handle invalid filters', () => {
|
it('handle invalid filters', () => {
|
||||||
|
@ -5,7 +5,7 @@ const { asyncTest } = require('./test-utils.js');
|
|||||||
const markdownUtils = require('@joplin/lib/markdownUtils').default;
|
const markdownUtils = require('@joplin/lib/markdownUtils').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at markdownUtils: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('markdownUtils', function() {
|
describe('markdownUtils', function() {
|
||||||
|
@ -11,7 +11,7 @@ const BaseModel = require('@joplin/lib/BaseModel').default;
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_BaseItem: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function allItems() {
|
async function allItems() {
|
||||||
|
@ -9,7 +9,7 @@ const BaseModel = require('@joplin/lib/BaseModel').default;
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_Folder: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function allItems() {
|
async function allItems() {
|
||||||
|
@ -11,7 +11,7 @@ const ArrayUtils = require('@joplin/lib/ArrayUtils.js');
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_Note: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function allItems() {
|
async function allItems() {
|
||||||
|
@ -11,7 +11,7 @@ const ArrayUtils = require('@joplin/lib/ArrayUtils.js');
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_Note_CustomSortOrder: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function allItems() {
|
async function allItems() {
|
||||||
|
@ -3,7 +3,7 @@ import Setting from '@joplin/lib/models/Setting';
|
|||||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_Setting: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('models_Setting', function() {
|
describe('models_Setting', function() {
|
||||||
|
@ -11,7 +11,7 @@ const BaseModel = require('@joplin/lib/BaseModel').default;
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at models_Tag: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('models_Tag', function() {
|
describe('models_Tag', function() {
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// import Setting from '@joplin/lib/models/Setting';
|
|
||||||
|
|
||||||
// const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('../test-utils.js');
|
|
||||||
|
|
||||||
// describe('plugin_api_JoplinSetting', function() {
|
|
||||||
|
|
||||||
// beforeEach(async (done) => {
|
|
||||||
// await setupDatabaseAndSynchronizer(1);
|
|
||||||
// await switchClient(1);
|
|
||||||
// done();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should get and set plugin-specific values', asyncTest(async () => {
|
|
||||||
// await
|
|
||||||
// }));
|
|
||||||
// });
|
|
@ -1,6 +1,7 @@
|
|||||||
import MenuUtils from '@joplin/lib/services/commands/MenuUtils';
|
import MenuUtils from '@joplin/lib/services/commands/MenuUtils';
|
||||||
import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||||
import CommandService, { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
|
import CommandService, { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
|
||||||
|
import KeymapService from '@joplin/lib/services/KeymapService';
|
||||||
|
|
||||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
||||||
|
|
||||||
@ -42,6 +43,9 @@ function registerCommand(service:CommandService, cmd:TestCommand) {
|
|||||||
describe('services_CommandService', function() {
|
describe('services_CommandService', function() {
|
||||||
|
|
||||||
beforeEach(async (done) => {
|
beforeEach(async (done) => {
|
||||||
|
KeymapService.destroyInstance();
|
||||||
|
KeymapService.instance().initialize();
|
||||||
|
|
||||||
await setupDatabaseAndSynchronizer(1);
|
await setupDatabaseAndSynchronizer(1);
|
||||||
await switchClient(1);
|
await switchClient(1);
|
||||||
done();
|
done();
|
||||||
|
@ -15,7 +15,7 @@ const SyncTargetRegistry = require('@joplin/lib/SyncTargetRegistry.js');
|
|||||||
const EncryptionService = require('@joplin/lib/services/EncryptionService.js');
|
const EncryptionService = require('@joplin/lib/services/EncryptionService.js');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at services_EncryptionService: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
let service = null;
|
let service = null;
|
||||||
|
@ -12,7 +12,7 @@ const fs = require('fs-extra');
|
|||||||
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at services_InteropService: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
function exportDir() {
|
function exportDir() {
|
||||||
|
@ -9,7 +9,7 @@ const Note = require('@joplin/lib/models/Note');
|
|||||||
const Folder = require('@joplin/lib/models/Folder');
|
const Folder = require('@joplin/lib/models/Folder');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at services_PluginService: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
const testPluginDir = `${__dirname}/../tests/support/plugins`;
|
const testPluginDir = `${__dirname}/../tests/support/plugins`;
|
||||||
|
@ -15,7 +15,7 @@ const RevisionService = require('@joplin/lib/services/RevisionService.js');
|
|||||||
const shim = require('@joplin/lib/shim').default;
|
const shim = require('@joplin/lib/shim').default;
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at services_Revision: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('services_Revision', function() {
|
describe('services_Revision', function() {
|
||||||
|
@ -157,85 +157,88 @@ describe('services_SearchEngine', function() {
|
|||||||
expect(rows[1].id).toBe(n2.id);
|
expect(rows[1].id).toBe(n2.id);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should correctly weigh notes using BM25 and user_updated_time', asyncTest(async () => {
|
// TODO: Need to update and replace jasmine.mockDate() calls with Jest
|
||||||
await mockDate(2020, 9, 30, 50);
|
// equivalent
|
||||||
const noteData = [
|
|
||||||
{
|
|
||||||
title: 'abc test2 test2',
|
|
||||||
updated_time: 1601425064756,
|
|
||||||
user_updated_time: 1601425064756,
|
|
||||||
created_time: 1601425064756,
|
|
||||||
user_created_time: 1601425064756,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'foo foo',
|
|
||||||
updated_time: 1601425064758,
|
|
||||||
user_updated_time: 1601425064758,
|
|
||||||
created_time: 1601425064758,
|
|
||||||
user_created_time: 1601425064758,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'dead beef',
|
|
||||||
updated_time: 1601425064760,
|
|
||||||
user_updated_time: 1601425064760,
|
|
||||||
created_time: 1601425064760,
|
|
||||||
user_created_time: 1601425064760,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'test2 bar',
|
|
||||||
updated_time: 1601425064761,
|
|
||||||
user_updated_time: 1601425064761,
|
|
||||||
created_time: 1601425064761,
|
|
||||||
user_created_time: 1601425064761,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'blah blah abc',
|
|
||||||
updated_time: 1601425064763,
|
|
||||||
user_updated_time: 1601425064763,
|
|
||||||
created_time: 1601425064763,
|
|
||||||
user_created_time: 1601425064763,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const n0 = await Note.save(noteData[0], { autoTimestamp: false });
|
// it('should correctly weigh notes using BM25 and user_updated_time', asyncTest(async () => {
|
||||||
const n1 = await Note.save(noteData[1], { autoTimestamp: false });
|
// await mockDate(2020, 9, 30, 50);
|
||||||
const n2 = await Note.save(noteData[2], { autoTimestamp: false });
|
// const noteData = [
|
||||||
const n3 = await Note.save(noteData[3], { autoTimestamp: false });
|
// {
|
||||||
const n4 = await Note.save(noteData[4], { autoTimestamp: false });
|
// title: 'abc test2 test2',
|
||||||
restoreDate();
|
// updated_time: 1601425064756,
|
||||||
await engine.syncTables();
|
// user_updated_time: 1601425064756,
|
||||||
await mockDate(2020, 9, 30, 50);
|
// created_time: 1601425064756,
|
||||||
|
// user_created_time: 1601425064756,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'foo foo',
|
||||||
|
// updated_time: 1601425064758,
|
||||||
|
// user_updated_time: 1601425064758,
|
||||||
|
// created_time: 1601425064758,
|
||||||
|
// user_created_time: 1601425064758,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'dead beef',
|
||||||
|
// updated_time: 1601425064760,
|
||||||
|
// user_updated_time: 1601425064760,
|
||||||
|
// created_time: 1601425064760,
|
||||||
|
// user_created_time: 1601425064760,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'test2 bar',
|
||||||
|
// updated_time: 1601425064761,
|
||||||
|
// user_updated_time: 1601425064761,
|
||||||
|
// created_time: 1601425064761,
|
||||||
|
// user_created_time: 1601425064761,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'blah blah abc',
|
||||||
|
// updated_time: 1601425064763,
|
||||||
|
// user_updated_time: 1601425064763,
|
||||||
|
// created_time: 1601425064763,
|
||||||
|
// user_created_time: 1601425064763,
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
|
|
||||||
let searchString = 'abc';
|
// const n0 = await Note.save(noteData[0], { autoTimestamp: false });
|
||||||
let scores = calculateScore(searchString, noteData);
|
// const n1 = await Note.save(noteData[1], { autoTimestamp: false });
|
||||||
let rows = await engine.search(searchString);
|
// const n2 = await Note.save(noteData[2], { autoTimestamp: false });
|
||||||
|
// const n3 = await Note.save(noteData[3], { autoTimestamp: false });
|
||||||
|
// const n4 = await Note.save(noteData[4], { autoTimestamp: false });
|
||||||
|
// restoreDate();
|
||||||
|
// await engine.syncTables();
|
||||||
|
// await mockDate(2020, 9, 30, 50);
|
||||||
|
|
||||||
expect(rows[0].weight).toEqual(scores[0]);
|
// let searchString = 'abc';
|
||||||
expect(rows[1].weight).toEqual(scores[1]);
|
// let scores = calculateScore(searchString, noteData);
|
||||||
|
// let rows = await engine.search(searchString);
|
||||||
|
|
||||||
// console.log(rows);
|
// expect(rows[0].weight).toEqual(scores[0]);
|
||||||
// console.log(scores);
|
// expect(rows[1].weight).toEqual(scores[1]);
|
||||||
|
|
||||||
searchString = 'test2';
|
// // console.log(rows);
|
||||||
scores = calculateScore(searchString, noteData);
|
// // console.log(scores);
|
||||||
rows = await engine.search(searchString);
|
|
||||||
|
|
||||||
// console.log(rows);
|
// searchString = 'test2';
|
||||||
// console.log(scores);
|
// scores = calculateScore(searchString, noteData);
|
||||||
|
// rows = await engine.search(searchString);
|
||||||
|
|
||||||
expect(rows[0].weight).toEqual(scores[0]);
|
// // console.log(rows);
|
||||||
expect(rows[1].weight).toEqual(scores[1]);
|
// // console.log(scores);
|
||||||
|
|
||||||
searchString = 'foo';
|
// expect(rows[0].weight).toEqual(scores[0]);
|
||||||
scores = calculateScore(searchString, noteData);
|
// expect(rows[1].weight).toEqual(scores[1]);
|
||||||
rows = await engine.search(searchString);
|
|
||||||
|
|
||||||
// console.log(rows);
|
// searchString = 'foo';
|
||||||
// console.log(scores);
|
// scores = calculateScore(searchString, noteData);
|
||||||
|
// rows = await engine.search(searchString);
|
||||||
|
|
||||||
expect(rows[0].weight).toEqual(scores[0]);
|
// // console.log(rows);
|
||||||
await restoreDate();
|
// // console.log(scores);
|
||||||
}));
|
|
||||||
|
// expect(rows[0].weight).toEqual(scores[0]);
|
||||||
|
// await restoreDate();
|
||||||
|
// }));
|
||||||
|
|
||||||
it('should tell where the results are found', asyncTest(async () => {
|
it('should tell where the results are found', asyncTest(async () => {
|
||||||
const notes = [
|
const notes = [
|
||||||
|
@ -16,7 +16,7 @@ const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
|||||||
|
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at services_SearchFilter: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
let engine = null;
|
let engine = null;
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
/* eslint-disable no-unused-vars */
|
|
||||||
/* eslint prefer-const: 0*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// const time = require('@joplin/lib/time').default;
|
|
||||||
// const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('./test-utils.js');
|
|
||||||
// const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine');
|
|
||||||
// const Note = require('@joplin/lib/models/Note');
|
|
||||||
// const Folder = require('@joplin/lib/models/Folder');
|
|
||||||
// const Tag = require('@joplin/lib/models/Tag');
|
|
||||||
// const ItemChange = require('@joplin/lib/models/ItemChange');
|
|
||||||
// const Setting = require('@joplin/lib/models/Setting');
|
|
||||||
// const Resource = require('@joplin/lib/models/Resource.js');
|
|
||||||
// const shim = require('@joplin/lib/shim').default;
|
|
||||||
// const ResourceService = require('@joplin/lib/services/ResourceService').default;
|
|
||||||
|
|
||||||
// process.on('unhandledRejection', (reason, p) => {
|
|
||||||
// console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let engine = null;
|
|
||||||
|
|
||||||
// const ids = (array) => array.map(a => a.id);
|
|
||||||
|
|
||||||
// describe('services_SearchFuzzy', function() {
|
|
||||||
// beforeEach(async (done) => {
|
|
||||||
// await setupDatabaseAndSynchronizer(1);
|
|
||||||
// await switchClient(1);
|
|
||||||
|
|
||||||
// engine = new SearchEngine();
|
|
||||||
// engine.setDb(db());
|
|
||||||
|
|
||||||
// Setting.setValue('db.fuzzySearchEnabled', 1);
|
|
||||||
// done();
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// it('should return note almost matching title', asyncTest(async () => {
|
|
||||||
// let rows;
|
|
||||||
// const n1 = await Note.save({ title: 'If It Ain\'t Baroque, Don\'t Fix It' });
|
|
||||||
// const n2 = await Note.save({ title: 'Important note' });
|
|
||||||
|
|
||||||
// await engine.syncTables();
|
|
||||||
// rows = await engine.search('Broke', { fuzzy: false });
|
|
||||||
// expect(rows.length).toBe(0);
|
|
||||||
|
|
||||||
// rows = await engine.search('Broke', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows[0].id).toBe(n1.id);
|
|
||||||
|
|
||||||
|
|
||||||
// rows = await engine.search('title:Broke', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows[0].id).toBe(n1.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('title:"Broke"', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows[0].id).toBe(n1.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('Imprtant', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows[0].id).toBe(n2.id);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
|
|
||||||
// it('should order results by min fuzziness', asyncTest(async () => {
|
|
||||||
// let rows;
|
|
||||||
// const n1 = await Note.save({ title: 'I demand you take me to him' });
|
|
||||||
// const n2 = await Note.save({ title: 'He demanded an answer' });
|
|
||||||
// const n3 = await Note.save({ title: 'Don\'t you make demands of me' });
|
|
||||||
// const n4 = await Note.save({ title: 'No drama for me' });
|
|
||||||
// const n5 = await Note.save({ title: 'Just minding my own business' });
|
|
||||||
|
|
||||||
// await engine.syncTables();
|
|
||||||
// rows = await engine.search('demand', { fuzzy: false });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows[0].id).toBe(n1.id);
|
|
||||||
|
|
||||||
|
|
||||||
// rows = await engine.search('demand', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(3);
|
|
||||||
// expect(rows[0].id).toBe(n1.id);
|
|
||||||
// expect(rows[1].id).toBe(n3.id);
|
|
||||||
// expect(rows[2].id).toBe(n2.id);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// it('should consider any:1', asyncTest(async () => {
|
|
||||||
// let rows;
|
|
||||||
// const n1 = await Note.save({ title: 'cat' });
|
|
||||||
// const n2 = await Note.save({ title: 'cats' });
|
|
||||||
// const n3 = await Note.save({ title: 'cot' });
|
|
||||||
|
|
||||||
// const n4 = await Note.save({ title: 'defenestrate' });
|
|
||||||
// const n5 = await Note.save({ title: 'defenstrate' });
|
|
||||||
// const n6 = await Note.save({ title: 'defenestrated' });
|
|
||||||
|
|
||||||
// const n7 = await Note.save({ title: 'he defenestrated the cat' });
|
|
||||||
|
|
||||||
// await engine.syncTables();
|
|
||||||
|
|
||||||
// rows = await engine.search('defenestrated cat', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
|
|
||||||
// rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(7);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// it('should leave phrase searches alone', asyncTest(async () => {
|
|
||||||
// let rows;
|
|
||||||
// const n1 = await Note.save({ title: 'abc def' });
|
|
||||||
// const n2 = await Note.save({ title: 'def ghi' });
|
|
||||||
// const n3 = await Note.save({ title: 'ghi jkl' });
|
|
||||||
// const n4 = await Note.save({ title: 'def abc' });
|
|
||||||
// const n5 = await Note.save({ title: 'mno pqr ghi jkl' });
|
|
||||||
|
|
||||||
// await engine.syncTables();
|
|
||||||
|
|
||||||
// rows = await engine.search('abc def', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(2);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n4.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('"abc def"', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('"ghi jkl"', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(2);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('"ghi jkl" mno', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(1);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
|
||||||
|
|
||||||
// rows = await engine.search('any:1 "ghi jkl" mno', { fuzzy: true });
|
|
||||||
// expect(rows.length).toBe(2);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// it('should leave wild card searches alone', asyncTest(async () => {
|
|
||||||
// let rows;
|
|
||||||
// const n1 = await Note.save({ title: 'abc def' });
|
|
||||||
// const n2 = await Note.save({ title: 'abcc ghi' });
|
|
||||||
// const n3 = await Note.save({ title: 'abccc ghi' });
|
|
||||||
// const n4 = await Note.save({ title: 'abcccc ghi' });
|
|
||||||
// const n5 = await Note.save({ title: 'wxy zzz' });
|
|
||||||
|
|
||||||
// await engine.syncTables();
|
|
||||||
|
|
||||||
// rows = await engine.search('abc*', { fuzzy: true });
|
|
||||||
|
|
||||||
// expect(rows.length).toBe(4);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n2.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
|
||||||
// expect(rows.map(r=>r.id)).toContain(n4.id);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// });
|
|
@ -4,9 +4,11 @@ import Setting from '@joplin/lib/models/Setting';
|
|||||||
|
|
||||||
const { db, asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
const { db, asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('./test-utils.js');
|
||||||
|
|
||||||
function describeIfCompatible(name:string, fn:any) {
|
function describeIfCompatible(name:string, fn:any, elseFn:any) {
|
||||||
if (['win32', 'darwin'].includes(shim.platformName())) {
|
if (['win32', 'darwin'].includes(shim.platformName())) {
|
||||||
return describe(name, fn);
|
return describe(name, fn);
|
||||||
|
} else {
|
||||||
|
elseFn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,4 +93,10 @@ describeIfCompatible('services_KeychainService', function() {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
}, () => {
|
||||||
|
|
||||||
|
it('will pass', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"spec_dir": "tests",
|
|
||||||
"spec_files": [
|
|
||||||
"*.js",
|
|
||||||
"services/plugins/*.js",
|
|
||||||
"services/plugins/api/*.js",
|
|
||||||
"!test-utils.js"
|
|
||||||
],
|
|
||||||
"stopSpecOnExpectationFailure": false,
|
|
||||||
"random": true
|
|
||||||
}
|
|
@ -127,7 +127,7 @@ setSyncTargetName('memory');
|
|||||||
// setSyncTargetName('onedrive');
|
// setSyncTargetName('onedrive');
|
||||||
// setSyncTargetName('amazon_s3');
|
// setSyncTargetName('amazon_s3');
|
||||||
|
|
||||||
console.info(`Testing with sync target: ${syncTargetName_}`);
|
// console.info(`Testing with sync target: ${syncTargetName_}`);
|
||||||
|
|
||||||
const syncDir = `${__dirname}/../tests/sync`;
|
const syncDir = `${__dirname}/../tests/sync`;
|
||||||
|
|
||||||
@ -190,6 +190,10 @@ function currentClientId() {
|
|||||||
return currentClient_;
|
return currentClient_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function afterEachCleanUp() {
|
||||||
|
await ItemChange.waitForAllSaved();
|
||||||
|
}
|
||||||
|
|
||||||
async function switchClient(id, options = null) {
|
async function switchClient(id, options = null) {
|
||||||
options = Object.assign({}, { keychainEnabled: false }, options);
|
options = Object.assign({}, { keychainEnabled: false }, options);
|
||||||
|
|
||||||
@ -542,8 +546,10 @@ function asyncTest(callback) {
|
|||||||
if (error.constructor && error.constructor.name === 'ExpectationFailed') {
|
if (error.constructor && error.constructor.name === 'ExpectationFailed') {
|
||||||
// OK - will be reported by Jasmine
|
// OK - will be reported by Jasmine
|
||||||
} else {
|
} else {
|
||||||
console.error(error);
|
// Better to rethrow exception as stack trace is more useful in this case
|
||||||
expect(0).toBe(1, 'Test has thrown an exception - see above error');
|
throw error;
|
||||||
|
// console.error(error);
|
||||||
|
// expect(0).toBe(1, 'Test has thrown an exception - see above error');
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
done();
|
done();
|
||||||
@ -728,4 +734,4 @@ class TestApp extends BaseApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { synchronizerStart, syncTargetName, setSyncTargetName, syncDir, createTempDir, isNetworkSyncTarget, kvStore, expectThrow, logger, expectNotThrow, resourceService, resourceFetcher, tempFilePath, allSyncTargetItemsEncrypted, msleep, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync, checkThrow, encryptionService, loadEncryptionMasterKey, fileContentEqual, decryptionWorker, asyncTest, currentClientId, id, ids, sortedIds, at, createNTestNotes, createNTestFolders, createNTestTags, mockDate, restoreDate, TestApp };
|
module.exports = { synchronizerStart, afterEachCleanUp, syncTargetName, setSyncTargetName, syncDir, createTempDir, isNetworkSyncTarget, kvStore, expectThrow, logger, expectNotThrow, resourceService, resourceFetcher, tempFilePath, allSyncTargetItemsEncrypted, msleep, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync, checkThrow, encryptionService, loadEncryptionMasterKey, fileContentEqual, decryptionWorker, asyncTest, currentClientId, id, ids, sortedIds, at, createNTestNotes, createNTestFolders, createNTestTags, mockDate, restoreDate, TestApp };
|
||||||
|
@ -3,7 +3,7 @@ const { asyncTest } = require('./test-utils.js');
|
|||||||
const urlUtils = require('@joplin/lib/urlUtils.js');
|
const urlUtils = require('@joplin/lib/urlUtils.js');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at urlUtils: Promise', p, 'reason:', reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('urlUtils', function() {
|
describe('urlUtils', function() {
|
||||||
|
@ -25,7 +25,9 @@ const isWindows = () => {
|
|||||||
async function main() {
|
async function main() {
|
||||||
// electron-rebuild --arch ia32 && electron-rebuild --arch x64
|
// electron-rebuild --arch ia32 && electron-rebuild --arch x64
|
||||||
|
|
||||||
// console.warn('ELECTRON REBUILD IS DISABLED!!!!!!!!!!!!!!!!!!!!!!!!');
|
// console.warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||||
|
// console.warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ELECTRON REBUILD IS DISABLED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||||
|
// console.warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
let exePath = `${__dirname}/../node_modules/.bin/electron-rebuild`;
|
let exePath = `${__dirname}/../node_modules/.bin/electron-rebuild`;
|
||||||
@ -34,12 +36,8 @@ async function main() {
|
|||||||
process.chdir(`${__dirname}/..`);
|
process.chdir(`${__dirname}/..`);
|
||||||
|
|
||||||
if (isWindows()) {
|
if (isWindows()) {
|
||||||
// const promises = [
|
// Cannot run this in parallel, or the 64-bit version might end up
|
||||||
// execCommand([`"${exePath}"`, '--arch ia32'].join(' ')),
|
// with 32-bit files and vice-versa
|
||||||
// execCommand([`"${exePath}"`, '--arch x64'].join(' ')),
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// await Promise.all(promises);
|
|
||||||
console.info(await execCommand([`"${exePath}"`, '--arch ia32'].join(' ')));
|
console.info(await execCommand([`"${exePath}"`, '--arch ia32'].join(' ')));
|
||||||
console.info(await execCommand([`"${exePath}"`, '--arch x64'].join(' ')));
|
console.info(await execCommand([`"${exePath}"`, '--arch x64'].join(' ')));
|
||||||
} else {
|
} else {
|
||||||
|
@ -26,7 +26,7 @@ const os = require('os');
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const JoplinError = require('./JoplinError');
|
const JoplinError = require('./JoplinError');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const syswidecas = require('syswide-cas');
|
const syswidecas = require('./vendor/syswide-cas');
|
||||||
const SyncTargetRegistry = require('./SyncTargetRegistry.js');
|
const SyncTargetRegistry = require('./SyncTargetRegistry.js');
|
||||||
const SyncTargetFilesystem = require('./SyncTargetFilesystem.js');
|
const SyncTargetFilesystem = require('./SyncTargetFilesystem.js');
|
||||||
const SyncTargetOneDrive = require('./SyncTargetOneDrive.js');
|
const SyncTargetOneDrive = require('./SyncTargetOneDrive.js');
|
||||||
|
5
packages/lib/package-lock.json
generated
5
packages/lib/package-lock.json
generated
@ -2315,11 +2315,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||||
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
|
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
|
||||||
},
|
},
|
||||||
"syswide-cas": {
|
|
||||||
"version": "5.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/syswide-cas/-/syswide-cas-5.3.0.tgz",
|
|
||||||
"integrity": "sha512-+RLgS6VInsX8rBpL+gy5qpa7phngecbK7NABelBZpqYpBTwOIK1y7CqHlXK5Vy/rA4erD9q/FyKzMjx2uX3zYg=="
|
|
||||||
},
|
|
||||||
"table-layout": {
|
"table-layout": {
|
||||||
"version": "0.4.5",
|
"version": "0.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
|
||||||
|
@ -65,7 +65,6 @@
|
|||||||
"sqlite3": "^4.1.1",
|
"sqlite3": "^4.1.1",
|
||||||
"string-padding": "^1.0.2",
|
"string-padding": "^1.0.2",
|
||||||
"string-to-stream": "^1.1.0",
|
"string-to-stream": "^1.1.0",
|
||||||
"syswide-cas": "^5.2.0",
|
|
||||||
"tar": "^4.4.10",
|
"tar": "^4.4.10",
|
||||||
"tcp-port-used": "^0.1.2",
|
"tcp-port-used": "^0.1.2",
|
||||||
"uglifycss": "0.0.29",
|
"uglifycss": "0.0.29",
|
||||||
|
@ -413,6 +413,10 @@ export default class KeymapService extends BaseService {
|
|||||||
|
|
||||||
private static instance_:KeymapService = null;
|
private static instance_:KeymapService = null;
|
||||||
|
|
||||||
|
public static destroyInstance() {
|
||||||
|
this.instance_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static instance():KeymapService {
|
public static instance():KeymapService {
|
||||||
if (this.instance_) return this.instance_;
|
if (this.instance_) return this.instance_;
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ function shimInit(sharp = null, keytar = null) {
|
|||||||
const newNote = Object.assign({}, note, {
|
const newNote = Object.assign({}, note, {
|
||||||
body: newBody,
|
body: newBody,
|
||||||
});
|
});
|
||||||
return await Note.save(newNote);
|
return Note.save(newNote);
|
||||||
};
|
};
|
||||||
|
|
||||||
shim.imageFromDataUrl = async function(imageDataUrl, filePath, options = null) {
|
shim.imageFromDataUrl = async function(imageDataUrl, filePath, options = null) {
|
||||||
|
106
packages/lib/vendor/syswide-cas.js
vendored
Normal file
106
packages/lib/vendor/syswide-cas.js
vendored
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// From https://github.com/capriza/syswide-cas/tree/e0a214f23a072866abf6af540a5b4b88b892a109
|
||||||
|
// With a patch to make it work within Jest environment
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const tls = require("tls");
|
||||||
|
|
||||||
|
const rootCAs = [];
|
||||||
|
|
||||||
|
// for node 7.2 and up, trapping method must be used.
|
||||||
|
var useTrap = false;
|
||||||
|
const parts = process.versions.node.split(".");
|
||||||
|
const major = parseInt(parts[0]);
|
||||||
|
const minor = parseInt(parts[1]);
|
||||||
|
if (major > 7 || (major == 7 && minor >= 2) || (major === 6 && minor >= 10)) {
|
||||||
|
useTrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an empty secure context loaded with the root CAs
|
||||||
|
const rootSecureContext = tls.createSecureContext ? tls.createSecureContext() : require("crypto").createCredentials();
|
||||||
|
|
||||||
|
function addDefaultCA(file) {
|
||||||
|
try {
|
||||||
|
var cert, match;
|
||||||
|
var content = fs.readFileSync(file, { encoding: "ascii" }).trim();
|
||||||
|
content = content.replace(/\r\n/g, "\n"); // Handles certificates that have been created in Windows
|
||||||
|
var regex = /-----BEGIN CERTIFICATE-----\n[\s\S]+?\n-----END CERTIFICATE-----/g;
|
||||||
|
var results = content.match(regex);
|
||||||
|
if (!results) throw new Error("Could not parse certificate");
|
||||||
|
results.forEach(function(match) {
|
||||||
|
var cert = match.trim();
|
||||||
|
rootCAs.push(cert);
|
||||||
|
// this will add the cert to the root certificate authorities list
|
||||||
|
// which will be used by all subsequent secure contexts with root CAs.
|
||||||
|
// this only works up to node 6. node 7 and up it has no affect.
|
||||||
|
if (!useTrap) {
|
||||||
|
rootSecureContext.context.addCACert(cert);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code !== "ENOENT") {
|
||||||
|
console.log("failed reading file " + file + ": " + e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.addCAs = function(dirs) {
|
||||||
|
if (!dirs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof dirs === "string") {
|
||||||
|
dirs = dirs.split(",").map(function(dir) {
|
||||||
|
return dir.trim();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var files, stat, file, i, j;
|
||||||
|
for (i = 0; i < dirs.length; ++i) {
|
||||||
|
try {
|
||||||
|
stat = fs.statSync(dirs[i]);
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
files = fs.readdirSync(dirs[i]);
|
||||||
|
for (j = 0; j < files.length; ++j) {
|
||||||
|
file = path.resolve(dirs[i], files[j]);
|
||||||
|
try {
|
||||||
|
stat = fs.statSync(file);
|
||||||
|
if (stat.isFile()) {
|
||||||
|
addDefaultCA(file);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code !== "ENOENT") {
|
||||||
|
console.log("failed reading " + file + ": " + e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addDefaultCA(dirs[i]);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code !== "ENOENT") {
|
||||||
|
console.log("failed reading " + dirs[i] + ": " + e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (useTrap) {
|
||||||
|
// trap the createSecureContext method and inject custom root CAs whenever invoked
|
||||||
|
const origCreateSecureContext = tls.createSecureContext;
|
||||||
|
tls.createSecureContext = function(options) {
|
||||||
|
options = options || {}; // PATCH - in Jest, this is null
|
||||||
|
var c = origCreateSecureContext.apply(null, arguments);
|
||||||
|
if (!options.ca && rootCAs.length > 0) {
|
||||||
|
rootCAs.forEach(function(ca) {
|
||||||
|
// add to the created context our own root CAs
|
||||||
|
c.context.addCACert(ca);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultCALocations = ["/etc/ssl/ca-node.pem"];
|
||||||
|
|
||||||
|
exports.addCAs(defaultCALocations);
|
Loading…
Reference in New Issue
Block a user