Skip to content

Commit

Permalink
refactor: restructure menu as positioner (#57)
Browse files Browse the repository at this point in the history
This PR brings some general refactoring and bug fixes. Test coverage is up slightly despite the large refactor on how menu positioning is done.

However, the `Positioner` API feels so much better and I'm looking forward to playing around with it later.

Docs will be added in a pull request coming soon. 

Closes #30
Closes #39
  • Loading branch information
ifiokjr committed Mar 20, 2019
1 parent 7bc87a4 commit b741635
Show file tree
Hide file tree
Showing 39 changed files with 1,059 additions and 345 deletions.
1 change: 0 additions & 1 deletion @remirror/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"license": "MIT",
"dependencies": {
"@emotion/core": "^10.0.9",
"@sindresorhus/is": "0.15.0",
"@types/memoize-one": "4.1.1",
"@types/nanoevents": "1.0.0",
"@types/nanoid": "1.2.1",
Expand Down
4 changes: 2 additions & 2 deletions @remirror/core/src/commands/replace-text.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NodeType } from 'prosemirror-model';
import { CommandFunction, FromTo } from '../types';
import { CommandFunction, FromToParams } from '../types';

/**
* Replaces text with an optional appended string at the end
Expand All @@ -10,7 +10,7 @@ import { CommandFunction, FromTo } from '../types';
* @param appendText
*/
export const replaceText = (
range: FromTo | null,
range: FromToParams | null,
type: NodeType,
attrs = {},
appendText = '',
Expand Down
9 changes: 4 additions & 5 deletions @remirror/core/src/extension-manager.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import is from '@sindresorhus/is';
import { AnyExtension, Extension } from './extension';
import { bool, Cast } from './helpers/base';
import { bool, Cast, isObject } from './helpers/base';
import { MarkExtension } from './mark-extension';
import { NodeExtension } from './node-extension';
import { AnyFunction, CommandParams, ExtensionType, FlexibleConfig, SchemaParams } from './types';
Expand Down Expand Up @@ -123,23 +122,23 @@ export const createFlexibleFunctionMap = <
* @param extension
*/
export const isNodeExtension = (extension: unknown): extension is NodeExtension<any> =>
is.object(extension) && extension instanceof NodeExtension;
isObject(extension) && extension instanceof NodeExtension;

/**
* Determines if the passed in extension is a mark extension. Useful as a type guard where a particular type of extension is needed.
*
* @param extension
*/
export const isMarkExtension = (extension: unknown): extension is MarkExtension<any> =>
is.object(extension) && extension instanceof MarkExtension;
isObject(extension) && extension instanceof MarkExtension;

/**
* Checks whether the this is an extension and if it is a plain one
*
* @param extension
*/
export const isPlainExtension = (extension: unknown): extension is Extension<any, never> =>
is.object(extension) && extension instanceof Extension && extension.type === ExtensionType.EXTENSION;
isObject(extension) && extension instanceof Extension && extension.type === ExtensionType.EXTENSION;

/**
* Checks to see if an optional property exists on an extension.
Expand Down
245 changes: 245 additions & 0 deletions @remirror/core/src/helpers/__tests__/base.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
import {
capitalize,
environment,
findMatches,
format,
isBoolean,
isClass,
isDate,
isEmptyArray,
isEmptyObject,
isError,
isFunction,
isInteger,
isMap,
isNativePromise,
isNull,
isNullOrUndefined,
isNumber,
isObject,
isPlainObject,
isPromise,
isRegExp,
isSafeInteger,
isSet,
isString,
isSymbol,
isUndefined,
randomInt,
startCase,
take,
trim,
uniqueId,
} from '../base';

describe('findMatches', () => {
it('finds the correct number of matches', () => {
expect(findMatches('1234', /[13]/g)).toHaveLength(2);
});

it('does not crash when no `g` flag added', () => {
expect(findMatches('ababab', /a/)).toHaveLength(3);
});
});

test('format', () => {
expect(format(' test ')).toBe('Test');
});

test('capitalize', () => {
expect(capitalize('test')).toBe('Test');
});

test('trim', () => {
expect(trim(' test ')).toBe('test');
});

test('randomInt', () => {
expect(randomInt(10)).toBeLessThanOrEqual(10);
expect(randomInt(20, 30)).toBeGreaterThanOrEqual(20);
});

test('startCase', () => {
expect(startCase('abcdefg')).toBe('Abcdefg');
expect(startCase('a living dream')).toBe('A Living Dream');
});

test('uniqueId', () => {
expect(uniqueId({ prefix: 'test' })).toInclude('test');
expect(uniqueId({ size: 10 })).toHaveLength(10);
});

test('take', () => {
expect(take([1, 2, 3], 2)).toEqual([1, 2]);
});

describe('environment', () => {
it('has all environment properties', () => {
expect(environment.isBrowser).toBeTrue();
expect(environment.isJSDOM).toBeTrue();
expect(environment.isNode).toBeTrue();
expect(environment.isMac).toBeFalse();
});
});

describe('predicates', () => {
it('isBoolean', () => {
const passValue = true;
const failValue = 'true';
expect(isBoolean(passValue)).toBeTrue();
expect(isBoolean(failValue)).toBeFalse();
});

it('isClass', () => {
const passValue = class Simple {};
const failValue = Function;
expect(isClass(passValue)).toBeTrue();
expect(isClass(failValue)).toBeFalse();
});

it('isDate', () => {
const passValue = new Date();
const failValue = Date.now();
expect(isDate(passValue)).toBeTrue();
expect(isDate(failValue)).toBeFalse();
});

it('isError', () => {
const passValue = new Error('Pass');
const failValue = new class Simple {}();
expect(isError(passValue)).toBeTrue();
expect(isError(failValue)).toBeFalse();
});

it('isFunction', () => {
const passValue = () => {};
const failValue = '() => {}';
expect(isFunction(passValue)).toBeTrue();
expect(isFunction(failValue)).toBeFalse();
});

it('isInteger', () => {
const passValue = 1002;
const failValue = 10.02;
expect(isInteger(passValue)).toBeTrue();
expect(isInteger(failValue)).toBeFalse();
});

it('isMap', () => {
const passValue = new Map();
const failValue = {};
expect(isMap(passValue)).toBeTrue();
expect(isMap(failValue)).toBeFalse();
});

it('isNativePromise', () => {
const passValue = Promise.resolve();
const failValue = { undefined };
expect(isNativePromise(passValue)).toBeTrue();
expect(isNativePromise(failValue)).toBeFalse();
});

it('isNull', () => {
const passValue = null;
const failValue = undefined;
expect(isNull(passValue)).toBeTrue();
expect(isNull(failValue)).toBeFalse();
});

it('isNumber', () => {
const passValue = 1;
const failValue = '1';
expect(isNumber(passValue)).toBeTrue();
expect(isNumber(failValue)).toBeFalse();
});

it('isPlainObject', () => {
const passValue = { a: 'a' };
const failValue = new class Simple {
public a = 'a';
}();
const simpleFailValue = undefined;
expect(isPlainObject(passValue)).toBeTrue();
expect(isPlainObject(failValue)).toBeFalse();
expect(isPlainObject(simpleFailValue)).toBeFalse();
});

it('isPromise', () => {
const passValue = { then: () => {}, catch: () => {} };
const failValue = null;
expect(isPromise(passValue)).toBeTrue();
expect(isPromise(failValue)).toBeFalse();
});

it('isRegExp', () => {
const passValue = new RegExp('', 'g');
const failValue = '//w';
expect(isRegExp(passValue)).toBeTrue();
expect(isRegExp(failValue)).toBeFalse();
});

it('isSafeInteger', () => {
const passValue = Math.pow(2, 53) - 1;
const failValue = Math.pow(2, 53);
expect(isSafeInteger(passValue)).toBeTrue();
expect(isSafeInteger(failValue)).toBeFalse();
});

it('isSet', () => {
const passValue = new Set();
const failValue = new WeakSet();
expect(isSet(passValue)).toBeTrue();
expect(isSet(failValue)).toBeFalse();
});

it('isString', () => {
const passValue = 'isString';
const failValue = 10;
expect(isString(passValue)).toBeTrue();
expect(isString(failValue)).toBeFalse();
});

it('isSymbol', () => {
const passValue = Symbol('a');
const failValue = 'symbol';
expect(isSymbol(passValue)).toBeTrue();
expect(isSymbol(failValue)).toBeFalse();
});

it('isUndefined', () => {
const passValue = undefined;
const failValue = null;
expect(isUndefined(passValue)).toBeTrue();
expect(isUndefined(failValue)).toBeFalse();
});

it('isNullOrUndefined', () => {
const passValue = null;
const failValue = false;
expect(isNullOrUndefined(passValue)).toBeTrue();
expect(isNullOrUndefined(failValue)).toBeFalse();
});

it('isObject', () => {
const passValue = new class Simple {}();
const failValue = false;
expect(isObject(passValue)).toBeTrue();
expect(isObject(failValue)).toBeFalse();
});

it('isEmptyObject', () => {
const passValue = {};
const failValue = { oop: 'sie' };
const altPassValue = new class Simple {}();
expect(isEmptyObject(passValue)).toBeTrue();
expect(isEmptyObject(failValue)).toBeFalse();
expect(isEmptyObject(altPassValue)).toBeTrue();
});

it('isEmptyArray', () => {
const passValue: never[] = [];
const failValue = ['oop', 'sie'];
expect(isEmptyArray(passValue)).toBeTrue();
expect(isEmptyArray(failValue)).toBeFalse();
});
});

0 comments on commit b741635

Please sign in to comment.