diff --git a/.circleci/config.yml b/.circleci/config.yml index 7a0a4d0f6e..764e5c2b6c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,9 +43,14 @@ jobs: - run: name: Prettier command: yarn prettier + # weak package is required for --detectLeaks in Unit tests + # it is not in package.json as it would require Python on Windows + - run: + name: Install weak + command: yarn add --dev weak - run: name: Unit Tests - command: yarn test --strict --maxWorkers=4 + command: yarn test --strict --maxWorkers=4 --detectLeaks - run: name: Report coverage command: bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa7c2ce3e0..78a0d75f7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixes - Fix focus outline visible only during keyboard navigation in `ListItem` @layershifter ([#727](https://github.com/stardust-ui/react/pull/727)) +- Pass `jest --detectLeaks` tests @miroslavstastny ([#718](https://github.com/stardust-ui/react/pull/718)) - Fix Avatar's size example @mnajdova ([#745](https://github.com/stardust-ui/react/pull/745)) ### Features @@ -35,15 +36,15 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixes - Remove `render` from default factories options @layershifter ([#735](https://github.com/stardust-ui/react/pull/735)) +### Features +- Add accessibility for submenu in toolbar and menu behavior @kolaps33 ([#686](https://github.com/stardust-ui/react/pull/686)) + ### Documentation - Fix ignored initial state of knobs @layershifter ([#720](https://github.com/stardust-ui/react/pull/720)) - Fix unclearable example's code @layershifter ([#720](https://github.com/stardust-ui/react/pull/720)) - Add ability to export examples to CodeSandbox @layershifter ([#731](https://github.com/stardust-ui/react/pull/731)) - Fix remove empty item in docs sidebar @layershifter ([#728](https://github.com/stardust-ui/react/pull/728)) -### Features -- Add accessibility for submenu in toolbar and menu behavior @kolaps33 ([#686](https://github.com/stardust-ui/react/pull/686)) - ## [v0.16.2](https://github.com/stardust-ui/react/tree/v0.16.2) (2019-01-14) [Compare changes](https://github.com/stardust-ui/react/compare/v0.16.1...v0.16.2) @@ -54,8 +55,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add `accessibility` and `styles` to the API of `createComponent` @kuzhelov ([#714](https://github.com/stardust-ui/react/pull/714)) ### Fixes -- Fix doc layout for Menu component @codepretty ([#695] https://github.com/stardust-ui/react/pull/695) -- Fix focus outline visible only during keyboard navigation @kolaps33 ([#689] https://github.com/stardust-ui/react/pull/689) +- Fix doc layout for Menu component @codepretty ([#695](https://github.com/stardust-ui/react/pull/695)) +- Fix focus outline visible only during keyboard navigation @kolaps33 ([#689](https://github.com/stardust-ui/react/pull/689)) - Fix handling changes of `renderer` prop in `Provider` @layershifter ([#702](https://github.com/stardust-ui/react/pull/702)) - Fix Menu themeing styles @codepretty ([#708](https://github.com/stardust-ui/react/pull/708)) - Prevent infinite rendering loop start on `Popup` open @kuzhelov ([#705](https://github.com/stardust-ui/react/pull/705)) diff --git a/build/gulp/tasks/test-unit.ts b/build/gulp/tasks/test-unit.ts index e58a376449..28fa5d2897 100644 --- a/build/gulp/tasks/test-unit.ts +++ b/build/gulp/tasks/test-unit.ts @@ -18,6 +18,7 @@ const jest = ({ watch = false } = {}) => cb => { watch && '--watchAll', argv.runInBand && '--runInBand', argv.maxWorkers && `--maxWorkers=${argv.maxWorkers}`, + argv.detectLeaks && '--detectLeaks', ] .filter(Boolean) .join(' ') diff --git a/docs/src/components/ExternalExampleLayout.tsx b/docs/src/components/ExternalExampleLayout.tsx index 38b262754c..f16e3c44fa 100644 --- a/docs/src/components/ExternalExampleLayout.tsx +++ b/docs/src/components/ExternalExampleLayout.tsx @@ -1,4 +1,4 @@ -import * as _ from 'lodash/fp' +import * as _ from 'lodash' import * as PropTypes from 'prop-types' import * as React from 'react' import SourceRender from 'react-source-render' @@ -18,10 +18,10 @@ const ExternalExampleLayout: any = props => { const { exampleName } = props.match.params const exampleFilename = exampleKebabNameToSourceFilename(exampleName) - const examplePath = _.find(path => { + const examplePath = _.find(examplePaths, path => { const { exampleName } = parseExamplePath(path) return exampleFilename === exampleName - }, examplePaths) + }) if (!examplePath) return const exampleSource: ExampleSource = exampleSourcesContext(examplePath) diff --git a/docs/src/components/Sidebar/Sidebar.tsx b/docs/src/components/Sidebar/Sidebar.tsx index 281359c40b..6c3a632dac 100644 --- a/docs/src/components/Sidebar/Sidebar.tsx +++ b/docs/src/components/Sidebar/Sidebar.tsx @@ -1,5 +1,5 @@ import keyboardKey from 'keyboard-key' -import * as _ from 'lodash/fp' +import * as _ from 'lodash' import * as PropTypes from 'prop-types' import * as React from 'react' import { findDOMNode } from 'react-dom' @@ -102,10 +102,10 @@ class Sidebar extends React.Component { } } - private menuItemsByType = _.map(nextType => { - const items = _.flow( - _.filter(({ type }) => type === nextType), - _.map(info => ( + private menuItemsByType = _.map(constants.typeOrder, nextType => { + const items = _.chain([...componentMenu, ...behaviorMenu]) + .filter(({ type }) => type === nextType) + .map(info => ( { to={getComponentPathname(info)} activeClassName="active" /> - )), - )([...componentMenu, ...behaviorMenu]) + )) + .value() return ( @@ -123,7 +123,7 @@ class Sidebar extends React.Component { {items} ) - }, constants.typeOrder) + }) private renderSearchItems = () => { const { selectedItemIndex, query } = this.state @@ -134,16 +134,16 @@ class Sidebar extends React.Component { const containsMatches: ComponentMenuItem[] = [] const escapedQuery = _.escapeRegExp(query) - _.each(info => { + _.each(componentMenu, info => { if (new RegExp(`^${escapedQuery}`, 'i').test(info.displayName)) { startsWithMatches.push(info) } else if (new RegExp(escapedQuery, 'i').test(info.displayName)) { containsMatches.push(info) } - }, componentMenu) + }) this.filteredMenu = [...startsWithMatches, ...containsMatches] - const menuItems = _.map(info => { + const menuItems = _.map(this.filteredMenu, info => { itemIndex += 1 const isSelected = itemIndex === selectedItemIndex @@ -162,7 +162,7 @@ class Sidebar extends React.Component { {isSelected && selectedItemLabel} ) - }, this.filteredMenu) + }) return {menuItems} } diff --git a/docs/src/utils/examplePathToHash.ts b/docs/src/utils/examplePathToHash.ts index b246f8ce98..b928116942 100644 --- a/docs/src/utils/examplePathToHash.ts +++ b/docs/src/utils/examplePathToHash.ts @@ -1,4 +1,4 @@ -import * as _ from 'lodash/fp' +import * as _ from 'lodash' import parseExamplePath from './parseExamplePath' /** diff --git a/src/lib/customPropTypes.tsx b/src/lib/customPropTypes.tsx index 8bac47cd0d..d457176f92 100644 --- a/src/lib/customPropTypes.tsx +++ b/src/lib/customPropTypes.tsx @@ -1,10 +1,8 @@ -import * as _ from 'lodash/fp' +import * as _ from 'lodash' import * as PropTypes from 'prop-types' import leven from './leven' import { ObjectOf } from '../../types/utils' -type SuggestProps = { score: number; suggestion: string } - const typeOf = x => Object.prototype.toString.call(x) /** @@ -39,27 +37,27 @@ export const suggest = (suggestions: string[]) => { const findBestSuggestions = _.memoize((str: string) => { const propValueWords = str.split(' ') - return _.flow( - _.map((suggestion: string) => { + return _.chain(suggestions) + .map((suggestion: string) => { const suggestionWords = suggestion.split(' ') - const propValueScore = _.flow( - _.map(x => _.map(y => leven(x, y), suggestionWords)), - _.map(_.min), - _.sum, - )(propValueWords) + const propValueScore = _.chain(propValueWords) + .map(x => _.map(suggestionWords, y => leven(x, y))) + .map(_.min) + .sum() + .value() - const suggestionScore = _.flow( - _.map(x => _.map(y => leven(x, y), propValueWords)), - _.map(_.min), - _.sum, - )(suggestionWords) + const suggestionScore = _.chain(suggestionWords) + .map(x => _.map(propValueWords, y => leven(x, y))) + .map(_.min) + .sum() + .value() return { suggestion, score: propValueScore + suggestionScore } - }), - _.sortBy(['score', 'suggestion']), - _.take(3), - )(suggestions) + }) + .sortBy(['score', 'suggestion']) + .take(3) + .value() }) // Convert the suggestions list into a hash map for O(n) lookup times. Ensure @@ -170,20 +168,20 @@ export const every = (validators: Function[]) => ( ) } - const errors = _.flow( - _.map(validator => { + const error = _.chain(validators) + .map(validator => { if (typeof validator !== 'function') { throw new Error( `every() argument "validators" should contain functions, found: ${typeOf(validator)}.`, ) } return validator(props, propName, componentName, ...args) - }), - _.compact, - )(validators) + }) + .compact() + .first() // we can only return one error at a time + .value() - // we can only return one error at a time - return errors[0] + return error } /** @@ -205,21 +203,22 @@ export const some = (validators: Function[]) => ( ) } - const errors = _.compact( - _.map(validator => { + const errors = _.chain(validators) + .map(validator => { if (!_.isFunction(validator)) { throw new Error( `some() argument "validators" should contain functions, found: ${typeOf(validator)}.`, ) } return validator(props, propName, componentName, ...args) - }, validators), - ) + }) + .compact() + .value() // fail only if all validators failed if (errors.length === validators.length) { const error = new Error('One of these validators must pass:') - error.message += `\n${_.map(err => `- ${err.message}`, errors).join('\n')}` + error.message += `\n${_.map(errors, err => `- ${err.message}`).join('\n')}` return error } @@ -269,7 +268,7 @@ export const givenProps = (propsShape: object, validator: Function) => ( if (error) { // poor mans shallow pretty print, prevents JSON circular reference errors - const prettyProps = `{ ${_.keys(_.pick(_.keys(propsShape), props)) + const prettyProps = `{ ${_.keys(_.pick(props, _.keys(propsShape))) .map(key => { const val = props[key] let renderedValue = val