Skip to content

Commit

Permalink
Merge branch 'master' into jest-resolved-values
Browse files Browse the repository at this point in the history
  • Loading branch information
julienw committed Apr 9, 2018
2 parents abd049d + 8caaec1 commit beffed4
Show file tree
Hide file tree
Showing 120 changed files with 11,680 additions and 1,376 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,28 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [2.4.0] - 2018-03-16

### IMPORTANT

A week after this release, all previous versions of `flow-typed` on npm will be DEPRECATED, in order to encourage upgrading to version `2.4.0`. After which, we will be introducing files to definition folders under `/definitions/npm`, which will break the `search`, `install` and `validate-defs` commands.

**We strongly recommend upgrading to `2.4.0` within that timeframe.**

### Added
- Allow any file type (.md, .json) under `/definitions/npm/<library>_vx.x.x/` (#1962)
- `describe` and `it` can now be importing from `'flow-typed-test'` in `_test` files (#1942)
- See [CONTRIBUTING.md](https://github.com/flowtype/flow-typed/blob/master/CONTRIBUTING.md)
- Root directory option (-rootDir) to install command (#1835)

### Changed
- Replace `unzip` with `unzipper` (#1957)

### Fixed
- Fix jest specs breaking by adding `babel-core` as a dependency (#1864)
58 changes: 39 additions & 19 deletions CONTRIBUTING.md
Expand Up @@ -8,8 +8,8 @@ to existing libdefs.

* [Contributing to the definitions repository](#contributing-to-the-definitions-repository)
* [Writing libdefs tips](#writing-libdefs-tips)
* [Avoid `any` when possible](#avoid-any-when-possible)
* [Don't import types from other libdefs](#dont-import-types-from-other-libdefs)
* [Avoid `any` when possible](#avoid-any-when-possible)
* [Always prefix global variables that aren't really meant to be global](#prefix-global-variables-that-arent-really-meant-to-be-global)
* [Writing tests](#writing-tests)
* [Use `describe` and `it` blocks to limit scope](#use-describe-and-it-blocks-to-limit-scope)
Expand Down Expand Up @@ -91,6 +91,23 @@ You know how to do it.

## Writing libdefs tips

### Don't import types from other libdefs

You might think it would be possible to import types from other libdefs, much the same way you do in your own code:

```js
import type { MyType } from 'some-module';
declare module 'other-module' {
declare export function takesMyType(val: MyType): number;
}
```
...but you would be wrong. Flow silently converts `MyType` to be typed `any`, and then sadness ensues.
You can use the raw, private React types (e.g. `React$Node`, `React$ComponentType`) directly without importing them, however.
Currently it's not possible to safely import types from other libdefs when making your libdef. [Further discussion here](https://github.com/flowtype/flow-typed/issues/1857).
### Avoid `any` when possible
Using the `any` type for a variable or interface results in the loss of type information as types pass through it. That means if a type passes through `any` before propogating on to other code, the `any` will potentially cause Flow to miss type errors!
Expand All @@ -105,7 +122,7 @@ function setCache(key: string, value: any) {
cache.set(key, value);
}
function getCache(key: string) {
cache.get(key);
return cache.get(key);
}

setCache('foo', 42);
Expand All @@ -123,7 +140,7 @@ function setCache(key: string, value: mixed) {
cache.set(key, value);
}
function getCache(key: string) {
cache.get(key);
return cache.get(key);
}

setCache('foo', 42);
Expand Down Expand Up @@ -157,21 +174,6 @@ getUser((user) => console.log('Got the user!'));

Using `mixed` in place of `any` for the return type of a function or the type of a variable is a judgement call, though. Return types and declared variables flow into users' programs, which means that users will have to prove the type of `mixed` before they can use them.

### Don't import types from other libdefs

You might think it would be possible to import types from other libdefs, much the same way you do in your own code:

```js
import type { MyType } from 'some-module';
declare module 'other-module' {
declare export function takesMyType(val: MyType): number;
}
```
...but you would be wrong. Flow silently converts `MyType` to be typed `any`, and then sadness ensues.
Currently it's not possible to safely import types from other libdefs when making your libdef. [Further discussion here](https://github.com/flowtype/flow-typed/issues/1857).
### Prefix global variables that aren't really meant to be global

Right now we don't have a good way to write types inside `declare module {}` bodies that *aren't* exported. This problem is being worked on, but in the meantime the best option is to just put a declaration outside the `declare module {}` and reference it.
Expand All @@ -193,9 +195,11 @@ declare module "MyModule" {
### Use `describe` and `it` blocks to limit scope
You can use `describe` and `it` verbs, much like you do in Mocha/Jest/whatever, to write descriptive tests and limit scope. These are available on the global scope, so you don't need to import anything. (Note that they don't actually run tests, they're just sugar to limit scope and emulate the TDD language with which we're all familiar).
You can use `describe` and `it` verbs, much like you do in Mocha/Jest/whatever, to write descriptive tests and limit scope. These are available under 'flow-typed-test'. (Note that they don't actually run tests, they're just sugar to limit scope and emulate the TDD language with which we're all familiar).
```js
import { describe, it } from 'flow-typed-test';

describe('#someFunction', () => {
it('should do something', () => {
const a: number = 1;
Expand All @@ -206,3 +210,19 @@ describe('#someFunction', () => {
const a: number = 'foo';
})
```
`describe` or `it` have the potential of causing collisions. In the event of a name collision, import them under new names.
```js
import { describe as foo, it as bar } from 'flow-typed-test';

foo('#someFunction', () => {
bar('should do something', () => {
const a: number = 1;
});

// you can also do type checks outside an it statement
//$ExpectError
const a: number = 'foo';
})
```
8 changes: 7 additions & 1 deletion README.md
Expand Up @@ -76,7 +76,7 @@ working with this repository. The full list of commands is available at

Installs libdefs from looking at your package.json.

If `package-specification` was specified, only that one libdef will be installed.
If `package-specification` was specified, only that one libdef will be installed.
If the `--ignoreDeps` flag was specified, the libdefs for the specified deps will be ignored. i.e: `--ignoreDeps dev bundle peer`.

```bash
Expand Down Expand Up @@ -107,3 +107,9 @@ on your local filesystem. Usually, the cache will automatically be updated after
a short grace period during a libdef installation, but sometimes it is useful to
do this update manually. Use this command if you want to download the most
recent definitions into the cache for yourself.

## Active Maintenance Team

[![Andrew Smith](https://github.com/andrewsouthpaw.png?size=100)](https://github.com/andrewsouthpaw) | [![Georges-Antoine Assi](https://github.com/gantoine.png?size=100)](https://github.com/gantoine) | [![Ville Saukkonen](https://github.com/villesau.png?size=100)](https://github.com/villesau)
:---:|:---:|:---:
[@AndrewSouthpaw](https://github.com/andrewsouthpaw) | [@GAntoine](https://github.com/gantoine) | [@villesau](https://github.com/villesau)
12 changes: 12 additions & 0 deletions cli/flow-typed/npm/jest_v22.x.x.js
Expand Up @@ -55,6 +55,11 @@ type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = {
mockImplementationOnce(
fn: (...args: TArguments) => TReturn,
): JestMockFn<TArguments, TReturn>,
/**
* Accepts a string to use in test result output in place of "jest.fn()" to
* indicate which mock function is being referenced.
*/
mockName(name: string): JestMockFn < TArguments, TReturn >,
/**
* Just a simple sugar function for returning `this`
*/
Expand Down Expand Up @@ -391,6 +396,13 @@ type JestObjectType = {
* Executes only the macro task queue (i.e. all tasks queued by setTimeout()
* or setInterval() and setImmediate()).
*/
advanceTimersByTime(msToRun: number): void,
/**
* Executes only the macro task queue (i.e. all tasks queued by setTimeout()
* or setInterval() and setImmediate()).
*
* Renamed to `advanceTimersByTime`.
*/
runTimersToTime(msToRun: number): void,
/**
* Executes only the macro-tasks that are currently pending (i.e., only the
Expand Down
13 changes: 9 additions & 4 deletions cli/package.json
Expand Up @@ -10,7 +10,7 @@
"bugs": {
"url": "https://github.com/flowtype/flow-typed/issues"
},
"version": "2.3.0",
"version": "2.4.0",
"main": "dist/cli.js",
"bin": "dist/cli.js",
"scripts": {
Expand All @@ -36,7 +36,7 @@
"semver": "^5.5.0",
"table": "^4.0.2",
"through": "^2.3.8",
"unzip": "^0.1.11",
"unzipper": "^0.8.11",
"which": "^1.3.0",
"yargs": "^4.2.0"
},
Expand All @@ -59,13 +59,18 @@
"prettier": "^1.9.2",
"regenerator-runtime": "^0.11.1"
},
"keywords": ["flow", "flowtype"],
"keywords": [
"flow",
"flowtype"
],
"jest": {
"name": "flow-typed-cli",
"modulePathIgnorePatterns": [
"<rootDir>/dist/.*",
"<rootDir>/node_modules/.*"
],
"testPathIgnorePatterns": ["<rootDir>/.*/__[^/]*-fixtures__/.*"]
"testPathIgnorePatterns": [
"<rootDir>/.*/__[^/]*-fixtures__/.*"
]
}
}
10 changes: 9 additions & 1 deletion cli/src/commands/__tests__/install-test.js
Expand Up @@ -103,6 +103,7 @@ describe('install (command)', () => {

describe('installNpmLibDefs', () => {
const origConsoleError = console.error;

beforeEach(() => {
(console: any).error = jest.fn();
});
Expand Down Expand Up @@ -140,6 +141,12 @@ describe('install (command)', () => {
() => {
return testProject(async ROOT_DIR => {
await touchFile(path.join(ROOT_DIR, '.flowconfig'));
await writePkgJson(path.join(ROOT_DIR, 'package.json'), {
name: 'test',
devDependencies: {
'flow-bin': '^0.40.0',
},
});
const result = await installNpmLibDefs({
cwd: ROOT_DIR,
flowVersion: parseFlowDirString('flow_v0.40.0', 'testContext'),
Expand All @@ -153,7 +160,8 @@ describe('install (command)', () => {
expect(result).toBe(1);
expect(_mock(console.error).mock.calls).toEqual([
[
'ERROR: Please specify npm package names in the format of `foo@1.2.3`',
'ERROR: Package not found from package.json.\n' +
'Please specify version for the package in the format of `foo@1.2.3`',
],
]);
});
Expand Down
43 changes: 34 additions & 9 deletions cli/src/commands/install.js
Expand Up @@ -27,7 +27,10 @@ import {
getPackageJsonDependencies,
} from '../lib/npm/npmProjectUtils';

import {getCacheRepoDir} from '../lib/cacheRepoUtils';
import {
getCacheRepoDir,
_setCustomCacheDir as setCustomCacheDir,
} from '../lib/cacheRepoUtils';

import {getRangeLowerBound} from '../lib/semver';

Expand All @@ -48,6 +51,7 @@ export type Args = {
skip: boolean,
verbose: boolean,
libdefDir?: string,
cacheDir?: string,
packageDir?: string,
ignoreDeps?: Array<string>,
rootDir?: string,
Expand Down Expand Up @@ -77,6 +81,13 @@ export function setup(yargs: Yargs) {
type: 'string',
demand: false,
},
cacheDir: {
alias: 'c',
describe:
'Directory (absolute or relative path, ~ is not supported) to store cache of libdefs',
type: 'string',
demand: false,
},
packageDir: {
alias: 'p',
describe: 'The relative path of package.json where flow-bin is installed',
Expand Down Expand Up @@ -107,6 +118,12 @@ export async function run(args: Args) {
return coreLibDefResult;
}

if (args.cacheDir) {
const cacheDir = path.resolve(args.cacheDir);
console.log('• Setting cache dir', cacheDir);
setCustomCacheDir(cacheDir);
}

const npmLibDefResult = await installNpmLibDefs({
cwd,
flowVersion,
Expand Down Expand Up @@ -190,15 +207,23 @@ async function installNpmLibDefs({
const term = explicitLibDefs[i];
const termMatches = term.match(/(@[^@\/]+\/)?([^@]+)@(.+)/);
if (termMatches == null) {
console.error(
'ERROR: Please specify npm package names in the format of `foo@1.2.3`',
);
return 1;
const pkgJsonData = await getPackageJsonData(cwd);
const pkgJsonDeps = getPackageJsonDependencies(pkgJsonData, []);
const packageVersion = pkgJsonDeps[term];
if (packageVersion) {
libdefsToSearchFor.set(term, packageVersion);
} else {
console.error(
'ERROR: Package not found from package.json.\n' +
'Please specify version for the package in the format of `foo@1.2.3`',
);
return 1;
}
} else {
const [_, npmScope, pkgName, pkgVerStr] = termMatches;
const scopedPkgName = npmScope != null ? npmScope + pkgName : pkgName;
libdefsToSearchFor.set(scopedPkgName, pkgVerStr);
}

const [_, npmScope, pkgName, pkgVerStr] = termMatches;
const scopedPkgName = npmScope != null ? npmScope + pkgName : pkgName;
libdefsToSearchFor.set(scopedPkgName, pkgVerStr);
}
console.log(`• Searching for ${libdefsToSearchFor.size} libdefs...`);
} else {
Expand Down

0 comments on commit beffed4

Please sign in to comment.