diff --git a/.npmignore b/.npmignore index 34c922809..8c9b62a45 100644 --- a/.npmignore +++ b/.npmignore @@ -13,3 +13,4 @@ dangerfile.js env .eslintrc.json jsconfig.json +coverage diff --git a/changelog.md b/changelog.md index a55ed2a01..c6ba5bd52 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,13 @@ ### master -// Add your own contribution below +// Add your own contribution below, ideally with a consumer's perspective in mind. + +* Updated jest-* dependencies to 19.x - orta + + Updating the jest-* dependencies seems to be exhibiting strange behavior in tests for windows if you update, and + use windows, can you please confirm that everything is 👍 + +* Added type shapings to `JSONPatchForFile` - orta ### 0.14.2 diff --git a/package.json b/package.json index 9b9f99215..a00060481 100644 --- a/package.json +++ b/package.json @@ -78,21 +78,21 @@ "@types/debug": "0.0.29", "@types/jest": "^19.2.1", "@types/node-fetch": "^1.6.6", - "babel-cli": "^6.16.0", + "babel-cli": "6.16", "babel-plugin-syntax-async-functions": "^6.13.0", - "babel-plugin-transform-flow-strip-types": "^6.8.0", - "babel-plugin-transform-regenerator": "^6.16.1", - "babel-preset-es2015": "^6.16.0", - "babel-preset-stage-3": "^6.17.0", + "babel-plugin-transform-flow-strip-types": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "babel-preset-es2015": "^6.24.0", + "babel-preset-stage-3": "^6.22.0", "husky": "^0.12.0", "in-publish": "^2.0.0", "jest": "^19.0.2", "lint-staged": "^3.2.5", "madge": "^1.4.4", "shx": "^0.2.1", - "ts-jest": "^19.0.0", + "ts-jest": "^19.0.2", "ts-node": "^3.0.0", - "tslint": "^4.4.0", + "tslint": "^4.5.1", "typescript": "2.2.1" }, "dependencies": { @@ -100,9 +100,9 @@ "chalk": "^1.1.1", "commander": "^2.9.0", "debug": "^2.6.0", - "jest-config": "^18.0.0", - "jest-environment-node": "^18.1.0", - "jest-runtime": "^18.0.0", + "jest-config": "^19.0.2", + "jest-environment-node": "^19.0.2", + "jest-runtime": "^19.0.2", "jsome": "^2.3.25", "jsonpointer": "^4.0.1", "lodash.find": "^4.6.0", diff --git a/source/ci_source/ci_source.ts b/source/ci_source/ci_source.ts index b664c2a0b..e1776ed60 100644 --- a/source/ci_source/ci_source.ts +++ b/source/ci_source/ci_source.ts @@ -1,6 +1,15 @@ + /** A json object that represents the outer ENV */ export type Env = any +/** Key details about a repo */ +export interface RepoMetaData { + /** A path like "artsy/eigen" */ + repoSlug: string, + /** The ID for the pull/merge request "11" */ + pullRequestID: string +} + /** The shape of an object that represents an individual CI */ export interface CISource { /** The project name, mainly for showing errors */ diff --git a/source/ci_source/ci_source_helpers.ts b/source/ci_source/ci_source_helpers.ts index a8d240315..28c87e0f5 100644 --- a/source/ci_source/ci_source_helpers.ts +++ b/source/ci_source/ci_source_helpers.ts @@ -1,4 +1,4 @@ -import { Env, CISource } from "./ci_source" +import { Env, RepoMetaData } from "./ci_source" import { GitHubAPI } from "../platforms/github/GitHubAPI" import { GitHubPRDSL } from "../dsl/GitHubDSL" import * as find from "lodash.find" @@ -42,12 +42,12 @@ export function ensureEnvKeysAreInt(env: Env, keys: Array): boolean { * @returns {number} The pull request ID, if any. Otherwise 0 (Github starts from #1). * If there are multiple pull requests open for a branch, returns the first. */ -export async function getPullRequestIDForBranch(source: CISource, env: Env, branch: string): Promise { +export async function getPullRequestIDForBranch(metadata: RepoMetaData, env: Env, branch: string): Promise { const token = env["DANGER_GITHUB_API_TOKEN"] if (!token) { return 0 } - const api = new GitHubAPI(source, token) + const api = new GitHubAPI(metadata, token) const prs = await api.getPullRequests() as any[] const prForBranch: GitHubPRDSL = find(prs, (pr: GitHubPRDSL) => pr.head.ref === branch) if (prForBranch) { diff --git a/source/danger.d.ts b/source/danger.d.ts index 4a9dfedb4..514048c00 100644 --- a/source/danger.d.ts +++ b/source/danger.d.ts @@ -140,6 +140,11 @@ export interface JSONDiffValue { removed?: any[] } +/** A map of string keys to JSONDiffValue */ +export interface JSONDiff { + [name: string]: JSONDiffValue +} + // This is `danger.git` /** The git specific metadata for a PR */ @@ -190,7 +195,7 @@ export interface GitDSL { * * @param {string} filename the path to the json file */ - JSONDiffForFile(filename: string): Promise, + JSONDiffForFile(filename: string): Promise, /** The Git commit metadata */ readonly commits: Array diff --git a/source/dsl/GitDSL.ts b/source/dsl/GitDSL.ts index f174863a7..0948f60fe 100644 --- a/source/dsl/GitDSL.ts +++ b/source/dsl/GitDSL.ts @@ -32,6 +32,11 @@ export interface JSONDiffValue { removed?: any[] } +/** A map of string keys to JSONDiffValue */ +export interface JSONDiff { + [name: string]: JSONDiffValue +} + // This is `danger.git` /** The git specific metadata for a PR */ @@ -85,7 +90,7 @@ export interface GitDSL { * * @param {string} filename the path to the json file */ - JSONDiffForFile(filename: string): Promise, + JSONDiffForFile(filename: string): Promise, /** The Git commit metadata */ readonly commits: Array diff --git a/source/platforms/_tests/GitHub.test.ts b/source/platforms/_tests/GitHub.test.ts index 4193c5fc7..934608d80 100644 --- a/source/platforms/_tests/GitHub.test.ts +++ b/source/platforms/_tests/GitHub.test.ts @@ -17,8 +17,7 @@ export const requestWithFixturedJSON = async (path: string): Promise<() => Promi describe("with fixtured data", () => { it("returns the correct github data", async () => { - const mockSource = new FakeCI({}) - const api = new GitHubAPI(mockSource) + const api = new GitHubAPI({ repoSlug: "unused/metadata", pullRequestID: "1" }) const github = new GitHub(api) api.getPullRequestInfo = await requestWithFixturedJSON("github_pr.json") diff --git a/source/platforms/_tests/fixtures/readme.md b/source/platforms/_tests/fixtures/readme.md new file mode 100644 index 000000000..315d23675 --- /dev/null +++ b/source/platforms/_tests/fixtures/readme.md @@ -0,0 +1,5 @@ +Here's an example CURL request to add a new fixture + +```sh +curl -H "Authorization: XXX" curl -H "Accept: application/vnd.github.black-cat-preview+json" --request GET https://api.github.com/repos/artsy/emission/pulls/327/requested_reviewers > source/platforms/_tests/fixtures/requested_reviewers.json +``` diff --git a/source/platforms/_tests/fixtures/requested_reviewers.json b/source/platforms/_tests/fixtures/requested_reviewers.json new file mode 100644 index 000000000..0b6a45359 --- /dev/null +++ b/source/platforms/_tests/fixtures/requested_reviewers.json @@ -0,0 +1,21 @@ +[ + { + "login": "ArtsyOpenSource", + "id": 12397828, + "avatar_url": "https://avatars1.githubusercontent.com/u/12397828?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/ArtsyOpenSource", + "html_url": "https://github.com/ArtsyOpenSource", + "followers_url": "https://api.github.com/users/ArtsyOpenSource/followers", + "following_url": "https://api.github.com/users/ArtsyOpenSource/following{/other_user}", + "gists_url": "https://api.github.com/users/ArtsyOpenSource/gists{/gist_id}", + "starred_url": "https://api.github.com/users/ArtsyOpenSource/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ArtsyOpenSource/subscriptions", + "organizations_url": "https://api.github.com/users/ArtsyOpenSource/orgs", + "repos_url": "https://api.github.com/users/ArtsyOpenSource/repos", + "events_url": "https://api.github.com/users/ArtsyOpenSource/events{/privacy}", + "received_events_url": "https://api.github.com/users/ArtsyOpenSource/received_events", + "type": "User", + "site_admin": false + } +] diff --git a/source/platforms/_tests/fixtures/reviews.json b/source/platforms/_tests/fixtures/reviews.json new file mode 100644 index 000000000..bc2d64a7f --- /dev/null +++ b/source/platforms/_tests/fixtures/reviews.json @@ -0,0 +1,146 @@ +[ + { + "id": 2332973, + "user": { + "login": "orta", + "id": 49038, + "avatar_url": "https://avatars1.githubusercontent.com/u/49038?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/orta", + "html_url": "https://github.com/orta", + "followers_url": "https://api.github.com/users/orta/followers", + "following_url": "https://api.github.com/users/orta/following{/other_user}", + "gists_url": "https://api.github.com/users/orta/gists{/gist_id}", + "starred_url": "https://api.github.com/users/orta/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/orta/subscriptions", + "organizations_url": "https://api.github.com/users/orta/orgs", + "repos_url": "https://api.github.com/users/orta/repos", + "events_url": "https://api.github.com/users/orta/events{/privacy}", + "received_events_url": "https://api.github.com/users/orta/received_events", + "type": "User", + "site_admin": false + }, + "body": "Generally speaking, there's a _lot_ of similar shaped code here that seems to mainly only be different to the artist a tiny amount\n", + "state": "COMMENTED", + "html_url": "https://github.com/artsy/emission/pull/327#pullrequestreview-2332973", + "pull_request_url": "https://api.github.com/repos/artsy/emission/pulls/327", + "_links": { + "html": { + "href": "https://github.com/artsy/emission/pull/327#pullrequestreview-2332973" + }, + "pull_request": { + "href": "https://api.github.com/repos/artsy/emission/pulls/327" + } + }, + "submitted_at": "2016-09-30T14:14:11Z", + "commit_id": "76c122e47ee36170c86739bb6cc665b6114e308c" + }, + { + "id": 2343835, + "user": { + "login": "orta", + "id": 49038, + "avatar_url": "https://avatars1.githubusercontent.com/u/49038?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/orta", + "html_url": "https://github.com/orta", + "followers_url": "https://api.github.com/users/orta/followers", + "following_url": "https://api.github.com/users/orta/following{/other_user}", + "gists_url": "https://api.github.com/users/orta/gists{/gist_id}", + "starred_url": "https://api.github.com/users/orta/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/orta/subscriptions", + "organizations_url": "https://api.github.com/users/orta/orgs", + "repos_url": "https://api.github.com/users/orta/repos", + "events_url": "https://api.github.com/users/orta/events{/privacy}", + "received_events_url": "https://api.github.com/users/orta/received_events", + "type": "User", + "site_admin": false + }, + "body": "", + "state": "COMMENTED", + "html_url": "https://github.com/artsy/emission/pull/327#pullrequestreview-2343835", + "pull_request_url": "https://api.github.com/repos/artsy/emission/pulls/327", + "_links": { + "html": { + "href": "https://github.com/artsy/emission/pull/327#pullrequestreview-2343835" + }, + "pull_request": { + "href": "https://api.github.com/repos/artsy/emission/pulls/327" + } + }, + "submitted_at": "2016-09-30T15:08:12Z", + "commit_id": "466bdef69fdbcdceb3b35242370edc328605ae1e" + }, + { + "id": 2344085, + "user": { + "login": "orta", + "id": 49038, + "avatar_url": "https://avatars1.githubusercontent.com/u/49038?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/orta", + "html_url": "https://github.com/orta", + "followers_url": "https://api.github.com/users/orta/followers", + "following_url": "https://api.github.com/users/orta/following{/other_user}", + "gists_url": "https://api.github.com/users/orta/gists{/gist_id}", + "starred_url": "https://api.github.com/users/orta/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/orta/subscriptions", + "organizations_url": "https://api.github.com/users/orta/orgs", + "repos_url": "https://api.github.com/users/orta/repos", + "events_url": "https://api.github.com/users/orta/events{/privacy}", + "received_events_url": "https://api.github.com/users/orta/received_events", + "type": "User", + "site_admin": false + }, + "body": "", + "state": "COMMENTED", + "html_url": "https://github.com/artsy/emission/pull/327#pullrequestreview-2344085", + "pull_request_url": "https://api.github.com/repos/artsy/emission/pulls/327", + "_links": { + "html": { + "href": "https://github.com/artsy/emission/pull/327#pullrequestreview-2344085" + }, + "pull_request": { + "href": "https://api.github.com/repos/artsy/emission/pulls/327" + } + }, + "submitted_at": "2016-09-30T15:09:27Z", + "commit_id": "466bdef69fdbcdceb3b35242370edc328605ae1e" + }, + { + "id": 2344137, + "user": { + "login": "orta", + "id": 49038, + "avatar_url": "https://avatars1.githubusercontent.com/u/49038?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/orta", + "html_url": "https://github.com/orta", + "followers_url": "https://api.github.com/users/orta/followers", + "following_url": "https://api.github.com/users/orta/following{/other_user}", + "gists_url": "https://api.github.com/users/orta/gists{/gist_id}", + "starred_url": "https://api.github.com/users/orta/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/orta/subscriptions", + "organizations_url": "https://api.github.com/users/orta/orgs", + "repos_url": "https://api.github.com/users/orta/repos", + "events_url": "https://api.github.com/users/orta/events{/privacy}", + "received_events_url": "https://api.github.com/users/orta/received_events", + "type": "User", + "site_admin": false + }, + "body": "", + "state": "COMMENTED", + "html_url": "https://github.com/artsy/emission/pull/327#pullrequestreview-2344137", + "pull_request_url": "https://api.github.com/repos/artsy/emission/pulls/327", + "_links": { + "html": { + "href": "https://github.com/artsy/emission/pull/327#pullrequestreview-2344137" + }, + "pull_request": { + "href": "https://api.github.com/repos/artsy/emission/pulls/327" + } + }, + "submitted_at": "2016-09-30T15:09:47Z", + "commit_id": "466bdef69fdbcdceb3b35242370edc328605ae1e" + } +] diff --git a/source/platforms/github/GitHubAPI.ts b/source/platforms/github/GitHubAPI.ts index a5be58e9e..7b13b4594 100644 --- a/source/platforms/github/GitHubAPI.ts +++ b/source/platforms/github/GitHubAPI.ts @@ -1,6 +1,6 @@ import { api as fetch } from "../../api/fetch" -import { CISource } from "../../ci_source/ci_source" -import { GitHubPRDSL} from "../../dsl/GitHubDSL" +import { RepoMetaData } from "../../ci_source/ci_source" +import { GitHubPRDSL, GitHubUser} from "../../dsl/GitHubDSL" import * as find from "lodash.find" // The Handle the API specific parts of the github @@ -16,7 +16,7 @@ export class GitHubAPI { fetch: typeof fetch additionalHeaders: any - constructor(public readonly ciSource: CISource, public readonly token?: APIToken) { + constructor(public readonly repoMetadata: RepoMetaData, public readonly token?: APIToken) { // This allows Peril to DI in a new Fetch function // which can handle unique API edge-cases around integrations this.fetch = fetch @@ -54,7 +54,7 @@ export class GitHubAPI { } async updateCommentWithID(id: number, comment: string): Promise { - const repo = this.ciSource.repoSlug + const repo = this.repoMetadata.repoSlug const res = await this.patch(`repos/${repo}/issues/comments/${id}`, {}, { body: comment }) @@ -63,7 +63,7 @@ export class GitHubAPI { } async deleteCommentWithID(id: number): Promise { - const repo = this.ciSource.repoSlug + const repo = this.repoMetadata.repoSlug const res = await this.api(`repos/${repo}/issues/comments/${id}`, {}, {}, "DELETE") return res.json() @@ -75,8 +75,8 @@ export class GitHubAPI { } async postPRComment(comment: string): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.post(`repos/${repo}/issues/${prID}/comments`, {}, { body: comment }) @@ -85,22 +85,22 @@ export class GitHubAPI { } async getPullRequestInfo(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/pulls/${prID}`) return res.ok ? res.json() : {} } async getPullRequestCommits(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/pulls/${prID}/commits`) return res.ok ? res.json() : [] } - async getUserInfo(): Promise { + async getUserInfo(): Promise { const response: any = await this.get("user") return response.json() @@ -108,16 +108,16 @@ export class GitHubAPI { // TODO: This does not handle pagination async getPullRequestComments(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/issues/${prID}/comments`) return res.ok ? res.json() : [] } async getPullRequestDiff(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/pulls/${prID}`, { accept: "application/vnd.github.v3.diff" }) @@ -131,15 +131,15 @@ export class GitHubAPI { } async getPullRequests(): Promise { - const repo = this.ciSource.repoSlug + const repo = this.repoMetadata.repoSlug const res = await this.get(`repos/${repo}/pulls`) return res.ok ? res.json : [] } async getReviewerRequests(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/pulls/${prID}/requested_reviewers`, { accept: "application/vnd.github.black-cat-preview+json" }) @@ -148,8 +148,8 @@ export class GitHubAPI { } async getReviews(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/pulls/${prID}/reviews`, { accept: "application/vnd.github.black-cat-preview+json" }) @@ -158,8 +158,8 @@ export class GitHubAPI { } async getIssue(): Promise { - const repo = this.ciSource.repoSlug - const prID = this.ciSource.pullRequestID + const repo = this.repoMetadata.repoSlug + const prID = this.repoMetadata.pullRequestID const res = await this.get(`repos/${repo}/issues/${prID}`) return res.ok ? res.json() : { labels: [] } diff --git a/source/platforms/github/_tests/_GitHubAPI.test.ts b/source/platforms/github/_tests/_GitHubAPI.test.ts index 25753050c..1ed342087 100644 --- a/source/platforms/github/_tests/_GitHubAPI.test.ts +++ b/source/platforms/github/_tests/_GitHubAPI.test.ts @@ -19,8 +19,7 @@ const fetch = (api, params): Promise => { } it("fileContents expects to grab PR JSON and pull out a file API call", async () => { - const mockSource = new FakeCI({}) - const api = new GitHubAPI(mockSource, "token") + const api = new GitHubAPI({ repoSlug: "unused/metadata", pullRequestID: "1" }, "token") api.getPullRequestInfo = await requestWithFixturedJSON("github_pr.json") api.getFileContents = await requestWithFixturedJSON("static_file.json") @@ -33,9 +32,7 @@ describe("API testing", () => { let api: GitHubAPI beforeEach(() => { - const mockSource = new FakeCI({}) - - api = new GitHubAPI(mockSource, "ABCDE") + api = new GitHubAPI({ repoSlug: "artsy/emission", pullRequestID: "1" }, "ABCDE") }) it("getUserInfo", async () => { @@ -64,14 +61,16 @@ describe("Peril", () => { it("Allows setting additional headers", async () => { const mockSource = new FakeCI({}) const api = new GitHubAPI(mockSource, "ABCDE") - api.fetch = fetchJSON + api.fetch = jest.fn() api.additionalHeaders = { "CUSTOM": "HEADER" } - const request = await api.getUserInfo() - expect(request.headers).toEqual({ - Authorization: "token ABCDE", + const request = await api.get("user") + expect(api.fetch).toHaveBeenCalledWith("https://api.github.com/user", + {"body": {}, "headers": { + "Authorization": "token ABCDE", "CUSTOM": "HEADER", - "Content-Type": "application/json", - }) + "Content-Type": "application/json" + }, "method": "GET"} + ) }) }) diff --git a/source/runner/DangerfileRunner.ts b/source/runner/DangerfileRunner.ts index 0ded15cd0..a4467e8a3 100644 --- a/source/runner/DangerfileRunner.ts +++ b/source/runner/DangerfileRunner.ts @@ -47,7 +47,7 @@ export async function createDangerfileRuntimeEnvironment(dangerfileContext: Dang * The Jest config object for this Danger run * @returns {any} the results of the run */ -async function dangerJestConfig() { +export async function dangerJestConfig() { // Note: This function is making assumptions that // the Dangerfile is being ran from the CWD @@ -55,20 +55,20 @@ async function dangerJestConfig() { // we can re-use things like haste transformers. // so if you can make you tests run right, // then it's pretty likely that Danger can do it too. - const jestConfig = await readConfig([], process.cwd()) - // console.log(jestConfig) + const jestConfig = await readConfig([], process.cwd()) return { cacheDirectory: os.tmpdir(), setupFiles: [], name: "danger", + testEnvironment: "node", haste: { defaultPlatform: "danger-js" }, moduleNameMapper: [], moduleDirectories: [ "node_modules" ], - moduleFileExtensions: ["js", ...jestConfig.moduleFileExtensions], - transform: [["js$", "babel-jest"], ...jestConfig.transform], - testPathIgnorePatterns: jestConfig.testPathIgnorePatterns, + moduleFileExtensions: ["js", ...jestConfig.config.moduleFileExtensions], + transform: [["js$", "babel-jest"], ...jestConfig.config.transform], + testPathIgnorePatterns: jestConfig.config.testPathIgnorePatterns, cache: null, testRegex: "", testPathDirs: [process.cwd()], diff --git a/source/runner/Executor.ts b/source/runner/Executor.ts index d46065294..64d59c5be 100644 --- a/source/runner/Executor.ts +++ b/source/runner/Executor.ts @@ -29,11 +29,11 @@ export class Executor { /** Mainly just a dumb helper because I can't do * async functions in danger-run.js * @param {string} file the path to run Danger from - * @returns {void} It's a promise, so a void promise + * @returns {Promise} The results of the Danger run */ async setupAndRunDanger(file: string) { const runtimeEnv = await this.setupDanger() - await this.runDanger(file, runtimeEnv) + return await this.runDanger(file, runtimeEnv) } /** @@ -49,12 +49,13 @@ export class Executor { /** * Runs all of the operations for a running just Danger * @param {string} file the filepath to the Dangerfile - * @returns {void} It's a promise, so a void promise + * @returns {Promise} The results of the Danger run */ async runDanger(file: string, runtime: DangerfileRuntimeEnv) { const results = await runDangerfileEnvironment(file, runtime) await this.handleResults(results) + return results } /** diff --git a/source/runner/_tests/DangerRunner.test.ts b/source/runner/_tests/DangerRunner.test.ts index 67142edb9..8d5788ff6 100644 --- a/source/runner/_tests/DangerRunner.test.ts +++ b/source/runner/_tests/DangerRunner.test.ts @@ -3,8 +3,10 @@ import { createDangerfileRuntimeEnvironment, runDangerfileEnvironment, updateDangerfile, - cleanDangerfile + cleanDangerfile, + dangerJestConfig } from "../DangerfileRunner" + import {FakeCI} from "../../ci_source/providers/Fake" import {FakePlatform} from "../../platforms/FakePlatform" import {Executor} from "../Executor" @@ -21,7 +23,12 @@ const fixtures = resolve(__dirname, "fixtures") */ async function setupDangerfileContext() { const platform = new FakePlatform() - const exec = new Executor(new FakeCI({}), platform) + const config = { + stdoutOnly: false, + verbose: false + } + + const exec = new Executor(new FakeCI({}), platform, config) platform.getPlatformGitRepresentation = jest.fn() platform.getPlatformDSLRepresentation = jest.fn() @@ -30,111 +37,113 @@ async function setupDangerfileContext() { return contextForDanger(dsl) } -describe("with fixtures", () => { - it("handles a blank Dangerfile", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileEmpty.js"), runtime) - - expect(results).toEqual({ - fails: [], - markdowns: [], - messages: [], - warnings: [] +if (process.platform !== "win32") { + describe("with fixtures", () => { + it("handles a blank Dangerfile", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileEmpty.js"), runtime) + + expect(results).toEqual({ + fails: [], + markdowns: [], + messages: [], + warnings: [] + }) }) - }) - it("handles a full set of messages", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileFullMessages.js"), runtime) - - expect(results).toEqual({ - fails: [{"message": "this is a failure"}], - markdowns: ["this is a *markdown*"], - messages: [{"message": "this is a message"}], - warnings: [{"message": "this is a warning"}] + it("handles a full set of messages", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileFullMessages.js"), runtime) + + expect(results).toEqual({ + fails: [{"message": "this is a failure"}], + markdowns: ["this is a *markdown*"], + messages: [{"message": "this is a message"}], + warnings: [{"message": "this is a warning"}] + }) }) - }) - it("handles a failing dangerfile", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) + it("handles a failing dangerfile", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) - try { - await runDangerfileEnvironment(resolve(fixtures, "__DangerfileBadSyntax.js"), runtime) - throw new Error("Do not get to this") - } - catch (e) { - // expect(e.message === ("Do not get to this")).toBeFalsy() - expect(e.message).toEqual("hello is not defined") - } - }) + try { + await runDangerfileEnvironment(resolve(fixtures, "__DangerfileBadSyntax.js"), runtime) + throw new Error("Do not get to this") + } + catch (e) { + // expect(e.message === ("Do not get to this")).toBeFalsy() + expect(e.message).toEqual("hello is not defined") + } + }) - it("handles relative imports correctly", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - await runDangerfileEnvironment(resolve(fixtures, "__DangerfileImportRelative.js"), runtime) - }) + it("handles relative imports correctly", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + await runDangerfileEnvironment(resolve(fixtures, "__DangerfileImportRelative.js"), runtime) + }) - it("handles scheduled (async) code", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileScheduled.js"), runtime) - expect(results).toEqual({ - fails: [], - messages: [], - markdowns: [], - warnings: [{ message: "Asynchronous Warning" }], + it("handles scheduled (async) code", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileScheduled.js"), runtime) + expect(results).toEqual({ + fails: [], + messages: [], + markdowns: [], + warnings: [{ message: "Asynchronous Warning" }], + }) }) - }) - it("handles multiple scheduled statements and all message types", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileMultiScheduled.js"), runtime) - expect(results).toEqual({ - fails: [{ message: "Asynchronous Failure" }], - messages: [{ message: "Asynchronous Message" }], - markdowns: ["Asynchronous Markdown"], - warnings: [{ message: "Asynchronous Warning" }], + it("handles multiple scheduled statements and all message types", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileMultiScheduled.js"), runtime) + expect(results).toEqual({ + fails: [{ message: "Asynchronous Failure" }], + messages: [{ message: "Asynchronous Message" }], + markdowns: ["Asynchronous Markdown"], + warnings: [{ message: "Asynchronous Warning" }], + }) }) - }) - // This adds > 6 seconds to the tests! Only orta should be forced into that. - if (process.env["USER"] === "orta") { - it("can execute async/await scheduled functions", async () => { - // this test takes *forever* because of babel-polyfill being required + // This adds > 6 seconds to the tests! Only orta should be forced into that. + if (process.env["USER"] === "orta") { + it("can execute async/await scheduled functions", async () => { + // this test takes *forever* because of babel-polyfill being required + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileAsync.js"), runtime) + expect(results.warnings).toEqual([{ + message: "Async Function" + }, { + message: "After Async Function" + }]) + }) + } + + it("can schedule callback-based promised", async () => { const context = await setupDangerfileContext() const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileAsync.js"), runtime) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileCallback.js"), runtime) expect(results.warnings).toEqual([{ - message: "Async Function" - }, { - message: "After Async Function" + message: "Scheduled a callback", }]) }) - } - it("can schedule callback-based promised", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileCallback.js"), runtime) - expect(results.warnings).toEqual([{ - message: "Scheduled a callback", - }]) - }) + it("can handle TypeScript based Dangerfiles", async () => { + const context = await setupDangerfileContext() + const runtime = await createDangerfileRuntimeEnvironment(context) + const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileTypeScript.ts"), runtime) + expect(results.messages).toEqual([{ + message: "Honey, we got Types", + }]) + }) - it("can handle TypeScript based Dangerfiles", async () => { - const context = await setupDangerfileContext() - const runtime = await createDangerfileRuntimeEnvironment(context) - const results = await runDangerfileEnvironment(resolve(fixtures, "__DangerfileTypeScript.ts"), runtime) - expect(results.messages).toEqual([{ - message: "Honey, we got Types", - }]) }) - -}) +} describe("cleaning Dangerfiles", () => { it("Supports removing the danger import", () => { @@ -178,3 +187,20 @@ let { danger, warn, fail, message } = require('danger'); expect(cleanDangerfile(before)).toEqual(after) }) }) + +it("creates a working jest config", async () => { + const config = await dangerJestConfig() + // OK, this is almost perfect, but well, everyone has different paths. + // So we'll amend the ones that should be different per developer/CI + config.cacheDirectory = "[cache]" + config.testPathDirs = ["[testPathDirs]"] + config.testPathIgnorePatterns = ["[testPathIgnorePatterns]"] + + const cwd = process.cwd() + config.transform = config.transform.map(([files, transformer]) => { + const trans = transformer.includes("ts-jest") ? "[ts-jest-transformer]" : transformer + return [files, trans] + }) + + expect(config).toMatchSnapshot() +}) diff --git a/source/runner/_tests/__snapshots__/DangerRunner.test.ts.snap b/source/runner/_tests/__snapshots__/DangerRunner.test.ts.snap new file mode 100644 index 000000000..29638dc75 --- /dev/null +++ b/source/runner/_tests/__snapshots__/DangerRunner.test.ts.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`creates a working jest config 1`] = ` +Object { + "cache": null, + "cacheDirectory": "[cache]", + "haste": Object { + "defaultPlatform": "danger-js", + }, + "moduleDirectories": Array [ + "node_modules", + ], + "moduleFileExtensions": Array [ + "js", + "js", + "jsx", + "json", + "ts", + "tsx", + ], + "moduleNameMapper": Array [], + "name": "danger", + "setupFiles": Array [], + "testEnvironment": "node", + "testPathDirs": Array [ + "[testPathDirs]", + ], + "testPathIgnorePatterns": Array [ + "[testPathIgnorePatterns]", + ], + "testRegex": "", + "transform": Array [ + Array [ + "js$", + "babel-jest", + ], + Array [ + ".(ts|tsx)", + "[ts-jest-transformer]", + ], + ], + "transformIgnorePatterns": Array [ + "/node_modules/", + ], +} +`; diff --git a/source/runner/types.ts b/source/runner/types.ts index a4fa18527..001071df8 100644 --- a/source/runner/types.ts +++ b/source/runner/types.ts @@ -23,6 +23,19 @@ export interface EnvironmentConstructor { new (config: any): Environment } +export interface InternalModuleOptions { + isInternalModule: boolean, +} + +export interface JestRuntime { + requireModule( + from: Path, + moduleName?: string, + options?: InternalModuleOptions, + ): any + +} + export interface Environment extends EnvironmentConstructor { dispose(): void runScript(script: any): any diff --git a/yarn.lock b/yarn.lock index 0525675e9..dd49852ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -81,7 +81,7 @@ ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" -ansi-styles@^2.2.1: +ansi-styles@^2.1.0, ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -155,7 +155,7 @@ array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" -array-uniq@^1.0.2: +array-uniq@^1.0.0, array-uniq@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -209,26 +209,31 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-cli@^6.16.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.24.0.tgz#a05ffd210dca0c288a26d5319c5ac8669a265ad0" +babel-cli@6.16: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.16.0.tgz#4e0d1cf40442ef78330f7fef88eb3a0a1b16bd37" dependencies: - babel-core "^6.24.0" - babel-polyfill "^6.23.0" - babel-register "^6.24.0" - babel-runtime "^6.22.0" + babel-core "^6.16.0" + babel-polyfill "^6.16.0" + babel-register "^6.16.0" + babel-runtime "^6.9.0" + bin-version-check "^2.1.0" + chalk "1.1.1" commander "^2.8.1" convert-source-map "^1.1.0" - fs-readdir-recursive "^1.0.0" - glob "^7.0.0" + fs-readdir-recursive "^0.1.0" + glob "^5.0.5" lodash "^4.2.0" + log-symbols "^1.0.2" output-file-sync "^1.1.0" + path-exists "^1.0.0" path-is-absolute "^1.0.0" + request "^2.65.0" slash "^1.0.0" source-map "^0.5.0" v8flags "^2.0.10" optionalDependencies: - chokidar "^1.6.1" + chokidar "^1.0.0" babel-code-frame@^6.20.0, babel-code-frame@^6.22.0: version "6.22.0" @@ -238,7 +243,7 @@ babel-code-frame@^6.20.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@^6.0.0, babel-core@^6.24.0: +babel-core@^6.0.0, babel-core@^6.16.0, babel-core@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.0.tgz#8f36a0a77f5c155aed6f920b844d23ba56742a02" dependencies: @@ -376,14 +381,6 @@ babel-helpers@^6.23.0: babel-runtime "^6.22.0" babel-template "^6.23.0" -babel-jest@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-18.0.0.tgz#17ebba8cb3285c906d859e8707e4e79795fb65e3" - dependencies: - babel-core "^6.0.0" - babel-plugin-istanbul "^3.0.0" - babel-preset-jest "^18.0.0" - babel-jest@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-19.0.0.tgz#59323ced99a3a84d359da219ca881074ffc6ce3f" @@ -404,15 +401,6 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-istanbul@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-3.1.2.tgz#11d5abde18425ec24b5d648c7e0b5d25cd354a22" - dependencies: - find-up "^1.1.2" - istanbul-lib-instrument "^1.4.2" - object-assign "^4.1.0" - test-exclude "^3.3.0" - babel-plugin-istanbul@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.1.tgz#c12de0fc6fe42adfb16be56f1ad11e4a9782eca9" @@ -421,10 +409,6 @@ babel-plugin-istanbul@^4.0.0: istanbul-lib-instrument "^1.6.2" test-exclude "^4.0.3" -babel-plugin-jest-hoist@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-18.0.0.tgz#4150e70ecab560e6e7344adc849498072d34e12a" - babel-plugin-jest-hoist@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-19.0.0.tgz#4ae2a04ea612a6e73651f3fde52c178991304bea" @@ -645,7 +629,7 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-flow-strip-types@^6.8.0: +babel-plugin-transform-flow-strip-types@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" dependencies: @@ -659,7 +643,7 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-regenerator@^6.16.1, babel-plugin-transform-regenerator@^6.22.0: +babel-plugin-transform-regenerator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz#65740593a319c44522157538d690b84094617ea6" dependencies: @@ -672,7 +656,7 @@ babel-plugin-transform-strict-mode@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-polyfill@^6.20.0, babel-polyfill@^6.23.0: +babel-polyfill@^6.16.0, babel-polyfill@^6.20.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" dependencies: @@ -680,7 +664,7 @@ babel-polyfill@^6.20.0, babel-polyfill@^6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-es2015@^6.16.0: +babel-preset-es2015@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz#c162d68b1932696e036cd3110dc1ccd303d2673a" dependencies: @@ -709,19 +693,13 @@ babel-preset-es2015@^6.16.0: babel-plugin-transform-es2015-unicode-regex "^6.22.0" babel-plugin-transform-regenerator "^6.22.0" -babel-preset-jest@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-18.0.0.tgz#84faf8ca3ec65aba7d5e3f59bbaed935ab24049e" - dependencies: - babel-plugin-jest-hoist "^18.0.0" - babel-preset-jest@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-19.0.0.tgz#22d67201d02324a195811288eb38294bb3cac396" dependencies: babel-plugin-jest-hoist "^19.0.0" -babel-preset-stage-3@^6.17.0: +babel-preset-stage-3@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.22.0.tgz#a4e92bbace7456fafdf651d7a7657ee0bbca9c2e" dependencies: @@ -731,7 +709,7 @@ babel-preset-stage-3@^6.17.0: babel-plugin-transform-exponentiation-operator "^6.22.0" babel-plugin-transform-object-rest-spread "^6.22.0" -babel-register@^6.24.0: +babel-register@^6.16.0, babel-register@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.0.tgz#5e89f8463ba9970356d02eb07dabe3308b080cfd" dependencies: @@ -743,7 +721,7 @@ babel-register@^6.24.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0: +babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.9.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: @@ -807,6 +785,21 @@ beeper@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" +bin-version-check@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-2.1.0.tgz#e4e5df290b9069f7d111324031efc13fdd11a5b0" + dependencies: + bin-version "^1.0.0" + minimist "^1.1.0" + semver "^4.0.3" + semver-truncate "^1.0.0" + +bin-version@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-1.0.4.tgz#9eb498ee6fd76f7ab9a7c160436f89579435d78e" + dependencies: + find-versions "^1.0.0" + binary-extensions@^1.0.0: version "1.8.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" @@ -918,6 +911,16 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chalk@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.1.tgz#509afb67066e7499f7eb3535c77445772ae2d019" + dependencies: + ansi-styles "^2.1.0" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -928,7 +931,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chokidar@^1.6.1: +chokidar@^1.0.0: version "1.6.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" dependencies: @@ -1431,7 +1434,7 @@ fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" -fb-watchman@^1.8.0, fb-watchman@^1.9.0: +fb-watchman@^1.8.0: version "1.9.2" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.2.tgz#a24cf47827f82d38fb59a69ad70b76e3b6ae7383" dependencies: @@ -1496,7 +1499,7 @@ find-parent-dir@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" -find-up@^1.0.0, find-up@^1.1.2: +find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" dependencies: @@ -1509,6 +1512,15 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-versions@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-1.2.1.tgz#cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62" + dependencies: + array-uniq "^1.0.0" + get-stdin "^4.0.1" + meow "^3.5.0" + semver-regex "^1.0.0" + find@0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/find/-/find-0.2.6.tgz#0d218b5d48c3424193f64cea59d389f8daa71d01" @@ -1559,9 +1571,9 @@ fs-extra@~0.6.4: ncp "~0.4.2" rimraf "~2.2.0" -fs-readdir-recursive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" +fs-readdir-recursive@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" fs.realpath@^1.0.0: version "1.0.0" @@ -1649,7 +1661,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^5.0.15, glob@~5.0.0: +glob@^5.0.15, glob@^5.0.5, glob@~5.0.0: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: @@ -2055,7 +2067,7 @@ istanbul-lib-hook@^1.0.5: dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.2.0, istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.6.2, istanbul-lib-instrument@^1.7.0: +istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.2.0, istanbul-lib-instrument@^1.6.2, istanbul-lib-instrument@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.0.tgz#b8e0dc25709bb44e17336ab47b7bb5c97c23f659" dependencies: @@ -2146,19 +2158,6 @@ jest-cli@^19.0.2: worker-farm "^1.3.1" yargs "^6.3.0" -jest-config@^18.0.0, jest-config@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-18.1.0.tgz#6111740a6d48aab86ff5a9e6ab0b98bd993b6ff4" - dependencies: - chalk "^1.1.1" - jest-environment-jsdom "^18.1.0" - jest-environment-node "^18.1.0" - jest-jasmine2 "^18.1.0" - jest-mock "^18.0.0" - jest-resolve "^18.1.0" - jest-util "^18.1.0" - json-stable-stringify "^1.0.0" - jest-config@^19.0.0, jest-config@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-19.0.2.tgz#1b9bd2db0ddd16df61c2b10a54009e1768da6411" @@ -2172,15 +2171,6 @@ jest-config@^19.0.0, jest-config@^19.0.2: jest-validate "^19.0.2" pretty-format "^19.0.0" -jest-diff@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-18.1.0.tgz#4ff79e74dd988c139195b365dc65d87f606f4803" - dependencies: - chalk "^1.1.3" - diff "^3.0.0" - jest-matcher-utils "^18.1.0" - pretty-format "^18.1.0" - jest-diff@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-19.0.0.tgz#d1563cfc56c8b60232988fbc05d4d16ed90f063c" @@ -2190,14 +2180,6 @@ jest-diff@^19.0.0: jest-matcher-utils "^19.0.0" pretty-format "^19.0.0" -jest-environment-jsdom@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-18.1.0.tgz#18b42f0c4ea2bae9f36cab3639b1e8f8c384e24e" - dependencies: - jest-mock "^18.0.0" - jest-util "^18.1.0" - jsdom "^9.9.1" - jest-environment-jsdom@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-19.0.2.tgz#ceda859c4a4b94ab35e4de7dab54b926f293e4a3" @@ -2206,13 +2188,6 @@ jest-environment-jsdom@^19.0.2: jest-util "^19.0.2" jsdom "^9.11.0" -jest-environment-node@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-18.1.0.tgz#4d6797572c8dda99acf5fae696eb62945547c779" - dependencies: - jest-mock "^18.0.0" - jest-util "^18.1.0" - jest-environment-node@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-19.0.2.tgz#6e84079db87ed21d0c05e1f9669f207b116fe99b" @@ -2220,24 +2195,10 @@ jest-environment-node@^19.0.2: jest-mock "^19.0.0" jest-util "^19.0.2" -jest-file-exists@^17.0.0: - version "17.0.0" - resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-17.0.0.tgz#7f63eb73a1c43a13f461be261768b45af2cdd169" - jest-file-exists@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-19.0.0.tgz#cca2e587a11ec92e24cfeab3f8a94d657f3fceb8" -jest-haste-map@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-18.1.0.tgz#06839c74b770a40c1a106968851df8d281c08375" - dependencies: - fb-watchman "^1.9.0" - graceful-fs "^4.1.6" - micromatch "^2.3.11" - sane "~1.4.1" - worker-farm "^1.3.1" - jest-haste-map@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-19.0.0.tgz#adde00b62b1fe04432a104b3254fc5004514b55e" @@ -2248,16 +2209,6 @@ jest-haste-map@^19.0.0: sane "~1.5.0" worker-farm "^1.3.1" -jest-jasmine2@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-18.1.0.tgz#094e104c2c189708766c77263bb2aecb5860a80b" - dependencies: - graceful-fs "^4.1.6" - jest-matcher-utils "^18.1.0" - jest-matchers "^18.1.0" - jest-snapshot "^18.1.0" - jest-util "^18.1.0" - jest-jasmine2@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-19.0.2.tgz#167991ac825981fb1a800af126e83afcca832c73" @@ -2268,13 +2219,6 @@ jest-jasmine2@^19.0.2: jest-message-util "^19.0.0" jest-snapshot "^19.0.2" -jest-matcher-utils@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-18.1.0.tgz#1ac4651955ee2a60cef1e7fcc98cdfd773c0f932" - dependencies: - chalk "^1.1.3" - pretty-format "^18.1.0" - jest-matcher-utils@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d" @@ -2282,15 +2226,6 @@ jest-matcher-utils@^19.0.0: chalk "^1.1.3" pretty-format "^19.0.0" -jest-matchers@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-18.1.0.tgz#0341484bf87a1fd0bac0a4d2c899e2b77a3f1ead" - dependencies: - jest-diff "^18.1.0" - jest-matcher-utils "^18.1.0" - jest-util "^18.1.0" - pretty-format "^18.1.0" - jest-matchers@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-19.0.0.tgz#c74ecc6ebfec06f384767ba4d6fa4a42d6755754" @@ -2307,10 +2242,6 @@ jest-message-util@^19.0.0: chalk "^1.1.1" micromatch "^2.3.11" -jest-mock@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-18.0.0.tgz#5c248846ea33fa558b526f5312ab4a6765e489b3" - jest-mock@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-19.0.0.tgz#67038641e9607ab2ce08ec4a8cb83aabbc899d01" @@ -2325,15 +2256,6 @@ jest-resolve-dependencies@^19.0.0: dependencies: jest-file-exists "^19.0.0" -jest-resolve@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-18.1.0.tgz#6800accb536658c906cd5e29de412b1ab9ac249b" - dependencies: - browser-resolve "^1.11.2" - jest-file-exists "^17.0.0" - jest-haste-map "^18.1.0" - resolve "^1.2.0" - jest-resolve@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-19.0.2.tgz#5793575de4f07aec32f7d7ff0c6c181963eefb3c" @@ -2342,26 +2264,6 @@ jest-resolve@^19.0.2: jest-haste-map "^19.0.0" resolve "^1.2.0" -jest-runtime@^18.0.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-18.1.0.tgz#3abfd687175b21fc3b85a2b8064399e997859922" - dependencies: - babel-core "^6.0.0" - babel-jest "^18.0.0" - babel-plugin-istanbul "^3.0.0" - chalk "^1.1.3" - graceful-fs "^4.1.6" - jest-config "^18.1.0" - jest-file-exists "^17.0.0" - jest-haste-map "^18.1.0" - jest-mock "^18.0.0" - jest-resolve "^18.1.0" - jest-snapshot "^18.1.0" - jest-util "^18.1.0" - json-stable-stringify "^1.0.0" - micromatch "^2.3.11" - yargs "^6.3.0" - jest-runtime@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-19.0.2.tgz#d9a43e72de416d27d196fd9c7940d98fe6685407" @@ -2382,17 +2284,6 @@ jest-runtime@^19.0.2: strip-bom "3.0.0" yargs "^6.3.0" -jest-snapshot@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-18.1.0.tgz#55b96d2ee639c9bce76f87f2a3fd40b71c7a5916" - dependencies: - jest-diff "^18.1.0" - jest-file-exists "^17.0.0" - jest-matcher-utils "^18.1.0" - jest-util "^18.1.0" - natural-compare "^1.4.0" - pretty-format "^18.1.0" - jest-snapshot@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-19.0.2.tgz#9c1b216214f7187c38bfd5c70b1efab16b0ff50b" @@ -2405,17 +2296,6 @@ jest-snapshot@^19.0.2: natural-compare "^1.4.0" pretty-format "^19.0.0" -jest-util@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-18.1.0.tgz#3a99c32114ab17f84be094382527006e6d4bfc6a" - dependencies: - chalk "^1.1.1" - diff "^3.0.0" - graceful-fs "^4.1.6" - jest-file-exists "^17.0.0" - jest-mock "^18.0.0" - mkdirp "^0.5.1" - jest-util@^19.0.0, jest-util@^19.0.2: version "19.0.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-19.0.2.tgz#e0a0232a2ab9e6b2b53668bdb3534c2b5977ed41" @@ -2465,7 +2345,7 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" -jsdom@^9.11.0, jsdom@^9.9.1: +jsdom@^9.11.0: version "9.12.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" dependencies: @@ -2509,7 +2389,7 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -2862,7 +2742,7 @@ memory-fs@^0.4.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.3.0: +meow@^3.3.0, meow@^3.5.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -3266,6 +3146,10 @@ parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" +path-exists@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -3354,12 +3238,6 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -pretty-format@^18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-18.1.0.tgz#fb65a86f7a7f9194963eee91865c1bcf1039e284" - dependencies: - ansi-styles "^2.2.1" - pretty-format@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84" @@ -3569,7 +3447,7 @@ replace-ext@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" -request@^2.79.0, request@^2.81.0: +request@^2.65.0, request@^2.79.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -3678,17 +3556,6 @@ safe-buffer@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" -sane@~1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sane/-/sane-1.4.1.tgz#88f763d74040f5f0c256b6163db399bf110ac715" - dependencies: - exec-sh "^0.2.0" - fb-watchman "^1.8.0" - minimatch "^3.0.2" - minimist "^1.1.1" - walker "~1.0.5" - watch "~0.10.0" - sane@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/sane/-/sane-1.5.0.tgz#a4adeae764d048621ecb27d5f9ecf513101939f3" @@ -3718,10 +3585,24 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" +semver-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" + +semver-truncate@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" + dependencies: + semver "^5.3.0" + "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" +semver@^4.0.3: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -3973,16 +3854,6 @@ term-size@^0.1.0: dependencies: execa "^0.4.0" -test-exclude@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-3.3.0.tgz#7a17ca1239988c98367b0621456dbb7d4bc38977" - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - test-exclude@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.0.3.tgz#86a13ce3effcc60e6c90403cf31a27a60ac6c4e7" @@ -4054,7 +3925,7 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -ts-jest@^19.0.0: +ts-jest@^19.0.2: version "19.0.6" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-19.0.6.tgz#757bbebe861a540f467bfa310fdb9e09db40ba2a" dependencies: @@ -4094,7 +3965,7 @@ tsconfig@^6.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslint@^4.4.0: +tslint@^4.5.1: version "4.5.1" resolved "https://registry.yarnpkg.com/tslint/-/tslint-4.5.1.tgz#05356871bef23a434906734006fc188336ba824b" dependencies: