Mailspring/app/spec/registries/component-registry-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

132 lines
4.9 KiB
TypeScript

/*
* decaffeinate suggestions:
* DS001: Remove Babel/TypeScript constructor workaround
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
import React from 'react';
import ComponentRegistry from '../../src/registries/component-registry';
class TestComponent extends React.Component {
static displayName = 'TestComponent';
}
class TestComponentNotSameIdentity extends React.Component {
static displayName = 'TestComponent';
}
class TestComponentNoDisplayName extends React.Component {}
class AComponent extends React.Component {
static displayName = 'A';
}
class BComponent extends React.Component {
static displayName = 'B';
}
class CComponent extends React.Component {
static displayName = 'C';
}
class DComponent extends React.Component {
static displayName = 'D';
}
class EComponent extends React.Component {
static displayName = 'E';
}
class FComponent extends React.Component {
static displayName = 'F';
}
describe('ComponentRegistry', function() {
beforeEach(() => ComponentRegistry._clear());
describe('register', function() {
it('throws an exception if passed a non-component', function() {
expect(() => ComponentRegistry.register(null)).toThrow();
expect(() => ComponentRegistry.register('cheese')).toThrow();
});
it('returns itself', () =>
expect(ComponentRegistry.register(TestComponent, { role: 'bla' })).toBe(ComponentRegistry));
it('does allow the exact same component to be redefined with different role/locations', function() {
ComponentRegistry.register(TestComponent, { role: 'bla' });
expect(() => ComponentRegistry.register(TestComponent, { role: 'other-role' })).not.toThrow();
});
it('does not allow components to be overridden by other components with the same displayName', function() {
ComponentRegistry.register(TestComponent, { role: 'bla' });
expect(() =>
ComponentRegistry.register(TestComponentNotSameIdentity, { role: 'bla' })
).toThrow();
});
it('does not allow components to be registered without a displayName', () =>
expect(() =>
ComponentRegistry.register(TestComponentNoDisplayName, { role: 'bla' })
).toThrow());
});
describe('findComponentByName', function() {
it('should return a component', function() {
ComponentRegistry.register(TestComponent, { role: 'bla' });
expect(ComponentRegistry.findComponentByName('TestComponent')).toEqual(TestComponent);
});
it('should return undefined if there is no component', () =>
expect(ComponentRegistry.findComponentByName('not actually a name')).toBeUndefined());
});
describe('findComponentsMatching', function() {
it('should throw if a descriptor is not provided', () =>
expect(() => ComponentRegistry.findComponentsMatching()).toThrow());
it('should return the correct results in a wide range of test cases', function() {
const StubLocation1 = { id: 'StubLocation1' };
const StubLocation2 = { id: 'StubLocation2' };
ComponentRegistry.register(AComponent, { role: 'ThreadAction' });
ComponentRegistry.register(BComponent, { role: 'ThreadAction', modes: ['list'] });
ComponentRegistry.register(CComponent, { location: StubLocation1, modes: ['split'] });
ComponentRegistry.register(DComponent, { locations: [StubLocation1, StubLocation2] });
ComponentRegistry.register(EComponent, { roles: ['ThreadAction', 'MessageAction'] });
ComponentRegistry.register(FComponent, { roles: ['MessageAction'], mode: 'list' });
const scenarios = [
{ descriptor: { role: 'ThreadAction' }, results: [AComponent, BComponent, EComponent] },
{
descriptor: { role: 'ThreadAction', mode: 'list' },
results: [AComponent, BComponent, EComponent],
},
{ descriptor: { role: 'ThreadAction', mode: 'split' }, results: [AComponent, EComponent] },
{ descriptor: { location: StubLocation1 }, results: [CComponent, DComponent] },
{ descriptor: { location: StubLocation1, mode: 'list' }, results: [DComponent] },
{
descriptor: { locations: [StubLocation1, StubLocation2] },
results: [CComponent, DComponent],
},
{
descriptor: { roles: ['ThreadAction', 'MessageAction'] },
results: [AComponent, BComponent, EComponent, FComponent],
},
];
scenarios.forEach(({ descriptor, results }) =>
expect(ComponentRegistry.findComponentsMatching(descriptor)).toEqual(results)
);
});
});
describe('unregister', function() {
it('unregisters the component if it exists', function() {
ComponentRegistry.register(TestComponent, { role: 'bla' });
ComponentRegistry.unregister(TestComponent);
expect(ComponentRegistry.findComponentByName('TestComponent')).toBeUndefined();
});
it('throws if a string is passed instead of a component', () =>
expect(() => ComponentRegistry.unregister('TestComponent')).toThrow());
});
});