Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hipstersmoothie committed May 17, 2020
1 parent 4dcfae4 commit 6aea8ac
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 10 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
{
"files": ["*.test.*"],
"rules": {
"no-import-assign": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-explicit-any": 0,
Expand Down
1 change: 1 addition & 0 deletions plugins/first-time-contributor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class FirstTimeContributorPlugin implements IPlugin {

/** Tap into auto plugin points. */
apply(auto: Auto) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const cache: Record<string, Record<string, any>> = {};

auto.hooks.onCreateChangelog.tap(this.name, (changelog) => {
Expand Down
10 changes: 10 additions & 0 deletions plugins/gem/__tests__/__snapshots__/gem.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Gem Plugin validateConfig validates invalid configuration 1`] = `
Array [
"\\"gem\\"
Found unknown configuration keys: command
",
]
`;
301 changes: 299 additions & 2 deletions plugins/gem/__tests__/gem.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,303 @@
import Auto from "@auto-it/core";
import * as Auto from "@auto-it/core";
import glob from "fast-glob";
import { makeHooks } from "@auto-it/core/dist/utils/make-hooks";
import { dummyLog } from "@auto-it/core/dist/utils/logger";
import { execSync } from "child_process";

import * as utils from "../src/utils";
import Gem from "../src";
import endent from "endent";
import { SEMVER } from "@auto-it/core";

const logger = dummyLog();

const execSyncSpy = jest.fn();
jest.mock("child_process");
// @ts-ignore
execSync.mockImplementation(execSyncSpy);

const execSpy = jest.fn();
execSpy.mockReturnValue("");
// @ts-ignore
jest.spyOn(Auto, "execPromise").mockImplementation(execSpy);

const globSpy = jest.fn();
jest.mock("fast-glob");
glob.sync = globSpy;

const readFile = jest.fn();
const writeFile = jest.fn();
jest.mock("../src/utils");
// @ts-ignore
utils.readFile = readFile as any;
// @ts-ignore
utils.writeFile = writeFile as any;

describe("Gem Plugin", () => {
test("should do something", async () => {});
beforeEach(() => {
globSpy.mockReset();
readFile.mockReset();
});

test("throws without a gemspec", async () => {
expect(() => new Gem()).toThrow();
});

test("loads with a gemspec", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
expect(() => new Gem()).not.toThrow();
});

describe("validateConfig", () => {
test("validates invalid configuration", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks } as any);

expect(
await hooks.validateConfig.promise("gem", { command: "foo" })
).toMatchSnapshot();
});

test("validates valid configuration", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks } as any);

expect(
await hooks.validateConfig.promise("gem", { releaseCommand: "foo" })
).toStrictEqual([]);
});
});

describe("getPreviousVersion", () => {
test("gets previous version from gemspec", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
spec.version = "0.1.0"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getPreviousVersion.promise()).toBe("0.1.0");
});

test("gets previous version from a version file", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
globSpy.mockReturnValueOnce("lib/version/version.rb");
readFile.mockReturnValueOnce("");
readFile.mockReturnValueOnce(endent`
module HelloWorld
VERSION = "0.1.14"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getPreviousVersion.promise()).toBe("0.1.14");
});

test("throws if no version found", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

await expect(hooks.getPreviousVersion.promise()).rejects.toBeInstanceOf(
Error
);
});
});

describe("getAuthor", () => {
test("gets author from gemspec", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
spec.authors = ["Andrew Lisowski"]
spec.email = ["lisowski54@gmail.com"]
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getAuthor.promise()).toStrictEqual({
name: "Andrew Lisowski",
email: "lisowski54@gmail.com",
});
});
});

describe("getRepository", () => {
test("returns if no url found", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getRepository.promise()).toBeUndefined();
});

test("returns if no repo found in url", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
spec.homepage = "https://google.com/"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getRepository.promise()).toBeUndefined();
});

test("find repo in homepage", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
spec.homepage = "https://github.com/hipstersmoothie/auto-gem-test"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getRepository.promise()).toStrictEqual({
owner: "hipstersmoothie",
repo: "auto-gem-test",
});
});

test("prefer repo in source_code_uri", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValueOnce(endent`
Gem::Specification.new do |spec|
spec.homepage = "https://github.com/hipstersmoothie/foo-bar"
spec.metadata["source_code_uri"] = "https://github.com/hipstersmoothie/auto-gem-test"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

expect(await hooks.getRepository.promise()).toStrictEqual({
owner: "hipstersmoothie",
repo: "auto-gem-test",
});
});
});

describe("version", () => {
test("bump version", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValue(endent`
Gem::Specification.new do |spec|
spec.version = "0.1.0"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);
await hooks.version.promise(SEMVER.minor);

expect(writeFile).toHaveBeenCalledWith(
"test.gemspec",
endent`
Gem::Specification.new do |spec|
spec.version = "0.2.0"
end
`
);
});

test("throws with invalid version", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValue(endent`
Gem::Specification.new do |spec|
spec.version = "0.1.avc"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);

await expect(hooks.version.promise(SEMVER.minor)).rejects.toBeInstanceOf(
Error
);
});
});

describe("publish", () => {
test("uses bundler + rake as default publishing method", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValue(endent`
Gem::Specification.new do |spec|
spec.version = "0.1.0"
end
`);

const plugin = new Gem();
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);
await hooks.publish.promise(SEMVER.minor);

expect(execSpy).toHaveBeenCalledWith("bundle", ["exec", "rake", "build"]);
});

test("user can configure release command", async () => {
globSpy.mockReturnValueOnce(["test.gemspec"]);
readFile.mockReturnValue(endent`
Gem::Specification.new do |spec|
spec.version = "0.1.0"
end
`);

const plugin = new Gem({
releaseCommand: "gem release --tag --push",
});
const hooks = makeHooks();

plugin.apply({ hooks, logger } as any);
await hooks.publish.promise(SEMVER.minor);

expect(execSyncSpy).toHaveBeenCalledWith("gem release --tag --push", {
stdio: "inherit",
});
});
});
});
15 changes: 7 additions & 8 deletions plugins/gem/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import {
} from "@auto-it/core";
import { execSync } from "child_process";
import * as fs from "fs";
import { promisify } from "util";
import endent from "endent";
import glob from "fast-glob";
import parseGitHubUrl from "parse-github-url";
import { inc, ReleaseType } from "semver";
import * as t from "io-ts";
import envCi from "env-ci";
import { readFile, writeFile } from "./utils";

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const VERSION_REGEX = /\d+\.\d+\.\d+/;
const { isCi } = envCi();

Expand All @@ -32,9 +30,9 @@ export default class GemPlugin implements IPlugin {
name = "gem";

/** A path the gemspec to publish */
readonly gemspec: string;
private readonly gemspec: string;
/** User options for the plugins */
readonly options: IGemPluginOptions;
private readonly options: IGemPluginOptions;

/** Initialize the plugin with it's options */
constructor(options: IGemPluginOptions = {}) {
Expand Down Expand Up @@ -107,8 +105,9 @@ export default class GemPlugin implements IPlugin {
const newTag = inc(version, bump as ReleaseType);

if (!newTag) {
auto.logger.log.info("No release found, doing nothing");
return;
throw new Error(
`The version "${version}" parsed from your version file "${versionFile}" was invalid and could not be incremented. Please fix this!`
);
}

const content = await readFile(versionFile, { encoding: "utf8" });
Expand Down Expand Up @@ -172,6 +171,6 @@ export default class GemPlugin implements IPlugin {
}
}

throw new Error("No version found!");
throw new Error("No version found in gemspec or version.rb!");
}
}
5 changes: 5 additions & 0 deletions plugins/gem/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as fs from "fs";
import { promisify } from "util";

export const readFile = promisify(fs.readFile);
export const writeFile = promisify(fs.writeFile);

0 comments on commit 6aea8ac

Please sign in to comment.