Mailspring/app/spec/stores/database-store-spec.ts
Ben Gotow 149b389508
Replace Babel with TypeScript compiler, switch entire app to TypeScript 🎉 (#1404)
* Switch to using Typescript instead of Babel

* Switch all es6 / jsx file extensions to ts / tsx

* Convert Utils to a TS module from module.exports style module

* Move everything from module.exports to typescript exports

* Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :(

* Load up on those @types

* Synthesize TS types from PropTypes for standard components

* Add types to Model classes and move constructor constants to instance vars

* 9800 => 7700 TS errors

* 7700 => 5600 TS errors

* 5600 => 5330 TS errors

* 5330 => 4866 TS errors

* 4866 => 4426 TS errors

* 4426 => 2411 TS errors

* 2411 > 1598 TS errors

* 1598 > 769 TS errors

* 769 > 129 TS errors

* 129 > 22 TS errors

* Fix runtime errors

* More runtime error fixes

* Remove support for custom .es6 file extension

* Remove a few odd remaining references to Nylas

* Don’t ship Typescript support in the compiled app for now

* Fix issues in compiled app - module resolution in TS is case sensitive?

* README updates

* Fix a few more TS errors

* Make “No Signature” option clickable + selectable

* Remove flicker when saving file and reloading keymaps

* Fix mail rule item height in preferences

* Fix missing spacing in thread sharing popover

* Fix scrollbar ticks being nested incorrectly

* Add Japanese as a manually reviewed language

* Prevent the thread list from “sticking”

* Re-use Sheet when switching root tabs, prevent sidebar from resetting

* Ensure specs run

* Update package configuration to avoid shpping types

* Turn eslint back on - we will opt-in to the TS rules one by one
2019-03-04 11:03:12 -08:00

143 lines
5.2 KiB
TypeScript

/* eslint quote-props: 0 */
import { Thread } from '../../src/flux/models/thread';
import TestModel from '../fixtures/db-test-model';
import ModelQuery from '../../src/flux/models/query';
import DatabaseStore from '../../src/flux/stores/database-store';
const testMatchers = { id: 'b' };
describe('DatabaseStore', function DatabaseStoreSpecs() {
beforeEach(() => {
TestModel.configureBasic();
spyOn(ModelQuery.prototype, 'where').andCallThrough();
this.performed = [];
// Note: We spy on _query and test all of the convenience methods that sit above
// it. None of these tests evaluate whether _query works!
jasmine.unspy(DatabaseStore, '_query');
spyOn(DatabaseStore, '_query').andCallFake((query, values = []) => {
this.performed.push({ query, values });
return Promise.resolve([]);
});
});
describe('find', () =>
it('should return a ModelQuery for retrieving a single item by Id', () => {
const q = DatabaseStore.find(TestModel, '4');
expect(q.sql()).toBe(
"SELECT `TestModel`.`data` FROM `TestModel` WHERE `TestModel`.`id` = '4' LIMIT 1"
);
}));
describe('findBy', () => {
it('should pass the provided predicates on to the ModelQuery', () => {
DatabaseStore.findBy<TestModel>(TestModel, testMatchers);
expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);
});
it('should return a ModelQuery ready to be executed', () => {
const q = DatabaseStore.findBy<TestModel>(TestModel, testMatchers);
expect(q.sql()).toBe(
"SELECT `TestModel`.`data` FROM `TestModel` WHERE `TestModel`.`id` = 'b' LIMIT 1"
);
});
});
describe('findAll', () => {
it('should pass the provided predicates on to the ModelQuery', () => {
DatabaseStore.findAll<TestModel>(TestModel, testMatchers);
expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);
});
it('should return a ModelQuery ready to be executed', () => {
const q = DatabaseStore.findAll<TestModel>(TestModel, testMatchers);
expect(q.sql()).toBe(
"SELECT `TestModel`.`data` FROM `TestModel` WHERE `TestModel`.`id` = 'b' "
);
});
});
describe('modelify', () => {
beforeEach(() => {
this.models = [
new Thread({ id: 'local-A' }),
new Thread({ id: 'local-B' }),
new Thread({ id: 'local-C' }),
new Thread({ id: 'local-D' }),
new Thread({ id: 'local-E' }),
new Thread({ id: 'local-F' }),
new Thread({ id: 'local-G' }),
];
// Actually returns correct sets for queries, since matchers can evaluate
// themselves against models in memory
spyOn(DatabaseStore, 'run').andCallFake(query => {
const results = this.models.filter(model =>
query._matchers.every(matcher => matcher.evaluate(model))
);
return Promise.resolve(results);
});
});
describe('when given an array or input that is not an array', () =>
it('resolves immediately with an empty array', () =>
waitsForPromise(() => {
return DatabaseStore.modelify(Thread, null).then(output => {
expect(output).toEqual([]);
});
})));
describe('when given an array of mixed IDs, and models', () =>
it('resolves with an array of models', () => {
const input = ['local-F', 'local-B', 'local-C', 'local-D', this.models[6]];
const expectedOutput = [
this.models[5],
this.models[1],
this.models[2],
this.models[3],
this.models[6],
];
return waitsForPromise(() => {
return DatabaseStore.modelify(Thread, input).then(output => {
expect(output).toEqual(expectedOutput);
});
});
}));
describe('when the input is only IDs', () =>
it('resolves with an array of models', () => {
const input = ['local-D', 'local-F', 'local-G'];
const expectedOutput = [this.models[3], this.models[5], this.models[6]];
return waitsForPromise(() => {
return DatabaseStore.modelify(Thread, input).then(output => {
expect(output).toEqual(expectedOutput);
});
});
}));
describe('when the input is all models', () =>
it('resolves with an array of models', () => {
const input = [this.models[0], this.models[1], this.models[2], this.models[3]];
const expectedOutput = [this.models[0], this.models[1], this.models[2], this.models[3]];
return waitsForPromise(() => {
return DatabaseStore.modelify(Thread, input).then(output => {
expect(output).toEqual(expectedOutput);
});
});
}));
});
describe('count', () => {
it('should pass the provided predicates on to the ModelQuery', () => {
DatabaseStore.findAll<TestModel>(TestModel, testMatchers);
expect(ModelQuery.prototype.where).toHaveBeenCalledWith(testMatchers);
});
it('should return a ModelQuery configured for COUNT ready to be executed', () => {
const q = DatabaseStore.findAll<TestModel>(TestModel, testMatchers);
expect(q.sql()).toBe(
"SELECT `TestModel`.`data` FROM `TestModel` WHERE `TestModel`.`id` = 'b' "
);
});
});
});