refactor: migrate unit test to Jest

This commit is contained in:
Juan Picado @jotadeveloper 2017-11-01 17:47:20 +01:00 committed by juanpicado
parent bc2b44c51e
commit 31c2bd48a0
24 changed files with 3805 additions and 2428 deletions

View File

@ -25,6 +25,12 @@
"transform-decorators-legacy"
]
},
"test": {
"presets": [ "es2015-node4", "flow"],
"plugins": [
"transform-object-rest-spread"
]
},
"registry": {
"presets": [
"es2015-node4", "flow"

View File

@ -2,5 +2,6 @@ node_modules
coverage/
wiki/
static/
flow-typed/
website/
build/

View File

@ -1,13 +1,15 @@
{
"plugins": [
"react",
"flowtype"
"flowtype",
"jest"
],
"extends": [
"eslint:recommended",
"google",
"plugin:react/recommended",
"plugin:flowtype/recommended"
"plugin:flowtype/recommended",
"plugin:jest/recommended"
],
"parser": "babel-eslint",
"parserOptions": {
@ -21,7 +23,8 @@
"env": {
"browser": true,
"node": true,
"es6": true
"es6": true,
"jest": true
},
"rules": {
"no-tabs": 0,

View File

@ -24,12 +24,11 @@ test:
override:
- yarn run pre:ci
- nvm alias default 6
- yarn run test:ci
- yarn run test
- nvm alias default 4
- yarn run test:ci
- yarn run test
- nvm alias default 8
- yarn run test:ci
- yarn run coverage:publish
- yarn run test
deployment:
production:
tag: /(v)?[0-9]+(\.[0-9]+)*/

459
flow-typed/npm/jest_v19.x.x.js vendored Normal file
View File

@ -0,0 +1,459 @@
// flow-typed signature: bdff15032a92c1b6daf0ab0067861cb1
// flow-typed version: b43dff3e0e/jest_v19.x.x/flow_>=v0.16.x
type JestMockFn = {
(...args: Array<any>): any,
/**
* An object for introspecting mock calls
*/
mock: {
/**
* An array that represents all calls that have been made into this mock
* function. Each call is represented by an array of arguments that were
* passed during the call.
*/
calls: Array<Array<any>>,
/**
* An array that contains all the object instances that have been
* instantiated from this mock function.
*/
instances: mixed,
},
/**
* Resets all information stored in the mockFn.mock.calls and
* mockFn.mock.instances arrays. Often this is useful when you want to clean
* up a mock's usage data between two assertions.
*/
mockClear(): Function,
/**
* Resets all information stored in the mock. This is useful when you want to
* completely restore a mock back to its initial state.
*/
mockReset(): Function,
/**
* Accepts a function that should be used as the implementation of the mock.
* The mock itself will still record all calls that go into and instances
* that come from itself -- the only difference is that the implementation
* will also be executed when the mock is called.
*/
mockImplementation(fn: Function): JestMockFn,
/**
* Accepts a function that will be used as an implementation of the mock for
* one call to the mocked function. Can be chained so that multiple function
* calls produce different results.
*/
mockImplementationOnce(fn: Function): JestMockFn,
/**
* Just a simple sugar function for returning `this`
*/
mockReturnThis(): void,
/**
* Deprecated: use jest.fn(() => value) instead
*/
mockReturnValue(value: any): JestMockFn,
/**
* Sugar for only returning a value once inside your mock
*/
mockReturnValueOnce(value: any): JestMockFn,
}
type JestAsymmetricEqualityType = {
/**
* A custom Jasmine equality tester
*/
asymmetricMatch(value: mixed): boolean,
}
type JestCallsType = {
allArgs(): mixed,
all(): mixed,
any(): boolean,
count(): number,
first(): mixed,
mostRecent(): mixed,
reset(): void,
}
type JestClockType = {
install(): void,
mockDate(date: Date): void,
tick(milliseconds?:number): void,
uninstall(): void,
}
type JestMatcherResult = {
message?: string | ()=>string,
pass: boolean,
}
type JestMatcher = (actual: any, expected: any) => JestMatcherResult;
type JestExpectType = {
not: JestExpectType,
/**
* If you have a mock function, you can use .lastCalledWith to test what
* arguments it was last called with.
*/
lastCalledWith(...args: Array<any>): void,
/**
* toBe just checks that a value is what you expect. It uses === to check
* strict equality.
*/
toBe(value: any): void,
/**
* Use .toHaveBeenCalled to ensure that a mock function got called.
*/
toBeCalled(): void,
/**
* Use .toBeCalledWith to ensure that a mock function was called with
* specific arguments.
*/
toBeCalledWith(...args: Array<any>): void,
/**
* Using exact equality with floating point numbers is a bad idea. Rounding
* means that intuitive things fail.
*/
toBeCloseTo(num: number, delta: any): void,
/**
* Use .toBeDefined to check that a variable is not undefined.
*/
toBeDefined(): void,
/**
* Use .toBeFalsy when you don't care what a value is, you just want to
* ensure a value is false in a boolean context.
*/
toBeFalsy(): void,
/**
* To compare floating point numbers, you can use toBeGreaterThan.
*/
toBeGreaterThan(number: number): void,
/**
* To compare floating point numbers, you can use toBeGreaterThanOrEqual.
*/
toBeGreaterThanOrEqual(number: number): void,
/**
* To compare floating point numbers, you can use toBeLessThan.
*/
toBeLessThan(number: number): void,
/**
* To compare floating point numbers, you can use toBeLessThanOrEqual.
*/
toBeLessThanOrEqual(number: number): void,
/**
* Use .toBeInstanceOf(Class) to check that an object is an instance of a
* class.
*/
toBeInstanceOf(cls: Class<*>): void,
/**
* .toBeNull() is the same as .toBe(null) but the error messages are a bit
* nicer.
*/
toBeNull(): void,
/**
* Use .toBeTruthy when you don't care what a value is, you just want to
* ensure a value is true in a boolean context.
*/
toBeTruthy(): void,
/**
* Use .toBeUndefined to check that a variable is undefined.
*/
toBeUndefined(): void,
/**
* Use .toContain when you want to check that an item is in a list. For
* testing the items in the list, this uses ===, a strict equality check.
*/
toContain(item: any): void,
/**
* Use .toContainEqual when you want to check that an item is in a list. For
* testing the items in the list, this matcher recursively checks the
* equality of all fields, rather than checking for object identity.
*/
toContainEqual(item: any): void,
/**
* Use .toEqual when you want to check that two objects have the same value.
* This matcher recursively checks the equality of all fields, rather than
* checking for object identity.
*/
toEqual(value: any): void,
/**
* Use .toHaveBeenCalled to ensure that a mock function got called.
*/
toHaveBeenCalled(): void,
/**
* Use .toHaveBeenCalledTimes to ensure that a mock function got called exact
* number of times.
*/
toHaveBeenCalledTimes(number: number): void,
/**
* Use .toHaveBeenCalledWith to ensure that a mock function was called with
* specific arguments.
*/
toHaveBeenCalledWith(...args: Array<any>): void,
/**
* If you have a mock function, you can use .toHaveBeenLastCalledWith to test what
* arguments it was last called with.
*/
toHaveBeenLastCalledWith(...args: Array<any>): void,
/**
* Check that an object has a .length property and it is set to a certain
* numeric value.
*/
toHaveLength(number: number): void,
/**
*
*/
toHaveProperty(propPath: string, value?: any): void,
/**
* Use .toMatch to check that a string matches a regular expression.
*/
toMatch(regexp: RegExp): void,
/**
* Use .toMatchObject to check that a javascript object matches a subset of the properties of an object.
*/
toMatchObject(object: Object): void,
/**
* This ensures that a React component matches the most recent snapshot.
*/
toMatchSnapshot(name?: string): void,
/**
* Use .toThrow to test that a function throws when it is called.
*/
toThrow(message?: string | Error): void,
/**
* Use .toThrowError to test that a function throws a specific error when it
* is called. The argument can be a string for the error message, a class for
* the error, or a regex that should match the error.
*/
toThrowError(message?: string | Error | RegExp): void,
/**
* Use .toThrowErrorMatchingSnapshot to test that a function throws a error
* matching the most recent snapshot when it is called.
*/
toThrowErrorMatchingSnapshot(): void,
}
type JestObjectType = {
/**
* Disables automatic mocking in the module loader.
*
* After this method is called, all `require()`s will return the real
* versions of each module (rather than a mocked version).
*/
disableAutomock(): JestObjectType,
/**
* An un-hoisted version of disableAutomock
*/
autoMockOff(): JestObjectType,
/**
* Enables automatic mocking in the module loader.
*/
enableAutomock(): JestObjectType,
/**
* An un-hoisted version of enableAutomock
*/
autoMockOn(): JestObjectType,
/**
* Clears the mock.calls and mock.instances properties of all mocks.
* Equivalent to calling .mockClear() on every mocked function.
*/
clearAllMocks(): JestObjectType,
/**
* Resets the state of all mocks. Equivalent to calling .mockReset() on every
* mocked function.
*/
resetAllMocks(): JestObjectType,
/**
* Removes any pending timers from the timer system.
*/
clearAllTimers(): void,
/**
* The same as `mock` but not moved to the top of the expectation by
* babel-jest.
*/
doMock(moduleName: string, moduleFactory?: any): JestObjectType,
/**
* The same as `unmock` but not moved to the top of the expectation by
* babel-jest.
*/
dontMock(moduleName: string): JestObjectType,
/**
* Returns a new, unused mock function. Optionally takes a mock
* implementation.
*/
fn(implementation?: Function): JestMockFn,
/**
* Determines if the given function is a mocked function.
*/
isMockFunction(fn: Function): boolean,
/**
* Given the name of a module, use the automatic mocking system to generate a
* mocked version of the module for you.
*/
genMockFromModule(moduleName: string): any,
/**
* Mocks a module with an auto-mocked version when it is being required.
*
* The second argument can be used to specify an explicit module factory that
* is being run instead of using Jest's automocking feature.
*
* The third argument can be used to create virtual mocks -- mocks of modules
* that don't exist anywhere in the system.
*/
mock(moduleName: string, moduleFactory?: any, options?: Object): JestObjectType,
/**
* Resets the module registry - the cache of all required modules. This is
* useful to isolate modules where local state might conflict between tests.
*/
resetModules(): JestObjectType,
/**
* Exhausts the micro-task queue (usually interfaced in node via
* process.nextTick).
*/
runAllTicks(): void,
/**
* Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(),
* setInterval(), and setImmediate()).
*/
runAllTimers(): void,
/**
* Exhausts all tasks queued by setImmediate().
*/
runAllImmediates(): void,
/**
* Executes only the macro task queue (i.e. all tasks queued by setTimeout()
* or setInterval() and setImmediate()).
*/
runTimersToTime(msToRun: number): void,
/**
* Executes only the macro-tasks that are currently pending (i.e., only the
* tasks that have been queued by setTimeout() or setInterval() up to this
* point)
*/
runOnlyPendingTimers(): void,
/**
* Explicitly supplies the mock object that the module system should return
* for the specified module. Note: It is recommended to use jest.mock()
* instead.
*/
setMock(moduleName: string, moduleExports: any): JestObjectType,
/**
* Indicates that the module system should never return a mocked version of
* the specified module from require() (e.g. that it should always return the
* real module).
*/
unmock(moduleName: string): JestObjectType,
/**
* Instructs Jest to use fake versions of the standard timer functions
* (setTimeout, setInterval, clearTimeout, clearInterval, nextTick,
* setImmediate and clearImmediate).
*/
useFakeTimers(): JestObjectType,
/**
* Instructs Jest to use the real versions of the standard timer functions.
*/
useRealTimers(): JestObjectType,
/**
* Creates a mock function similar to jest.fn but also tracks calls to
* object[methodName].
*/
spyOn(object: Object, methodName: string): JestMockFn,
}
type JestSpyType = {
calls: JestCallsType,
}
/** Runs this function after every test inside this context */
declare function afterEach(fn: Function): void;
/** Runs this function before every test inside this context */
declare function beforeEach(fn: Function): void;
/** Runs this function after all tests have finished inside this context */
declare function afterAll(fn: Function): void;
/** Runs this function before any tests have started inside this context */
declare function beforeAll(fn: Function): void;
/** A context for grouping tests together */
declare function describe(name: string, fn: Function): void;
/** An individual test unit */
declare var it: {
/**
* An individual test unit
*
* @param {string} Name of Test
* @param {Function} Test
*/
(name: string, fn?: Function): ?Promise<void>,
/**
* Only run this test
*
* @param {string} Name of Test
* @param {Function} Test
*/
only(name: string, fn?: Function): ?Promise<void>,
/**
* Skip running this test
*
* @param {string} Name of Test
* @param {Function} Test
*/
skip(name: string, fn?: Function): ?Promise<void>,
/**
* Run the test concurrently
*
* @param {string} Name of Test
* @param {Function} Test
*/
concurrent(name: string, fn?: Function): ?Promise<void>,
};
declare function fit(name: string, fn: Function): ?Promise<void>;
/** An individual test unit */
declare var test: typeof it;
/** A disabled group of tests */
declare var xdescribe: typeof describe;
/** A focused group of tests */
declare var fdescribe: typeof describe;
/** A disabled individual test */
declare var xit: typeof it;
/** A disabled individual test */
declare var xtest: typeof it;
/** The expect function is used every time you want to test a value */
declare var expect: {
/** The object that you want to make assertions against */
(value: any): JestExpectType,
/** Add additional Jasmine matchers to Jest's roster */
extend(matchers: {[name:string]: JestMatcher}): void,
/** Add a module that formats application-specific data structures. */
addSnapshotSerializer(serializer: (input: Object) => string): void,
assertions(expectedAssertions: number): void,
any(value: mixed): JestAsymmetricEqualityType,
anything(): void,
arrayContaining(value: Array<mixed>): void,
objectContaining(value: Object): void,
/** Matches any received string that contains the exact expected string. */
stringContaining(value: string): void,
stringMatching(value: string | RegExp): void,
};
// TODO handle return type
// http://jasmine.github.io/2.4/introduction.html#section-Spies
declare function spyOn(value: mixed, method: string): Object;
/** Holds all functions related to manipulating test runner */
declare var jest: JestObjectType
/**
* The global Jamine object, this is generally not exposed as the public API,
* using features inside here could break in later versions of Jest.
*/
declare var jasmine: {
DEFAULT_TIMEOUT_INTERVAL: number,
any(value: mixed): JestAsymmetricEqualityType,
anything(): void,
arrayContaining(value: Array<mixed>): void,
clock(): JestClockType,
createSpy(name: string): JestSpyType,
createSpyObj(baseName: string, methodNames: Array<string>): {[methodName: string]: JestSpyType},
objectContaining(value: Object): void,
stringMatching(value: string): void,
}

514
flow-typed/npm/lodash_v4.x.x.js vendored Normal file
View File

@ -0,0 +1,514 @@
// flow-typed signature: 495348fe7e36289229ca4b9b8cbad572
// flow-typed version: 9821eaaefe/lodash_v4.x.x/flow_>=v0.47.x
declare module 'lodash' {
declare type TemplateSettings = {
escape?: RegExp,
evaluate?: RegExp,
imports?: Object,
interpolate?: RegExp,
variable?: string,
};
declare type TruncateOptions = {
length?: number,
omission?: string,
separator?: RegExp|string,
};
declare type DebounceOptions = {
leading?: bool,
maxWait?: number,
trailing?: bool,
};
declare type ThrottleOptions = {
leading?: bool,
trailing?: bool,
};
declare type NestedArray<T> = Array<Array<T>>;
declare type matchesIterateeShorthand = Object;
declare type matchesPropertyIterateeShorthand = [string, any];
declare type propertyIterateeShorthand = string;
declare type OPredicate<A, O> =
| ((value: A, key: string, object: O) => any)
| matchesIterateeShorthand
| matchesPropertyIterateeShorthand
| propertyIterateeShorthand;
declare type OIterateeWithResult<V, O, R> = Object|string|((value: V, key: string, object: O) => R);
declare type OIteratee<O> = OIterateeWithResult<any, O, any>;
declare type OFlatMapIteratee<T, U> = OIterateeWithResult<any, T, Array<U>>;
declare type Predicate<T> =
| ((value: T, index: number, array: Array<T>) => any)
| matchesIterateeShorthand
| matchesPropertyIterateeShorthand
| propertyIterateeShorthand;
declare type _ValueOnlyIteratee<T> = (value: T) => mixed;
declare type ValueOnlyIteratee<T> = _ValueOnlyIteratee<T>|string;
declare type _Iteratee<T> = (item: T, index: number, array: ?Array<T>) => mixed;
declare type Iteratee<T> = _Iteratee<T>|Object|string;
declare type FlatMapIteratee<T, U> = ((item: T, index: number, array: ?Array<T>) => Array<U>)|Object|string;
declare type Comparator<T> = (item: T, item2: T) => bool;
declare type MapIterator<T,U> =
| ((item: T, index: number, array: Array<T>) => U)
| propertyIterateeShorthand;
declare type OMapIterator<T,O,U> =
| ((item: T, key: string, object: O) => U)
| propertyIterateeShorthand;
declare class Lodash {
// Array
chunk<T>(array: ?Array<T>, size?: number): Array<Array<T>>;
compact<T,N:?T>(array: Array<N>): Array<T>;
concat<T>(base: Array<T>, ...elements: Array<any>): Array<T|any>;
difference<T>(array: ?Array<T>, values?: Array<T>): Array<T>;
differenceBy<T>(array: ?Array<T>, values: Array<T>, iteratee: ValueOnlyIteratee<T>): T[];
differenceWith<T>(array: T[], values: T[], comparator?: Comparator<T>): T[];
drop<T>(array: ?Array<T>, n?: number): Array<T>;
dropRight<T>(array: ?Array<T>, n?: number): Array<T>;
dropRightWhile<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
dropWhile<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
fill<T, U>(array: ?Array<T>, value: U, start?: number, end?: number): Array<T|U>;
findIndex<T>(array: ?Array<T>, predicate?: Predicate<T>, fromIndex?: number): number;
findLastIndex<T>(array: ?Array<T>, predicate?: Predicate<T>, fromIndex?: number): number;
// alias of _.head
first<T>(array: ?Array<T>): T;
flatten<T,X>(array: Array<Array<T>|X>): Array<T|X>;
flattenDeep<T>(array: any[]): Array<T>;
flattenDepth(array: any[], depth?: number): any[];
fromPairs<T>(pairs: Array<T>): Object;
head<T>(array: ?Array<T>): T;
indexOf<T>(array: ?Array<T>, value: T, fromIndex?: number): number;
initial<T>(array: ?Array<T>): Array<T>;
intersection<T>(...arrays: Array<Array<T>>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
intersectionBy<T>(a1: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
intersectionBy<T>(a1: Array<T>, a2: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
intersectionBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
intersectionBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
intersectionWith<T>(a1: Array<T>, comparator: Comparator<T>): Array<T>;
intersectionWith<T>(a1: Array<T>, a2: Array<T>, comparator: Comparator<T>): Array<T>;
intersectionWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, comparator: Comparator<T>): Array<T>;
intersectionWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, comparator: Comparator<T>): Array<T>;
join<T>(array: ?Array<T>, separator?: string): string;
last<T>(array: ?Array<T>): T;
lastIndexOf<T>(array: ?Array<T>, value: T, fromIndex?: number): number;
nth<T>(array: T[], n?: number): T;
pull<T>(array: ?Array<T>, ...values?: Array<T>): Array<T>;
pullAll<T>(array: ?Array<T>, values: Array<T>): Array<T>;
pullAllBy<T>(array: ?Array<T>, values: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
pullAllWith<T>(array?: T[], values: T[], comparator?: Function): T[];
pullAt<T>(array: ?Array<T>, ...indexed?: Array<number>): Array<T>;
pullAt<T>(array: ?Array<T>, indexed?: Array<number>): Array<T>;
remove<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
reverse<T>(array: ?Array<T>): Array<T>;
slice<T>(array: ?Array<T>, start?: number, end?: number): Array<T>;
sortedIndex<T>(array: ?Array<T>, value: T): number;
sortedIndexBy<T>(array: ?Array<T>, value: T, iteratee?: ValueOnlyIteratee<T>): number;
sortedIndexOf<T>(array: ?Array<T>, value: T): number;
sortedLastIndex<T>(array: ?Array<T>, value: T): number;
sortedLastIndexBy<T>(array: ?Array<T>, value: T, iteratee?: ValueOnlyIteratee<T>): number;
sortedLastIndexOf<T>(array: ?Array<T>, value: T): number;
sortedUniq<T>(array: ?Array<T>): Array<T>;
sortedUniqBy<T>(array: ?Array<T>, iteratee?: (value: T) => mixed): Array<T>;
tail<T>(array: ?Array<T>): Array<T>;
take<T>(array: ?Array<T>, n?: number): Array<T>;
takeRight<T>(array: ?Array<T>, n?: number): Array<T>;
takeRightWhile<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
takeWhile<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
union<T>(...arrays?: Array<Array<T>>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
unionBy<T>(a1: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
unionBy<T>(a1: Array<T>, a2: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
unionBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
unionBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
unionWith<T>(a1: Array<T>, comparator?: Comparator<T>): Array<T>;
unionWith<T>(a1: Array<T>, a2: Array<T>, comparator?: Comparator<T>): Array<T>;
unionWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, comparator?: Comparator<T>): Array<T>;
unionWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, comparator?: Comparator<T>): Array<T>;
uniq<T>(array: ?Array<T>): Array<T>;
uniqBy<T>(array: ?Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
uniqWith<T>(array: ?Array<T>, comparator?: Comparator<T>): Array<T>;
unzip<T>(array: ?Array<T>): Array<T>;
unzipWith<T>(array: ?Array<T>, iteratee?: Iteratee<T>): Array<T>;
without<T>(array: ?Array<T>, ...values?: Array<T>): Array<T>;
xor<T>(...array: Array<Array<T>>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
xorBy<T>(a1: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
xorBy<T>(a1: Array<T>, a2: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
xorBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
xorBy<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, iteratee?: ValueOnlyIteratee<T>): Array<T>;
//Workaround until (...parameter: T, parameter2: U) works
xorWith<T>(a1: Array<T>, comparator?: Comparator<T>): Array<T>;
xorWith<T>(a1: Array<T>, a2: Array<T>, comparator?: Comparator<T>): Array<T>;
xorWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, comparator?: Comparator<T>): Array<T>;
xorWith<T>(a1: Array<T>, a2: Array<T>, a3: Array<T>, a4: Array<T>, comparator?: Comparator<T>): Array<T>;
zip<A, B>(a1: A[], a2: B[]): Array<[A, B]>;
zip<A, B, C>(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>;
zip<A, B, C, D>(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>;
zip<A, B, C, D, E>(a1: A[], a2: B[], a3: C[], a4: D[], a5: E[]): Array<[A, B, C, D, E]>;
zipObject(props?: Array<any>, values?: Array<any>): Object;
zipObjectDeep(props?: any[], values?: any): Object;
//Workaround until (...parameter: T, parameter2: U) works
zipWith<T>(a1: NestedArray<T>, iteratee?: Iteratee<T>): Array<T>;
zipWith<T>(a1: NestedArray<T>, a2: NestedArray<T>, iteratee?: Iteratee<T>): Array<T>;
zipWith<T>(a1: NestedArray<T>, a2: NestedArray<T>, a3: NestedArray<T>, iteratee?: Iteratee<T>): Array<T>;
zipWith<T>(a1: NestedArray<T>, a2: NestedArray<T>, a3: NestedArray<T>, a4: NestedArray<T>, iteratee?: Iteratee<T>): Array<T>;
// Collection
countBy<T>(array: ?Array<T>, iteratee?: ValueOnlyIteratee<T>): Object;
countBy<T: Object>(object: T, iteratee?: ValueOnlyIteratee<T>): Object;
// alias of _.forEach
each<T>(array: ?Array<T>, iteratee?: Iteratee<T>): Array<T>;
each<T: Object>(object: T, iteratee?: OIteratee<T>): T;
// alias of _.forEachRight
eachRight<T>(array: ?Array<T>, iteratee?: Iteratee<T>): Array<T>;
eachRight<T: Object>(object: T, iteratee?: OIteratee<T>): T;
every<T>(array: ?Array<T>, iteratee?: Iteratee<T>): bool;
every<T: Object>(object: T, iteratee?: OIteratee<T>): bool;
filter<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
filter<A, T: {[id: string]: A}>(object: T, predicate?: OPredicate<A, T>): Array<A>;
find<T>(array: ?Array<T>, predicate?: Predicate<T>, fromIndex?: number): T|void;
find<V, A, T: {[id: string]: A}>(object: T, predicate?: OPredicate<A, T>, fromIndex?: number): V;
findLast<T>(array: ?Array<T>, predicate?: Predicate<T>, fromIndex?: number): T|void;
findLast<V, A, T: {[id: string]: A}>(object: T, predicate?: OPredicate<A, T>): V;
flatMap<T, U>(array: ?Array<T>, iteratee?: FlatMapIteratee<T, U>): Array<U>;
flatMap<T: Object, U>(object: T, iteratee?: OFlatMapIteratee<T, U>): Array<U>;
flatMapDeep<T, U>(array: ?Array<T>, iteratee?: FlatMapIteratee<T, U>): Array<U>;
flatMapDeep<T: Object, U>(object: T, iteratee?: OFlatMapIteratee<T, U>): Array<U>;
flatMapDepth<T, U>(array: ?Array<T>, iteratee?: FlatMapIteratee<T, U>, depth?: number): Array<U>;
flatMapDepth<T: Object, U>(object: T, iteratee?: OFlatMapIteratee<T, U>, depth?: number): Array<U>;
forEach<T>(array: ?Array<T>, iteratee?: Iteratee<T>): Array<T>;
forEach<T: Object>(object: T, iteratee?: OIteratee<T>): T;
forEachRight<T>(array: ?Array<T>, iteratee?: Iteratee<T>): Array<T>;
forEachRight<T: Object>(object: T, iteratee?: OIteratee<T>): T;
groupBy<V, T>(array: ?Array<T>, iteratee?: ValueOnlyIteratee<T>): {[key: V]: Array<T>};
groupBy<V, A, T: {[id: string]: A}>(object: T, iteratee?: ValueOnlyIteratee<A>): {[key: V]: Array<A>};
includes<T>(array: ?Array<T>, value: T, fromIndex?: number): bool;
includes<T: Object>(object: T, value: any, fromIndex?: number): bool;
includes(str: string, value: string, fromIndex?: number): bool;
invokeMap<T>(array: ?Array<T>, path: ((value: T) => Array<string>|string)|Array<string>|string, ...args?: Array<any>): Array<any>;
invokeMap<T: Object>(object: T, path: ((value: any) => Array<string>|string)|Array<string>|string, ...args?: Array<any>): Array<any>;
keyBy<T, V>(array: ?Array<T>, iteratee?: ValueOnlyIteratee<T>): {[key: V]: ?T};
keyBy<V, A, I, T: {[id: I]: A}>(object: T, iteratee?: ValueOnlyIteratee<A>): {[key: V]: ?A};
map<T, U>(array: ?Array<T>, iteratee?: MapIterator<T, U>): Array<U>;
map<V, T: Object, U>(object: ?T, iteratee?: OMapIterator<V, T, U>): Array<U>;
map(str: ?string, iteratee?: (char: string, index: number, str: string) => any): string;
orderBy<T>(array: ?Array<T>, iteratees?: Array<Iteratee<T>>|string, orders?: Array<'asc'|'desc'>|string): Array<T>;
orderBy<V, T: Object>(object: T, iteratees?: Array<OIteratee<*>>|string, orders?: Array<'asc'|'desc'>|string): Array<V>;
partition<T>(array: ?Array<T>, predicate?: Predicate<T>): NestedArray<T>;
partition<V, A, T: {[id: string]: A}>(object: T, predicate?: OPredicate<A, T>): NestedArray<V>;
reduce<T, U>(array: ?Array<T>, iteratee?: (accumulator: U, value: T, index: number, array: ?Array<T>) => U, accumulator?: U): U;
reduce<T: Object, U>(object: T, iteratee?: (accumulator: U, value: any, key: string, object: T) => U, accumulator?: U): U;
reduceRight<T, U>(array: ?Array<T>, iteratee?: (accumulator: U, value: T, index: number, array: ?Array<T>) => U, accumulator?: U): U;
reduceRight<T: Object, U>(object: T, iteratee?: (accumulator: U, value: any, key: string, object: T) => U, accumulator?: U): U;
reject<T>(array: ?Array<T>, predicate?: Predicate<T>): Array<T>;
reject<V: Object, A, T: {[id: string]: A}>(object: T, predicate?: OPredicate<A, T>): Array<V>;
sample<T>(array: ?Array<T>): T;
sample<V, T: Object>(object: T): V;
sampleSize<T>(array: ?Array<T>, n?: number): Array<T>;
sampleSize<V, T: Object>(object: T, n?: number): Array<V>;
shuffle<T>(array: ?Array<T>): Array<T>;
shuffle<V, T: Object>(object: T): Array<V>;
size(collection: Array<any>|Object): number;
some<T>(array: ?Array<T>, predicate?: Predicate<T>): bool;
some<A, T: {[id: string]: A}>(object?: ?T, predicate?: OPredicate<A, T>): bool;
sortBy<T>(array: ?Array<T>, ...iteratees?: Array<Iteratee<T>>): Array<T>;
sortBy<T>(array: ?Array<T>, iteratees?: Array<Iteratee<T>>): Array<T>;
sortBy<V, T: Object>(object: T, ...iteratees?: Array<OIteratee<T>>): Array<V>;
sortBy<V, T: Object>(object: T, iteratees?: Array<OIteratee<T>>): Array<V>;
// Date
now(): number;
// Function
after(n: number, fn: Function): Function;
ary(func: Function, n?: number): Function;
before(n: number, fn: Function): Function;
bind(func: Function, thisArg: any, ...partials: Array<any>): Function;
bindKey(obj: Object, key: string, ...partials: Array<any>): Function;
curry(func: Function, arity?: number): Function;
curryRight(func: Function, arity?: number): Function;
debounce(func: Function, wait?: number, options?: DebounceOptions): Function;
defer(func: Function, ...args?: Array<any>): number;
delay(func: Function, wait: number, ...args?: Array<any>): number;
flip(func: Function): Function;
memoize(func: Function, resolver?: Function): Function;
negate(predicate: Function): Function;
once(func: Function): Function;
overArgs(func: Function, ...transforms: Array<Function>): Function;
overArgs(func: Function, transforms: Array<Function>): Function;
partial(func: Function, ...partials: any[]): Function;
partialRight(func: Function, ...partials: Array<any>): Function;
partialRight(func: Function, partials: Array<any>): Function;
rearg(func: Function, ...indexes: Array<number>): Function;
rearg(func: Function, indexes: Array<number>): Function;
rest(func: Function, start?: number): Function;
spread(func: Function): Function;
throttle(func: Function, wait?: number, options?: ThrottleOptions): Function;
unary(func: Function): Function;
wrap(value: any, wrapper: Function): Function;
// Lang
castArray(value: *): any[];
clone<T>(value: T): T;
cloneDeep<T>(value: T): T;
cloneDeepWith<T, U>(value: T, customizer?: ?(value: T, key: number|string, object: T, stack: any) => U): U;
cloneWith<T, U>(value: T, customizer?: ?(value: T, key: number|string, object: T, stack: any) => U): U;
conformsTo<T:{[key:string]:mixed}>(source: T, predicates: T&{[key:string]:(x:any)=>boolean}): boolean;
eq(value: any, other: any): bool;
gt(value: any, other: any): bool;
gte(value: any, other: any): bool;
isArguments(value: any): bool;
isArray(value: any): bool;
isArrayBuffer(value: any): bool;
isArrayLike(value: any): bool;
isArrayLikeObject(value: any): bool;
isBoolean(value: any): bool;
isBuffer(value: any): bool;
isDate(value: any): bool;
isElement(value: any): bool;
isEmpty(value: any): bool;
isEqual(value: any, other: any): bool;
isEqualWith<T, U>(value: T, other: U, customizer?: (objValue: any, otherValue: any, key: number|string, object: T, other: U, stack: any) => bool|void): bool;
isError(value: any): bool;
isFinite(value: any): bool;
isFunction(value: Function): true;
isFunction(value: number|string|void|null|Object): false;
isInteger(value: any): bool;
isLength(value: any): bool;
isMap(value: any): bool;
isMatch(object?: ?Object, source: Object): bool;
isMatchWith<T: Object, U: Object>(object: T, source: U, customizer?: (objValue: any, srcValue: any, key: number|string, object: T, source: U) => bool|void): bool;
isNaN(value: any): bool;
isNative(value: any): bool;
isNil(value: any): bool;
isNull(value: any): bool;
isNumber(value: any): bool;
isObject(value: any): bool;
isObjectLike(value: any): bool;
isPlainObject(value: any): bool;
isRegExp(value: any): bool;
isSafeInteger(value: any): bool;
isSet(value: any): bool;
isString(value: string): true;
isString(value: number|bool|Function|void|null|Object|Array<any>): false;
isSymbol(value: any): bool;
isTypedArray(value: any): bool;
isUndefined(value: any): bool;
isWeakMap(value: any): bool;
isWeakSet(value: any): bool;
lt(value: any, other: any): bool;
lte(value: any, other: any): bool;
toArray(value: any): Array<any>;
toFinite(value: any): number;
toInteger(value: any): number;
toLength(value: any): number;
toNumber(value: any): number;
toPlainObject(value: any): Object;
toSafeInteger(value: any): number;
toString(value: any): string;
// Math
add(augend: number, addend: number): number;
ceil(number: number, precision?: number): number;
divide(dividend: number, divisor: number): number;
floor(number: number, precision?: number): number;
max<T>(array: ?Array<T>): T;
maxBy<T>(array: ?Array<T>, iteratee?: Iteratee<T>): T;
mean(array: Array<*>): number;
meanBy<T>(array: Array<T>, iteratee?: Iteratee<T>): number;
min<T>(array: ?Array<T>): T;
minBy<T>(array: ?Array<T>, iteratee?: Iteratee<T>): T;
multiply(multiplier: number, multiplicand: number): number;
round(number: number, precision?: number): number;
subtract(minuend: number, subtrahend: number): number;
sum(array: Array<*>): number;
sumBy<T>(array: Array<T>, iteratee?: Iteratee<T>): number;
// number
clamp(number: number, lower?: number, upper: number): number;
inRange(number: number, start?: number, end: number): bool;
random(lower?: number, upper?: number, floating?: bool): number;
// Object
assign(object?: ?Object, ...sources?: Array<Object>): Object;
assignIn<A, B>(a: A, b: B): A & B;
assignIn<A, B, C>(a: A, b: B, c: C): A & B & C;
assignIn<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
assignIn<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E;
assignInWith<T: Object, A: Object>(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object;
assignInWith<T: Object, A: Object, B: Object>(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object;
assignInWith<T: Object, A: Object, B: Object, C: Object>(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object;
assignInWith<T: Object, A: Object, B: Object, C: Object, D: Object>(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object;
assignWith<T: Object, A: Object>(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object;
assignWith<T: Object, A: Object, B: Object>(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object;
assignWith<T: Object, A: Object, B: Object, C: Object>(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object;
assignWith<T: Object, A: Object, B: Object, C: Object, D: Object>(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object;
at(object?: ?Object, ...paths: Array<string>): Array<any>;
at(object?: ?Object, paths: Array<string>): Array<any>;
create<T>(prototype: T, properties?: Object): $Supertype<T>;
defaults(object?: ?Object, ...sources?: Array<Object>): Object;
defaultsDeep(object?: ?Object, ...sources?: Array<Object>): Object;
// alias for _.toPairs
entries(object?: ?Object): NestedArray<any>;
// alias for _.toPairsIn
entriesIn(object?: ?Object): NestedArray<any>;
// alias for _.assignIn
extend<A, B>(a: A, b: B): A & B;
extend<A, B, C>(a: A, b: B, c: C): A & B & C;
extend<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
extend<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E;
// alias for _.assignInWith
extendWith<T: Object, A: Object>(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object;
extendWith<T: Object, A: Object, B: Object>(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object;
extendWith<T: Object, A: Object, B: Object, C: Object>(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object;
extendWith<T: Object, A: Object, B: Object, C: Object, D: Object>(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object;
findKey<A, T: {[id: string]: A}>(object?: ?T, predicate?: OPredicate<A, T>): string|void;
findLastKey<A, T: {[id: string]: A}>(object?: ?T, predicate?: OPredicate<A, T>): string|void;
forIn(object?: ?Object, iteratee?: OIteratee<*>): Object;
forInRight(object?: ?Object, iteratee?: OIteratee<*>): Object;
forOwn(object?: ?Object, iteratee?: OIteratee<*>): Object;
forOwnRight(object?: ?Object, iteratee?: OIteratee<*>): Object;
functions(object?: ?Object): Array<string>;
functionsIn(object?: ?Object): Array<string>;
get(object?: ?Object|?Array<any>, path?: ?Array<string>|string, defaultValue?: any): any;
has(object?: ?Object, path?: ?Array<string>|string): bool;
hasIn(object?: ?Object, path?: ?Array<string>|string): bool;
invert(object?: ?Object, multiVal?: bool): Object;
invertBy(object: ?Object, iteratee?: Function): Object;
invoke(object?: ?Object, path?: ?Array<string>|string, ...args?: Array<any>): any;
keys(object?: ?Object): Array<string>;
keysIn(object?: ?Object): Array<string>;
mapKeys(object?: ?Object, iteratee?: OIteratee<*>): Object;
mapValues(object?: ?Object, iteratee?: OIteratee<*>): Object;
merge(object?: ?Object, ...sources?: Array<?Object>): Object;
mergeWith<T: Object, A: Object>(object: T, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object;
mergeWith<T: Object, A: Object, B: Object>(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object;
mergeWith<T: Object, A: Object, B: Object, C: Object>(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object;
mergeWith<T: Object, A: Object, B: Object, C: Object, D: Object>(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object;
omit(object?: ?Object, ...props: Array<string>): Object;
omit(object?: ?Object, props: Array<string>): Object;
omitBy<A, T: {[id: string]: A}>(object?: ?T, predicate?: OPredicate<A, T>): Object;
pick(object?: ?Object, ...props: Array<string>): Object;
pick(object?: ?Object, props: Array<string>): Object;
pickBy<A, T: {[id: string]: A}>(object?: ?T, predicate?: OPredicate<A, T>): Object;
result(object?: ?Object, path?: ?Array<string>|string, defaultValue?: any): any;
set(object?: ?Object, path?: ?Array<string>|string, value: any): Object;
setWith<T>(object: T, path?: ?Array<string>|string, value: any, customizer?: (nsValue: any, key: string, nsObject: T) => any): Object;
toPairs(object?: ?Object|Array<*>): NestedArray<any>;
toPairsIn(object?: ?Object): NestedArray<any>;
transform(collection: Object|Array<any>, iteratee?: OIteratee<*>, accumulator?: any): any;
unset(object?: ?Object, path?: ?Array<string>|string): bool;
update(object: Object, path: string[]|string, updater: Function): Object;
updateWith(object: Object, path: string[]|string, updater: Function, customizer?: Function): Object;
values(object?: ?Object): Array<any>;
valuesIn(object?: ?Object): Array<any>;
// Seq
// harder to read, but this is _()
(value: any): any;
chain<T>(value: T): any;
tap<T>(value: T, interceptor: (value:T)=>any): T;
thru<T1,T2>(value: T1, interceptor: (value:T1)=>T2): T2;
// TODO: _.prototype.*
// String
camelCase(string?: ?string): string;
capitalize(string?: string): string;
deburr(string?: string): string;
endsWith(string?: string, target?: string, position?: number): bool;
escape(string?: string): string;
escapeRegExp(string?: string): string;
kebabCase(string?: string): string;
lowerCase(string?: string): string;
lowerFirst(string?: string): string;
pad(string?: string, length?: number, chars?: string): string;
padEnd(string?: string, length?: number, chars?: string): string;
padStart(string?: string, length?: number, chars?: string): string;
parseInt(string: string, radix?: number): number;
repeat(string?: string, n?: number): string;
replace(string?: string, pattern: RegExp|string, replacement: ((string: string) => string)|string): string;
snakeCase(string?: string): string;
split(string?: string, separator: RegExp|string, limit?: number): Array<string>;
startCase(string?: string): string;
startsWith(string?: string, target?: string, position?: number): bool;
template(string?: string, options?: TemplateSettings): Function;
toLower(string?: string): string;
toUpper(string?: string): string;
trim(string?: string, chars?: string): string;
trimEnd(string?: string, chars?: string): string;
trimStart(string?: string, chars?: string): string;
truncate(string?: string, options?: TruncateOptions): string;
unescape(string?: string): string;
upperCase(string?: string): string;
upperFirst(string?: string): string;
words(string?: string, pattern?: RegExp|string): Array<string>;
// Util
attempt(func: Function): any;
bindAll(object?: ?Object, methodNames: Array<string>): Object;
bindAll(object?: ?Object, ...methodNames: Array<string>): Object;
cond(pairs: NestedArray<Function>): Function;
conforms(source: Object): Function;
constant<T>(value: T): () => T;
defaultTo<T1:string|boolean|Object,T2>(value: T1, default: T2): T1;
// NaN is a number instead of its own type, otherwise it would behave like null/void
defaultTo<T1:number,T2>(value: T1, default: T2): T1|T2;
defaultTo<T1:void|null,T2>(value: T1, default: T2): T2;
flow(...funcs?: Array<Function>): Function;
flow(funcs?: Array<Function>): Function;
flowRight(...funcs?: Array<Function>): Function;
flowRight(funcs?: Array<Function>): Function;
identity<T>(value: T): T;
iteratee(func?: any): Function;
matches(source: Object): Function;
matchesProperty(path?: ?Array<string>|string, srcValue: any): Function;
method(path?: ?Array<string>|string, ...args?: Array<any>): Function;
methodOf(object?: ?Object, ...args?: Array<any>): Function;
mixin<T: Function|Object>(object?: T, source: Object, options?: { chain: bool }): T;
noConflict(): Lodash;
noop(...args: Array<mixed>): void;
nthArg(n?: number): Function;
over(...iteratees: Array<Function>): Function;
over(iteratees: Array<Function>): Function;
overEvery(...predicates: Array<Function>): Function;
overEvery(predicates: Array<Function>): Function;
overSome(...predicates: Array<Function>): Function;
overSome(predicates: Array<Function>): Function;
property(path?: ?Array<string>|string): Function;
propertyOf(object?: ?Object): Function;
range(start: number, end: number, step?: number): Array<number>;
range(end: number, step?: number): Array<number>;
rangeRight(start: number, end: number, step?: number): Array<number>;
rangeRight(end: number, step?: number): Array<number>;
runInContext(context?: Object): Function;
stubArray(): Array<*>;
stubFalse(): false;
stubObject(): {};
stubString(): '';
stubTrue(): true;
times(n: number, ...rest: Array<void>): Array<number>;
times<T>(n: number, iteratee: ((i: number) => T)): Array<T>;
toPath(value: any): Array<string>;
uniqueId(prefix?: string): string;
// Properties
VERSION: string;
templateSettings: TemplateSettings;
}
declare var exports: Lodash;
}

12
jest.config.js Normal file
View File

@ -0,0 +1,12 @@
/* eslint comma-dangle: 0 */
module.exports = {
'name': 'verdaccio-jest',
'verbose': true,
'collectCoverage': true,
'coveragePathIgnorePatterns': [
'node_modules',
'fixtures'
],
'testRegex': '(/test/unit/.*\\.spec)\\.js'
};

1
jestEnvironment.js Normal file
View File

@ -0,0 +1 @@
require.requireActual('babel/polyfill');

View File

@ -54,6 +54,7 @@
"babel-core": "6.26.0",
"babel-eslint": "8.0.3",
"babel-jest": "^21.2.0",
"babel-jest": "^21.2.0",
"babel-loader": "7.1.2",
"babel-plugin-flow-runtime": "0.15.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
@ -77,6 +78,8 @@
"css-loader": "0.28.7",
"element-react": "1.4.3",
"element-theme-default": "1.4.12",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.2",
"eslint": "4.12.1",
"eslint-config-google": "0.9.1",
"eslint-loader": "1.9.0",
@ -84,6 +87,7 @@
"eslint-plugin-flowtype": "2.39.1",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-react": "7.5.1",
"eslint-plugin-jest": "^21.2.0",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"flow-bin": "0.52.0",
@ -93,12 +97,11 @@
"github-markdown-css": "2.9.0",
"html-webpack-plugin": "2.30.1",
"in-publish": "2.0.0",
"jest": "^21.2.1",
"jest-serializer-enzyme": "^1.0.0",
"localstorage-memory": "1.0.2",
"mocha": "3.5.3",
"mocha-lcov-reporter": "1.3.0",
"node-sass": "4.7.2",
"normalize.css": "7.0.0",
"nyc": "11.3.0",
"ora": "1.3.0",
"prop-types": "15.6.0",
"react": "16.2.0",
@ -134,13 +137,10 @@
"release": "standard-version -a -s",
"prepublish": "in-publish && npm run build:webui || not-in-publish",
"flow": "flow",
"test": "cross-env BABEL_ENV=registry mocha --require babel-register ./test/functional ./test/unit --reporter=spec --full-trace",
"test": "cross-env jest",
"pre:ci": "npm run build:webui",
"test:ci": "npm run test:coverage",
"test:only": "mocha ./test/functional ./test/unit",
"test:coverage": "nyc npm t",
"coverage:html": "nyc report --reporter=html",
"coverage:publish": "nyc report --reporter=lcov | codecov",
"coverage:publish": "codecov",
"lint": "eslint .",
"lint:css": "stylelint 'src/**/*.scss' --syntax scss",
"dev:start": "cross-env BABEL_ENV=registry babel-node src/lib/cli",
@ -151,14 +151,9 @@
"build:docker": "docker build -t verdaccio . --no-cache",
"build:docker:rpi": "docker build -f Dockerfile.rpi -t verdaccio:rpi ."
},
"jest": {
"snapshotSerializers": [
"jest-serializer-enzyme"
]
},
"engines": {
"node": ">=4.6.1",
"npm": ">=2.15.9"
"npm": ">=3"
},
"preferGlobal": true,
"publishConfig": {

View File

@ -1,7 +0,0 @@
All tests are split in three folders:
- `unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry.
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.

View File

@ -1,4 +0,0 @@
--reporter spec
--timeout 20000
--full-trace
--colors

View File

@ -7,25 +7,31 @@ const rimraf = require('rimraf');
const verdaccio = require('../../');
const config = require('./partials/config');
describe('basic system test', function() {
const app = express();
const server = require('http').createServer(app);
describe('basic system test', () => {
let port;
before(function(done) {
beforeAll(function(done) {
rimraf(__dirname + '/store/test-storage', done);
});
before(function(done) {
let app = express();
beforeAll(function(done) {
app.use(verdaccio(config));
const server = require('http').createServer(app);
server.listen(0, function() {
port = server.address().port;
done();
});
});
it('server should respond on /', function(done) {
afterAll((done) => {
server.close(done);
});
test('server should respond on /', done => {
request({
url: 'http://localhost:' + port + '/',
}, function(err, res, body) {
@ -35,7 +41,7 @@ describe('basic system test', function() {
});
});
it('server should respond on /whatever', function(done) {
test('server should respond on /whatever', done => {
request({
url: 'http://localhost:' + port + '/whatever',
}, function(err, res, body) {

View File

@ -25,14 +25,14 @@ const checkPackages = (config) => {
assert.equal(config.uplinks['npmjs'].url, 'https://registry.npmjs.org');
};
describe('Config file', function() {
before(function() {
describe('Config file', () => {
beforeAll(function() {
this.config = new Config(Utils.parseConfigFile(resolveConf('full')));
});
describe('Config file', () => {
it('parse full.yaml', () => {
test('parse full.yaml', () => {
const config = new Config(Utils.parseConfigFile(resolveConf('full')));
checkUplink(config);
assert.equal(config.storage, './storage');
@ -40,14 +40,14 @@ describe('Config file', function() {
checkPackages(config);
});
it('parse docker.yaml', () => {
test('parse docker.yaml', () => {
const config = new Config(Utils.parseConfigFile(resolveConf('docker')));
checkUplink(config);
assert.equal(config.storage, '/verdaccio/storage');
assert.equal(config.auth.htpasswd.file, '/verdaccio/conf/htpasswd');
});
it('parse default.yaml', () => {
test('parse default.yaml', () => {
const config = new Config(Utils.parseConfigFile(resolveConf('default')));
checkUplink(config);
assert.equal(config.storage, './storage');

View File

@ -4,9 +4,9 @@ const assert = require('assert');
const _ = require('lodash');
const parse = require('../../src/lib/utils').parse_address;
describe('Parse listen address', function() {
describe('Parse listen address', () => {
function addTest(what, proto, host, port) {
it(what, function() {
test(what, () => {
if (_.isNull(proto)) {
assert.strictEqual(parse(what), null);
} else if (port) {

View File

@ -1,81 +0,0 @@
// 'use strict';
//
// const assert = require('assert');
// const LocalData = require('../../src/lib/storage/local/local-data');
// const path = require('path');
// const _ = require('lodash');
// const fs = require('fs-extra');
//
//
// describe('Local Database', function() {
//
// const buildCorruptedPath = () => path.join(__dirname, './partials/storage/verdaccio-corrupted.db.json');
// const buildValidDbPath = () => path.join(__dirname, './partials/storage/verdaccio.db.json');
//
// describe('reading database', () => {
//
// it('should return empty database on read corrupted database', () => {
// const dataLocal = new LocalData(buildCorruptedPath());
//
// assert(_.isEmpty(dataLocal.data.list));
// });
//
// it('should return a database on read valid database', () => {
// const dataLocal = new LocalData(buildValidDbPath());
//
// assert(_.isEmpty(dataLocal.data.list) === false);
// });
//
// it('should fails on sync a corrupted database', () => {
// const dataLocal = new LocalData(buildCorruptedPath());
// const error = dataLocal.sync();
//
// assert(_.isError(error));
// assert(error.message.match(/locked/));
// assert(dataLocal.locked);
// });
//
// });
//
// describe('add/remove packages to database', () => {
// it('should add a new package to local database', () => {
// const dataLocal = new LocalData(buildCorruptedPath());
// assert(_.isEmpty(dataLocal.data.list));
// dataLocal.add('package1');
// assert(!_.isEmpty(dataLocal.data.list));
// });
//
// it('should remove a new package to local database', () => {
// const dataLocal = new LocalData(buildCorruptedPath());
// const pkgName = 'package1';
//
// assert(_.isEmpty(dataLocal.data.list));
// dataLocal.add(pkgName);
// dataLocal.remove(pkgName);
// assert(_.isEmpty(dataLocal.data.list));
// });
// });
//
// describe('sync packages to database', () => {
// beforeEach(function() {
// this.newDb = path.join(__dirname, './test-storage/verdaccio.temp.db.json');
// fs.copySync(buildValidDbPath(), this.newDb);
// });
//
// it('should check sync packages', function() {
// const localData1 = new LocalData(this.newDb);
//
// localData1.add('package1');
//
// const localData2 = new LocalData(this.newDb);
//
// assert(_.isEmpty(localData2.data.list) === false);
// assert(localData2.data.list.length === 2);
//
// });
//
//
// });
//
// });
//

View File

@ -10,18 +10,18 @@ function setupProxy(host, config, mainconfig) {
return new Storage(config, mainconfig);
}
describe('Use proxy', function() {
it('should work fine without proxy', function() {
describe('Use proxy', () => {
test('should work fine without proxy', () => {
let x = setupProxy('http://x/x', {}, {});
assert.equal(x.proxy, null);
});
it('local config should take priority', function() {
test('local config should take priority', () => {
let x = setupProxy('http://x/x', {http_proxy: '123'}, {http_proxy: '456'});
assert.equal(x.proxy, '123');
});
it('no_proxy is invalid', function() {
test('no_proxy is invalid', () => {
let x = setupProxy('http://x/x', {http_proxy: '123', no_proxy: false}, {});
assert.equal(x.proxy, '123');
x = setupProxy('http://x/x', {http_proxy: '123', no_proxy: null}, {});
@ -32,17 +32,17 @@ describe('Use proxy', function() {
assert.equal(x.proxy, '123');
});
it('no_proxy - simple/include', function() {
test('no_proxy - simple/include', () => {
let x = setupProxy('http://localhost', {http_proxy: '123'}, {no_proxy: 'localhost'});
assert.equal(x.proxy, undefined);
});
it('no_proxy - simple/not', function() {
test('no_proxy - simple/not', () => {
let x = setupProxy('http://localhost', {http_proxy: '123'}, {no_proxy: 'blah'});
assert.equal(x.proxy, '123');
});
it('no_proxy - various, single string', function() {
test('no_proxy - various, single string', () => {
let x = setupProxy('http://blahblah', {http_proxy: '123'}, {no_proxy: 'blah'});
assert.equal(x.proxy, '123');
x = setupProxy('http://blah.blah', {}, {http_proxy: '123', no_proxy: 'blah'});
@ -57,7 +57,7 @@ describe('Use proxy', function() {
assert.equal(x.proxy, '123');
});
it('no_proxy - various, array', function() {
test('no_proxy - various, array', () => {
let x = setupProxy('http://blahblah', {http_proxy: '123'}, {no_proxy: 'foo,bar,blah'});
assert.equal(x.proxy, '123');
x = setupProxy('http://blah.blah', {http_proxy: '123'}, {no_proxy: 'foo,bar,blah'});
@ -72,14 +72,14 @@ describe('Use proxy', function() {
assert.equal(x.proxy, null);
});
it('no_proxy - hostport', function() {
test('no_proxy - hostport', () => {
let x = setupProxy('http://localhost:80', {http_proxy: '123'}, {no_proxy: 'localhost'});
assert.equal(x.proxy, null);
x = setupProxy('http://localhost:8080', {http_proxy: '123'}, {no_proxy: 'localhost'});
assert.equal(x.proxy, null);
});
it('no_proxy - secure', function() {
test('no_proxy - secure', () => {
let x = setupProxy('https://something', {http_proxy: '123'}, {});
assert.equal(x.proxy, null);
x = setupProxy('https://something', {https_proxy: '123'}, {});

View File

@ -3,9 +3,9 @@
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('Parse interval', function() {
describe('Parse interval', () => {
function add_test(str, res) {
it('parse ' + str, function() {
test('parse ' + str, () => {
if (res === null) {
assert.throws(function() {
console.log(parseInterval(str));

View File

@ -1,12 +1,13 @@
'use strict';
require('../../src/lib/logger').setup([]);
const assert = require('assert');
const load_plugins = require('../../src/lib/plugin-loader').load_plugins;
const path = require('path');
describe('plugin loader', function() {
describe('plugin loader', () => {
it('testing auth valid plugin loader', function() {
test('testing auth valid plugin loader', () => {
let _config = {
self_path: path.join(__dirname, './'),
max_users: 0,
@ -20,7 +21,7 @@ describe('plugin loader', function() {
assert(p.length === 1);
});
it('testing auth plugin invalid plugin', function() {
test('testing auth plugin invalid plugin', () => {
let _config = {
self_path: path.join(__dirname, './'),
auth: {
@ -36,7 +37,7 @@ describe('plugin loader', function() {
}
});
it('testing auth plugin invalid plugin sanityCheck', function() {
test('testing auth plugin invalid plugin sanityCheck', () => {
let _config = {
self_path: path.join(__dirname, './'),
auth: {
@ -52,7 +53,7 @@ describe('plugin loader', function() {
}
});
it('testing auth plugin no plugins', function() {
test('testing auth plugin no plugins', () => {
let _config = {
self_path: path.join(__dirname, './'),
auth: {

View File

@ -32,8 +32,8 @@ let packages = [
},
];
describe('search', function() {
before(function() {
describe('search', () => {
beforeAll(function() {
let config = new Config(config_hash);
this.storage = new Storage(config);
Search.configureStorage(this.storage);
@ -42,12 +42,12 @@ describe('search', function() {
});
});
it('search query item', function() {
test('search query item', () => {
let result = Search.query('t');
assert(result.length === 3);
});
it('search remove item', function() {
test('search remove item', () => {
let item = {
name: 'test6',
description: 'description',

View File

@ -6,9 +6,9 @@ let merge = require('../../src/lib/storage')._merge_versions;
require('../../src/lib/logger').setup([]);
describe('merge versions', function() {
describe('merge versions', () => {
it('simple', function() {
test('simple', () => {
let pkg = {
'versions': {a: 1, b: 1, c: 1},
'dist-tags': {},
@ -22,7 +22,7 @@ describe('merge versions', function() {
});
});
it('dist-tags - compat', function() {
test('dist-tags - compat', () => {
let pkg = {
'versions': {},
'dist-tags': {q: '1.1.1', w: '2.2.2'},
@ -36,7 +36,7 @@ describe('merge versions', function() {
});
});
it('dist-tags - staging', function() {
test('dist-tags - staging', () => {
let pkg = {
versions: {},
@ -57,7 +57,7 @@ describe('merge versions', function() {
});
it('semver_sort', function() {
test('semver_sort', () => {
assert.deepEqual(semver_sort(['1.2.3', '1.2', '1.2.3a', '1.2.3c', '1.2.3-b']),
['1.2.3a',

View File

@ -5,8 +5,8 @@ let tag_version = require('../../src/lib/utils').tag_version;
require('../../src/lib/logger').setup([]);
describe('tag_version', function() {
it('add new one', function() {
describe('tag_version', () => {
test('add new one', () => {
let pkg = {
'versions': {},
'dist-tags': {},
@ -18,7 +18,7 @@ describe('tag_version', function() {
});
});
it('add (compat)', function() {
test('add (compat)', () => {
const x = {
'versions': {},
'dist-tags': {foo: '1.1.0'},
@ -30,7 +30,7 @@ describe('tag_version', function() {
});
});
it('add fresh tag', function() {
test('add fresh tag', () => {
let x = {
'versions': {},
'dist-tags': {foo: '1.1.0'},

View File

@ -3,38 +3,38 @@
let assert = require('assert');
let validate = require('../../src/lib/utils').validate_name;
describe('Validate', function() {
it('good ones', function() {
describe('Validate', () => {
test('good ones', () => {
assert( validate('verdaccio') );
assert( validate('some.weird.package-zzz') );
assert( validate('old-package@0.1.2.tgz') );
});
it('uppercase', function() {
test('uppercase', () => {
assert( validate('EVE') );
assert( validate('JSONStream') );
});
it('no package.json', function() {
test('no package.json', () => {
assert( !validate('package.json') );
});
it('no path seps', function() {
test('no path seps', () => {
assert( !validate('some/thing') );
assert( !validate('some\\thing') );
});
it('no hidden', function() {
test('no hidden', () => {
assert( !validate('.bin') );
});
it('no reserved', function() {
test('no reserved', () => {
assert( !validate('favicon.ico') );
assert( !validate('node_modules') );
assert( !validate('__proto__') );
});
it('other', function() {
test('other', () => {
assert( !validate('pk g') );
assert( !validate('pk\tg') );
assert( !validate('pk%20g') );

View File

@ -14,9 +14,9 @@ const path = require('path');
app.param('revision', validate_name);
app.param('token', validate_name);
*/
describe('api endpoint app.param()', test('../endpoint/index.js'));
describe('api endpoint app.param()', runTest('../endpoint/index.js'));
function test(file) {
function runTest(file) {
return function() {
let requirePath = path.normalize(path.join(__dirname + '/../../src/api/web/', file));
@ -43,11 +43,12 @@ function test(file) {
});
}
Object.keys(appParams).forEach(function(param) {
it('should validate ":'+param+'"', function() {
assert.equal(appParams[param], 'ok');
Object.keys(appParams).forEach(function(param) {
test('should validate ":'+param+'"', () => {
assert.equal(appParams[param], 'ok');
});
});
});
};
}

4985
yarn.lock

File diff suppressed because it is too large Load Diff