From e346b37b076d2d5acbde42e6c8810a452c47c117 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:05:20 +0200 Subject: [PATCH 01/48] test: Add test --- tests/unit/core/badges.spec.ts | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 79080823..b3afbef8 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,4 +1,8 @@ -import { markdownImage, markdownLink } from "@/core/badges"; +import { + markdownImage, + markdownImageWithLink, + markdownLink +} from "@/core/badges"; describe("#markdownLink", () => { it("returns a valid markdown link", () => { @@ -12,20 +16,33 @@ describe("#markdownLink", () => { describe("#markdownImage", () => { it("returns a valid markdown image", () => { - expect(markdownImage("Alt text", "foo.md")).toBe("![Alt text](foo.md)"); + expect(markdownImage("Alt text", "foo.png")).toBe("![Alt text](foo.png)"); - expect(markdownImage("Example", "https://example.com")).toBe( - "![Example](https://example.com)" + expect(markdownImage("Example", "https://example.com/foo.png")).toBe( + "![Example](https://example.com/foo.png)" ); }); it("returns a valid markdown image with hover text", () => { - expect(markdownImage("Alt text", "foo.md", "My hover text")).toBe( - '![Alt text](foo.md "My hover text")' + expect(markdownImage("Alt text", "foo.png", "My hover text")).toBe( + '![Alt text](foo.png "My hover text")' ); expect( - markdownImage("Example", "https://example.com", "Go to example") - ).toBe('![Example](https://example.com "Go to example")'); + markdownImage("Example", "https://example.com", "My example") + ).toBe('![Example](https://example.com "My example")'); + }); +}); + +describe("#markdownImageWithLink", () => { + it("returns a valid tag using all parameters set", () => { + expect( + markdownImageWithLink( + "Alt text", + "foo.png", + "https://example.com", + "My foo" + ) + ).toBe('[![Alt text](foo.png "My foo")](https://example.com)'); }); }); From d7ce317de74b6b7f4dce1d3459775acf64f13993 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:34:03 +0200 Subject: [PATCH 02/48] fix: Update encode --- src/core/badges.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 2712094a..35c6a650 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -37,25 +37,22 @@ export function markdownImageWithLink( /** * Encode a value to safe as a param in a URL. * - * Prepare a value for dash-baseds shields.io API based on notes on the site. - * The builtin encodeURI function is used to handle spaces and special characters. + * Prepare a value for dash-based shields.io API based on notes on the site. See badges.spec.ts for cases. * - * Note that '>' and '<' are valid on shields.io and should not be encoded. + * A builtin function is used to handle spaces and special characters. * - * e.g. 'Foo Bar_Baz-Buzz' becomes 'Foo_Bar__Baz--Buzz'. - * Note the API itself does funny things if you do use more than one - * occurence of dash and space or underscore and space when when this is escaped correctly. - * e.g. 'A - B - C' converted to 'A_--_B_--_C' renders as 'A - B_- C'. - * So just don't mix them and you'll be ok - like with 'A-B-C'. + * Note the shields.io API itself does funny things if you do use more than one + * occurence of dash and space or underscore and space when this is escaped correctly. + * e.g. 'A - B - C' converted to 'A_--_B_--_C' unfortunately renders in the SVG result 'A - B_- C'. + * So just don't mix them and you'll be ok. Like do 'A-B-C'. */ -function encode(value: string, spaceToUnderscore = true) { +export function encode(value: string, spaceToUnderscore = true) { value = value.replace(/-/g, "--").replace(/_/g, "__"); if (spaceToUnderscore) { value = value.replace(/ /g, "_"); } - - const encoded = encodeURI(value); + const encoded = encodeURIComponent(value); return encoded.replace(/%3E/g, ">").replace(/%3C/g, "<"); } From 021f13cf4cddf5e4bfc69647c8dce4681eefe0cc Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:34:07 +0200 Subject: [PATCH 03/48] test: Add tests --- tests/unit/core/badges.spec.ts | 87 +++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index b3afbef8..f369fd4c 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,5 +1,19 @@ +/* +Template: + +describe("#foo", () => { + it("", () => { + expect( + foo( + "" + ) + ).toBe(""); + }); +}); +*/ + import { - markdownImage, + encode, markdownImage, markdownImageWithLink, markdownLink } from "@/core/badges"; @@ -46,3 +60,74 @@ describe("#markdownImageWithLink", () => { ).toBe('[![Alt text](foo.png "My foo")](https://example.com)'); }); }); + +describe("#encode", () => { + it("convert a space to an underscore", () => { + expect( + encode( + "Foo Bar" + ) + ).toBe("Foo_Bar"); + }) + + it("converts a single dash to two", () => { + expect( + encode( + "Foo-Bar" + ) + ).toBe("Foo--Bar"); + }); + + it("converts a single underscore to two", () => { + expect( + encode( + "Foo_Bar" + ) + ).toBe("Foo__Bar"); + }); + + it("converts a mix of space, underscore and a dash correctly", () => { + expect( + encode( + "Foo Bar_Baz-Buzz" + ) + ).toBe("Foo_Bar__Baz--Buzz"); + }); + + // These could appear when putting a URL as a value in the path, so need to be escaped. + it("encodes special characters likely correctly", () => { + expect( + encode( + "&" + ) + ).toBe("%26"); + + expect( + encode( + "/" + ) + ).toBe("%2F"); + + + expect( + encode( + "?" + ) + ).toBe("%3F"); + }); + + // Note that '>' and '<' are valid on shields.io and should not be encoded. + it("encodes a string correctly without converting angle brackets", () => { + expect( + encode( + ">=3" + ) + ).toBe(">%3D3"); + + expect( + encode( + "<2" + ) + ).toBe("<2"); + }); +}); From 9482dca9819347518f48d632729ea45a3090be7d Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:15:39 +0200 Subject: [PATCH 04/48] build: Update Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 34cf61e9..a8aa2a86 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,9 @@ install: l lint: yarn lint:fix + t test: + yarn compile yarn test:unit s serve: lint test From 68782294de7764b302078d9bb7803d32655fd662 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:15:41 +0200 Subject: [PATCH 05/48] docs: Update usage.md --- docs/usage.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 250f39ef..8fc60290 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -3,6 +3,7 @@ ## Run dev server This will compile TS to JS and serve the app. + ```sh $ yarn start ``` @@ -39,11 +40,16 @@ Run unit tests. ```sh $ yarn test:unit -$ # Or +``` + +Note that it able to work with the TS files directly. It this does need or produce any output JS files. + +To add the ability to get errors from the TypeScript compiler (such as bad use of arguments) before the tests are run, use this: + +```sh $ make test ``` -Note that this does need or produce any output directory. It operates directly on the `.ts` files. ## Compile From 9831184c9c02db5f582fdefc18814787765bb683 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:17:08 +0200 Subject: [PATCH 06/48] refactor: Make color a required default --- src/core/badges.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 35c6a650..786147e3 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -1,7 +1,7 @@ /** * Handle rendering of each badge and all badges. */ -import { DEFAULT_COLOR, SHIELDS_BADGE, SHIELDS_STATIC } from "./constants"; +import { SHIELDS_BADGE, SHIELDS_STATIC } from "./constants"; // TODO combine link/target functions in a module. export function markdownLink(altText: string, linkTarget: string) { @@ -172,27 +172,23 @@ function staticDashUrl({ label, message, color, styleParams }: GenericBadge) { * Everything is optional except message. * * In the dash style, the result is LABEL-MESSAGE-COLOR or MESSABE-COLOR. The API needs color to be - * set. - * Sample: https://img.shields.io/badge/Foo-Bar--Baz-green + * set, so this is made a required param here on this function. + * Sample URL: https://img.shields.io/badge/Foo-Bar--Baz-green * - * Use the params style by setting onlyQueryParams to be true. There result is more verbose but does - * not required escaping characters. Sample: + * Use the params style by setting onlyQueryParams to be true. The result is more verbose but does + * not require escaping characters. Sample: * https://img.shields.io/static/v1?label=MichaelCurrin&message=badge-generator&logo=github&color=blue */ export function genericBadge( label = "", message: string, - color = "", + color: string, isLarge = false, target = "", logo = "", logoColor = "", onlyQueryParams = false ) { - if (!color) { - color = DEFAULT_COLOR; - } - const title = formatTitle(label, message); const styleParams = logoParams(isLarge, logo, logoColor), From e822fed7d71c9f302fb45670bf9dc2623d9e5a43 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Sat, 12 Dec 2020 21:17:18 +0200 Subject: [PATCH 07/48] test: Add tests to badges.spec.ts --- tests/unit/core/badges.spec.ts | 133 ++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index f369fd4c..288c1768 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -13,9 +13,11 @@ describe("#foo", () => { */ import { - encode, markdownImage, + encode, + genericBadge, + markdownImage, markdownImageWithLink, - markdownLink + markdownLink, } from "@/core/badges"; describe("#markdownLink", () => { @@ -42,9 +44,9 @@ describe("#markdownImage", () => { '![Alt text](foo.png "My hover text")' ); - expect( - markdownImage("Example", "https://example.com", "My example") - ).toBe('![Example](https://example.com "My example")'); + expect(markdownImage("Example", "https://example.com", "My example")).toBe( + '![Example](https://example.com "My example")' + ); }); }); @@ -63,71 +65,102 @@ describe("#markdownImageWithLink", () => { describe("#encode", () => { it("convert a space to an underscore", () => { - expect( - encode( - "Foo Bar" - ) - ).toBe("Foo_Bar"); - }) + expect(encode("Foo Bar")).toBe("Foo_Bar"); + }); it("converts a single dash to two", () => { - expect( - encode( - "Foo-Bar" - ) - ).toBe("Foo--Bar"); + expect(encode("Foo-Bar")).toBe("Foo--Bar"); }); it("converts a single underscore to two", () => { - expect( - encode( - "Foo_Bar" - ) - ).toBe("Foo__Bar"); + expect(encode("Foo_Bar")).toBe("Foo__Bar"); }); it("converts a mix of space, underscore and a dash correctly", () => { - expect( - encode( - "Foo Bar_Baz-Buzz" - ) - ).toBe("Foo_Bar__Baz--Buzz"); + expect(encode("Foo Bar_Baz-Buzz")).toBe("Foo_Bar__Baz--Buzz"); }); // These could appear when putting a URL as a value in the path, so need to be escaped. it("encodes special characters likely correctly", () => { - expect( - encode( - "&" - ) - ).toBe("%26"); + expect(encode("&")).toBe("%26"); - expect( - encode( - "/" - ) - ).toBe("%2F"); + expect(encode("/")).toBe("%2F"); - - expect( - encode( - "?" - ) - ).toBe("%3F"); + expect(encode("?")).toBe("%3F"); }); // Note that '>' and '<' are valid on shields.io and should not be encoded. it("encodes a string correctly without converting angle brackets", () => { + expect(encode(">=3")).toBe(">%3D3"); + + expect(encode("<2")).toBe("<2"); + }); +}); + +// These cases are based on common choices and defaults in the UI, to save on testing the frontend directly. +describe("#genericBadge", () => { + it("displays a badge given a message and a color", () => { + expect(genericBadge("", "Bar", "green")).toBe( + "![Bar](https://img.shields.io/badge/Bar-green)" + ); + }); + + it("displays a badge given label, message and a color", () => { + expect(genericBadge("Foo", "Bar", "green")).toBe( + "![Foo - Bar](https://img.shields.io/badge/Foo-Bar-green)" + ); + }); + + it("displays a badge point to external link", () => { + const target = "https://example.com"; + + expect(genericBadge("", "Bar", "green", false, target)).toBe( + "[![Bar](https://img.shields.io/badge/Bar-green)](https://example.com)" + ); + + expect(genericBadge("", "Bar", "green", false, target, "", "", true)).toBe( + "[![Bar](https://img.shields.io/static/v1?message=Bar&color=green)](https://example.com)" + ); + }); + + it("displays a large badge", () => { + const displayLarge = true; + + expect(genericBadge("", "Bar", "green", displayLarge)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?style=for-the-badge)" + ); + expect( - encode( - ">=3" - ) - ).toBe(">%3D3"); + genericBadge("", "Bar", "green", displayLarge, "", "", "", true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&style=for-the-badge)" + ); + }); + + it("displays a logo", () => { + const logo = "github"; + + expect(genericBadge("", "Bar", "green", false, "", logo)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github)" + ); + + expect(genericBadge("", "Bar", "green", false, "", logo, "", true)).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github)" + ); + }); + + it("displays a logo with a custom logo color", () => { + const logo = "github", + logoColor = "yellow"; + + expect(genericBadge("", "Bar", "green", false, "", logo, logoColor)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github&logoColor=yellow)" + ); expect( - encode( - "<2" - ) - ).toBe("<2"); + genericBadge("", "Bar", "green", false, "", logo, logoColor, true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github&logoColor=yellow)" + ); }); }); From a494b67f98dab5dda7ce9a3d894557c5e7d75d8a Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:14:08 +0200 Subject: [PATCH 08/48] test: Ignore dist directory --- jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jest.config.js b/jest.config.js index f9d5bfe8..92fbd7a9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,4 @@ module.exports = { preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel", + testPathIgnorePatterns: ["/dist/"] }; From a82165f0af968768f837f66c7f4a2931298f1aea Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:37:22 +0200 Subject: [PATCH 09/48] docs: Update development.md --- docs/development.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/docs/development.md b/docs/development.md index ca51ced6..32f19b3b 100644 --- a/docs/development.md +++ b/docs/development.md @@ -4,7 +4,7 @@ ## Roadmap -- [ ] Add tests +- [x] Add tests - [ ] Refactor JS to be DRY - [x] Add TS support - [ ] Use interfaces and types @@ -166,10 +166,49 @@ Therefore formatting rules can be set at a few levels, which makes things confus - Editor Config file (for indentation at least.) +## Tests + +All functions tested needed `export` so they can be imported. A leading underscore is used to indicate functions are private - intended for use only within a module and not to be called directly (except in tests). + +A template for new tests: + +``` +describe("#foo", () => { + it("", () => { + expect( + foo( + "" + ) + ).toBe(""); + }); +}); +``` + + ## Packages On upgrading packages. +Check outdated plugins: + +```sh +$ npx vue outdatded +``` + +Outdated packages: + +```sh +$ yarn oudated +``` + +Upgrade: + +```sh +$ yarn add foo +``` + +That will use the high available without conflicting with extant packages. + I attempted to upgrade these outdated packages as follows: ``` From cbcb7cefafb9d3590cc5c731571245c63534e0db Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:37:30 +0200 Subject: [PATCH 10/48] docs: Update usage.md --- docs/usage.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 8fc60290..6d7a6c17 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -8,7 +8,7 @@ This will compile TS to JS and serve the app. $ yarn start ``` -This does the same but adds lint fixes and tests first. +This does the same but adds lint fixes first. Tests are left out so the app can still be used without passing tests. ```sh $ make serve @@ -50,6 +50,7 @@ To add the ability to get errors from the TypeScript compiler (such as bad use o $ make test ``` +Or just look for TypeScript errors in the IDE. ## Compile From cef28c41fbd13b53e95ad5cd7310f3f73576a03a Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:37:37 +0200 Subject: [PATCH 11/48] build: Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a8aa2a86..0a4db4a0 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ t test: yarn compile yarn test:unit -s serve: lint test +s serve: lint yarn start From d54e6eadd06b18b867557117fef9c2463ffc466f Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:37:57 +0200 Subject: [PATCH 12/48] refactor: Update badges.ts --- src/core/badges.ts | 52 +++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 786147e3..381be6b6 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -35,41 +35,45 @@ export function markdownImageWithLink( } /** - * Encode a value to safe as a param in a URL. + * Replace dashes, underscores and spaces to match shields.io API format. * - * Prepare a value for dash-based shields.io API based on notes on the site. See badges.spec.ts for cases. - * - * A builtin function is used to handle spaces and special characters. - * - * Note the shields.io API itself does funny things if you do use more than one - * occurence of dash and space or underscore and space when this is escaped correctly. - * e.g. 'A - B - C' converted to 'A_--_B_--_C' unfortunately renders in the SVG result 'A - B_- C'. - * So just don't mix them and you'll be ok. Like do 'A-B-C'. + * Spaces are converted to underscores - so if you pass the result to an encode functions they won't become '%20'. */ -export function encode(value: string, spaceToUnderscore = true) { +export function _encodeSeparators(value: string, spaceToUnderscore: boolean) { value = value.replace(/-/g, "--").replace(/_/g, "__"); if (spaceToUnderscore) { value = value.replace(/ /g, "_"); } - const encoded = encodeURIComponent(value); - return encoded.replace(/%3E/g, ">").replace(/%3C/g, "<"); + return value; +} + +/** + * Turn URL-encoded '<' and '>' back into characters. + */ +export function _decodeAngleBrackets(value: string) { + return value.replace(/%3E/g, ">").replace(/%3C/g, "<"); } /** - * Make a fixed markdown badge using any given inputs. + * Encode a value to be safe as a param in a URL. * - * Escapes URLs. - * TODO: Avoid escaping if internal URLs. - * TODO: Maybe remove this function. + * See badges.spec.ts for cases. + * + * Prepare a value for dash-based shields.io API based on notes on that site. + * + * Note the shields.io API itself does funny things if you do use more than one + * occurence of dash and space or underscore and space when this is escaped correctly. + * e.g. 'A - B - C' converted to 'A_--_B_--_C' unfortunately renders in the SVG result 'A - B_- C'. + * So just don't mix them and you'll be ok. Like do 'A-B-C'. */ -export function makeBadge( - title: string, - imageTarget: string, - linkTarget: string -) { - return markdownImageWithLink(title, encode(imageTarget), encode(linkTarget)); +export function encodeParam(value: string, spaceToUnderscore = true) { + value = _encodeSeparators(value, spaceToUnderscore); + + const encoded = encodeURIComponent(value); + + return _decodeAngleBrackets(encoded); } /** @@ -108,11 +112,11 @@ function formatTitle(label: string, message: string) { * So you can pass in more readable values. */ function dashShieldPath(message: string, color: string, label?: string) { - message = encode(message); + message = encodeParam(message); let pieces = [message, color]; if (label) { - label = encode(label); + label = encodeParam(label); pieces.unshift(label); } From 507fcb2224232ee35bd2ef842abfa560aa1bb5f5 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:38:19 +0200 Subject: [PATCH 13/48] test: Update encode calls --- tests/unit/core/badges.spec.ts | 45 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 288c1768..2794f84d 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,23 +1,10 @@ -/* -Template: - -describe("#foo", () => { - it("", () => { - expect( - foo( - "" - ) - ).toBe(""); - }); -}); -*/ - import { - encode, + encodeParam, genericBadge, + markdownImage, markdownImageWithLink, - markdownLink, + markdownLink } from "@/core/badges"; describe("#markdownLink", () => { @@ -63,41 +50,39 @@ describe("#markdownImageWithLink", () => { }); }); -describe("#encode", () => { +describe("#encodeParam", () => { it("convert a space to an underscore", () => { - expect(encode("Foo Bar")).toBe("Foo_Bar"); + expect(encodeParam("Foo Bar")).toBe("Foo_Bar"); }); it("converts a single dash to two", () => { - expect(encode("Foo-Bar")).toBe("Foo--Bar"); + expect(encodeParam("Foo-Bar")).toBe("Foo--Bar"); }); it("converts a single underscore to two", () => { - expect(encode("Foo_Bar")).toBe("Foo__Bar"); + expect(encodeParam("Foo_Bar")).toBe("Foo__Bar"); }); it("converts a mix of space, underscore and a dash correctly", () => { - expect(encode("Foo Bar_Baz-Buzz")).toBe("Foo_Bar__Baz--Buzz"); + expect(encodeParam("Foo Bar_Baz-Buzz")).toBe("Foo_Bar__Baz--Buzz"); }); // These could appear when putting a URL as a value in the path, so need to be escaped. - it("encodes special characters likely correctly", () => { - expect(encode("&")).toBe("%26"); - - expect(encode("/")).toBe("%2F"); - - expect(encode("?")).toBe("%3F"); + it("encodes special characters correctly", () => { + expect(encodeParam("&")).toBe("%26"); + expect(encodeParam("/")).toBe("%2F"); + expect(encodeParam("?")).toBe("%3F"); }); // Note that '>' and '<' are valid on shields.io and should not be encoded. it("encodes a string correctly without converting angle brackets", () => { - expect(encode(">=3")).toBe(">%3D3"); + expect(encodeParam(">=3")).toBe(">%3D3"); - expect(encode("<2")).toBe("<2"); + expect(encodeParam("<2")).toBe("<2"); }); }); -// These cases are based on common choices and defaults in the UI, to save on testing the frontend directly. +// These cases are based on the common choices and defaults in the UI, which approximates testing the frontend. describe("#genericBadge", () => { it("displays a badge given a message and a color", () => { expect(genericBadge("", "Bar", "green")).toBe( From 79313bf796a650d60d5df78b4224cccf4a731989 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:43:48 +0200 Subject: [PATCH 14/48] test: Add test case --- src/core/badges.ts | 5 +++++ tests/unit/core/badges.spec.ts | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 381be6b6..09f7b4dc 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -20,6 +20,11 @@ export function markdownImage( } // TODO: Add pre-label as social badges have. +/** + * Create a markdown image tag with external link. + * + * This performs no encoding - the inputs should be encoded already to be a URL without spaces and to be a valid URL for shields.io API. + */ export function markdownImageWithLink( altText: string, imageTarget: string, diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 2794f84d..15ee981c 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -47,6 +47,21 @@ describe("#markdownImageWithLink", () => { "My foo" ) ).toBe('[![Alt text](foo.png "My foo")](https://example.com)'); + + expect(markdownImageWithLink("My title", "/example.png", "https://example.com")).toBe( + "[![My title](/example.png)](https://example.com)" + ); + }) + it("Does not encode special characters", () => { + expect( + markdownImageWithLink( + "My title", + "/example.png", + "https://example.com?foo=bar&fizz_buzz=baz&x>=2" + ) + ).toBe( + "[![My title](/example.png)](https://example.com?foo=bar&fizz_buzz=baz&x>=2)" + ); }); }); @@ -77,7 +92,6 @@ describe("#encodeParam", () => { // Note that '>' and '<' are valid on shields.io and should not be encoded. it("encodes a string correctly without converting angle brackets", () => { expect(encodeParam(">=3")).toBe(">%3D3"); - expect(encodeParam("<2")).toBe("<2"); }); }); From 8dcf0e793617bb1d711d797e65e38cd508b73264 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:46:23 +0200 Subject: [PATCH 15/48] refactor: Make functions private --- src/core/badges.ts | 12 ++++++------ tests/unit/core/badges.spec.ts | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 09f7b4dc..0e1c78b1 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -116,7 +116,7 @@ function formatTitle(label: string, message: string) { * This appropriately escapes label and message for you, based on notes on the shields.io website. * So you can pass in more readable values. */ -function dashShieldPath(message: string, color: string, label?: string) { +function _dashShieldPath(message: string, color: string, label?: string) { message = encodeParam(message); let pieces = [message, color]; @@ -160,15 +160,15 @@ interface GenericBadge { // TODO: Move business logic for specific badges to separate module from general markdown and URL handling. /** Image URL for param-based static badge. */ -function staticParamsUrl({ label, message, color, styleParams }: GenericBadge) { +function _staticParamsUrl({ label, message, color, styleParams }: GenericBadge) { const params = { label, message, color, ...styleParams }; return buildUrl(SHIELDS_STATIC, params); } /** Image URL for dash-based static badge. */ -function staticDashUrl({ label, message, color, styleParams }: GenericBadge) { - const imgPath = dashShieldPath(message, color, label), +function _staticDashUrl({ label, message, color, styleParams }: GenericBadge) { + const imgPath = _dashShieldPath(message, color, label), imgUrl = `${SHIELDS_BADGE}/${imgPath}`; return buildUrl(imgUrl, styleParams); @@ -204,8 +204,8 @@ export function genericBadge( badgeFields = { label, message, color, styleParams }; const fullImgUrl = onlyQueryParams - ? staticParamsUrl(badgeFields) - : staticDashUrl(badgeFields); + ? _staticParamsUrl(badgeFields) + : _staticDashUrl(badgeFields); return markdownImageWithLink(title, fullImgUrl, target); } diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 15ee981c..97e5a559 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -2,8 +2,9 @@ import { encodeParam, genericBadge, - markdownImage, - markdownImageWithLink, + + + markdownImage, markdownImageWithLink, markdownLink } from "@/core/badges"; From 3c8418b91a8f8a0e5c888a4214382270fbb757c9 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Mon, 14 Dec 2020 08:51:53 +0200 Subject: [PATCH 16/48] style: Format --- jest.config.js | 2 +- src/core/badges.ts | 7 ++++++- tests/unit/core/badges.spec.ts | 16 +++++++--------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/jest.config.js b/jest.config.js index 92fbd7a9..58969d35 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ module.exports = { preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel", - testPathIgnorePatterns: ["/dist/"] + testPathIgnorePatterns: ["/dist/"], }; diff --git a/src/core/badges.ts b/src/core/badges.ts index 0e1c78b1..953a00f9 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -160,7 +160,12 @@ interface GenericBadge { // TODO: Move business logic for specific badges to separate module from general markdown and URL handling. /** Image URL for param-based static badge. */ -function _staticParamsUrl({ label, message, color, styleParams }: GenericBadge) { +function _staticParamsUrl({ + label, + message, + color, + styleParams, +}: GenericBadge) { const params = { label, message, color, ...styleParams }; return buildUrl(SHIELDS_STATIC, params); diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 97e5a559..82b706a8 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,11 +1,9 @@ import { encodeParam, genericBadge, - - - - markdownImage, markdownImageWithLink, - markdownLink + markdownImage, + markdownImageWithLink, + markdownLink, } from "@/core/badges"; describe("#markdownLink", () => { @@ -49,10 +47,10 @@ describe("#markdownImageWithLink", () => { ) ).toBe('[![Alt text](foo.png "My foo")](https://example.com)'); - expect(markdownImageWithLink("My title", "/example.png", "https://example.com")).toBe( - "[![My title](/example.png)](https://example.com)" - ); - }) + expect( + markdownImageWithLink("My title", "/example.png", "https://example.com") + ).toBe("[![My title](/example.png)](https://example.com)"); + }); it("Does not encode special characters", () => { expect( markdownImageWithLink( From fdb926a82fab2e95a34b7ac75b472f1f6b475bb8 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:03:16 +0200 Subject: [PATCH 17/48] docs: Update development.md --- docs/development.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development.md b/docs/development.md index 32f19b3b..53a6d6f2 100644 --- a/docs/development.md +++ b/docs/development.md @@ -192,13 +192,13 @@ On upgrading packages. Check outdated plugins: ```sh -$ npx vue outdatded +$ npx vue outdated ``` Outdated packages: ```sh -$ yarn oudated +$ yarn outdated ``` Upgrade: From b1fea79d444b655128f7672c2d900de09be62a5f Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:06:31 +0200 Subject: [PATCH 18/48] build: Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0a4db4a0..f752f616 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ default: install h help: - @egrep '^\S|^$$' Makefile + @egrep '^[a-z#]' Makefile .PHONY: hooks From 7d3b46677773f5cfd7cf52454f07c7e36e4b5e32 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:08:01 +0200 Subject: [PATCH 19/48] docs: Update badges.ts --- src/core/badges.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 953a00f9..cab91dfb 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -23,7 +23,8 @@ export function markdownImage( /** * Create a markdown image tag with external link. * - * This performs no encoding - the inputs should be encoded already to be a URL without spaces and to be a valid URL for shields.io API. + * This performs no encoding - the inputs should be encoded already to be a URL without spaces and + * to be a valid URL for shields.io API. */ export function markdownImageWithLink( altText: string, @@ -42,7 +43,8 @@ export function markdownImageWithLink( /** * Replace dashes, underscores and spaces to match shields.io API format. * - * Spaces are converted to underscores - so if you pass the result to an encode functions they won't become '%20'. + * Spaces are converted to underscores - so if you pass the result to an encode functions they won't + * become '%20'. */ export function _encodeSeparators(value: string, spaceToUnderscore: boolean) { value = value.replace(/-/g, "--").replace(/_/g, "__"); @@ -84,10 +86,11 @@ export function encodeParam(value: string, spaceToUnderscore = true) { /** * Serialize a URL from query params. * - * Note the URL must have a protocal or it will be considered invalid. Any empty values get - * dropped to keep the result short. + * Note the URL must have a protocal or it will be considered invalid. Any empty values get dropped + * to keep the result short. * - * The URL types's API performs encoding, so at the end we must reverse this so the result works for badges. + * The URL types's API performs encoding, so at the end we must reverse this so the result works for + * badges. */ export function buildUrl( urlStr: string, @@ -158,7 +161,8 @@ interface GenericBadge { styleParams: { [key: string]: string }; } -// TODO: Move business logic for specific badges to separate module from general markdown and URL handling. +// TODO: Move business logic for specific badges to separate module from general markdown and URL +// handling. /** Image URL for param-based static badge. */ function _staticParamsUrl({ label, From d875b86e00d09c934dbf38dd48c1055f168cf8dd Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:15:02 +0200 Subject: [PATCH 20/48] test: Add test --- src/core/badges.ts | 3 --- tests/unit/core/badges.spec.ts | 24 +++++++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index cab91dfb..c78b7568 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -42,9 +42,6 @@ export function markdownImageWithLink( /** * Replace dashes, underscores and spaces to match shields.io API format. - * - * Spaces are converted to underscores - so if you pass the result to an encode functions they won't - * become '%20'. */ export function _encodeSeparators(value: string, spaceToUnderscore: boolean) { value = value.replace(/-/g, "--").replace(/_/g, "__"); diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 82b706a8..3742ad72 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -4,6 +4,7 @@ import { markdownImage, markdownImageWithLink, markdownLink, + _encodeSeparators } from "@/core/badges"; describe("#markdownLink", () => { @@ -64,8 +65,29 @@ describe("#markdownImageWithLink", () => { }); }); +describe("#_encodeSeparators", () => { + it("converts a space to an underscore", () => { + expect(_encodeSeparators("Foo Bar", true)).toBe("Foo_Bar"); + }); + it("can ignore transforming a space", () => { + expect(_encodeSeparators("Foo Bar", false)).toBe("Foo Bar"); + }); + + it("converts a single dash to two", () => { + expect(_encodeSeparators("Foo-Bar", true)).toBe("Foo--Bar"); + }); + + it("converts a single underscore to two", () => { + expect(_encodeSeparators("Foo_Bar", true)).toBe("Foo__Bar"); + }); + + it("converts a mix of space, underscore and a dash correctly", () => { + expect(_encodeSeparators("Foo Bar_Baz-Buzz", true)).toBe("Foo_Bar__Baz--Buzz"); + }); +}); + describe("#encodeParam", () => { - it("convert a space to an underscore", () => { + it("converts a space to an underscore", () => { expect(encodeParam("Foo Bar")).toBe("Foo_Bar"); }); From a2e9a9f0e7ff311500ddccf1e9f92edcb5935290 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:15:57 +0200 Subject: [PATCH 21/48] refactor: Rename to private function --- src/core/badges.ts | 6 +++--- tests/unit/core/badges.spec.ts | 27 +++++++++++++++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index c78b7568..c9a2e4ce 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -72,7 +72,7 @@ export function _decodeAngleBrackets(value: string) { * e.g. 'A - B - C' converted to 'A_--_B_--_C' unfortunately renders in the SVG result 'A - B_- C'. * So just don't mix them and you'll be ok. Like do 'A-B-C'. */ -export function encodeParam(value: string, spaceToUnderscore = true) { +export function _encodeParam(value: string, spaceToUnderscore = true) { value = _encodeSeparators(value, spaceToUnderscore); const encoded = encodeURIComponent(value); @@ -117,11 +117,11 @@ function formatTitle(label: string, message: string) { * So you can pass in more readable values. */ function _dashShieldPath(message: string, color: string, label?: string) { - message = encodeParam(message); + message = _encodeParam(message); let pieces = [message, color]; if (label) { - label = encodeParam(label); + label = _encodeParam(label); pieces.unshift(label); } diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 3742ad72..a0e75831 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,9 +1,12 @@ import { - encodeParam, genericBadge, markdownImage, markdownImageWithLink, - markdownLink, + markdownLink, _encodeParam, + + + + _encodeSeparators } from "@/core/badges"; @@ -86,34 +89,34 @@ describe("#_encodeSeparators", () => { }); }); -describe("#encodeParam", () => { +describe("#_encodeParam", () => { it("converts a space to an underscore", () => { - expect(encodeParam("Foo Bar")).toBe("Foo_Bar"); + expect(_encodeParam("Foo Bar")).toBe("Foo_Bar"); }); it("converts a single dash to two", () => { - expect(encodeParam("Foo-Bar")).toBe("Foo--Bar"); + expect(_encodeParam("Foo-Bar")).toBe("Foo--Bar"); }); it("converts a single underscore to two", () => { - expect(encodeParam("Foo_Bar")).toBe("Foo__Bar"); + expect(_encodeParam("Foo_Bar")).toBe("Foo__Bar"); }); it("converts a mix of space, underscore and a dash correctly", () => { - expect(encodeParam("Foo Bar_Baz-Buzz")).toBe("Foo_Bar__Baz--Buzz"); + expect(_encodeParam("Foo Bar_Baz-Buzz")).toBe("Foo_Bar__Baz--Buzz"); }); // These could appear when putting a URL as a value in the path, so need to be escaped. it("encodes special characters correctly", () => { - expect(encodeParam("&")).toBe("%26"); - expect(encodeParam("/")).toBe("%2F"); - expect(encodeParam("?")).toBe("%3F"); + expect(_encodeParam("&")).toBe("%26"); + expect(_encodeParam("/")).toBe("%2F"); + expect(_encodeParam("?")).toBe("%3F"); }); // Note that '>' and '<' are valid on shields.io and should not be encoded. it("encodes a string correctly without converting angle brackets", () => { - expect(encodeParam(">=3")).toBe(">%3D3"); - expect(encodeParam("<2")).toBe("<2"); + expect(_encodeParam(">=3")).toBe(">%3D3"); + expect(_encodeParam("<2")).toBe("<2"); }); }); From ada08a862bbce2060b2e18acac75248664904e5c Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:16:35 +0200 Subject: [PATCH 22/48] style: Update badges.spec.ts --- tests/unit/core/badges.spec.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index a0e75831..5a4fc1fe 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -2,11 +2,8 @@ import { genericBadge, markdownImage, markdownImageWithLink, - markdownLink, _encodeParam, - - - - + markdownLink, + _encodeParam, _encodeSeparators } from "@/core/badges"; From b7a1a7b7ee5960e05efb7828b967479574b00e45 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:23:22 +0200 Subject: [PATCH 23/48] test: Add tests for _decodeAngleBrackets --- src/core/badges.ts | 9 +++++---- tests/unit/core/badges.spec.ts | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index c9a2e4ce..2b72d886 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -54,17 +54,18 @@ export function _encodeSeparators(value: string, spaceToUnderscore: boolean) { } /** - * Turn URL-encoded '<' and '>' back into characters. + * Turn URL-encoded '<' and '>' symbols back into readable characters. + * + * These are allowed in shields.io URLs so should not be encoded. */ export function _decodeAngleBrackets(value: string) { - return value.replace(/%3E/g, ">").replace(/%3C/g, "<"); + return value.replace(/%3E/g, ">") + .replace(/%3C/g, "<"); } /** * Encode a value to be safe as a param in a URL. * - * See badges.spec.ts for cases. - * * Prepare a value for dash-based shields.io API based on notes on that site. * * Note the shields.io API itself does funny things if you do use more than one diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 5a4fc1fe..40521669 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -3,7 +3,9 @@ import { markdownImage, markdownImageWithLink, markdownLink, - _encodeParam, + + + _decodeAngleBrackets, _encodeParam, _encodeSeparators } from "@/core/badges"; @@ -86,6 +88,16 @@ describe("#_encodeSeparators", () => { }); }); +describe("#_decodeAngleBrackets", () => { + it("decodes a left angle bracket", () => { + expect(_decodeAngleBrackets("%3E%3D1")).toBe(">%3D1"); + }); + + it("decodes a right angle bracket", () => { + expect(_decodeAngleBrackets("foo%3C1")).toBe("foo<1"); + }); +}) + describe("#_encodeParam", () => { it("converts a space to an underscore", () => { expect(_encodeParam("Foo Bar")).toBe("Foo_Bar"); @@ -110,7 +122,6 @@ describe("#_encodeParam", () => { expect(_encodeParam("?")).toBe("%3F"); }); - // Note that '>' and '<' are valid on shields.io and should not be encoded. it("encodes a string correctly without converting angle brackets", () => { expect(_encodeParam(">=3")).toBe(">%3D3"); expect(_encodeParam("<2")).toBe("<2"); From e6ddc441d42e7bcb56577210b8f1cc34422c64ed Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:23:51 +0200 Subject: [PATCH 24/48] style: Update imports --- tests/unit/core/badges.spec.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 40521669..e5ba0239 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -3,9 +3,8 @@ import { markdownImage, markdownImageWithLink, markdownLink, - - - _decodeAngleBrackets, _encodeParam, + _decodeAngleBrackets, + _encodeParam, _encodeSeparators } from "@/core/badges"; From 7e3924ae8c195b34f8aa389de985ec550c1549d2 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:34:18 +0200 Subject: [PATCH 25/48] test: Add test for buildUrl --- src/core/badges.ts | 9 +++----- tests/unit/core/badges.spec.ts | 42 ++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 2b72d886..91a59125 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -82,13 +82,10 @@ export function _encodeParam(value: string, spaceToUnderscore = true) { } /** - * Serialize a URL from query params. + * Serialize a URL using query params. * - * Note the URL must have a protocal or it will be considered invalid. Any empty values get dropped - * to keep the result short. - * - * The URL types's API performs encoding, so at the end we must reverse this so the result works for - * badges. + * The URL must have a protocol or it will be considered invalid. We drop any empty values to keep + * the result short. */ export function buildUrl( urlStr: string, diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index e5ba0239..65478b97 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,4 +1,5 @@ import { + buildUrl, genericBadge, markdownImage, markdownImageWithLink, @@ -70,7 +71,7 @@ describe("#_encodeSeparators", () => { it("converts a space to an underscore", () => { expect(_encodeSeparators("Foo Bar", true)).toBe("Foo_Bar"); }); - it("can ignore transforming a space", () => { + it("will ignore transforming a space", () => { expect(_encodeSeparators("Foo Bar", false)).toBe("Foo Bar"); }); @@ -127,7 +128,44 @@ describe("#_encodeParam", () => { }); }); -// These cases are based on the common choices and defaults in the UI, which approximates testing the frontend. + +describe("#buildUrl", () => { + it("handles empty query params", () => { + expect( + buildUrl( + "http://example.com", {} + ) + ).toBe("http://example.com/"); + }); + + it("ignores a param which is null", () => { + expect( + buildUrl( + "http://example.com", { "foo": "" } + ) + ).toBe("http://example.com/"); + }); + + it("adds a single query param", () => { + expect( + buildUrl( + "http://example.com", { "foo": "bar" } + ) + ).toBe("http://example.com/?foo=bar"); + }); + + + it("adds two query params", () => { + expect( + buildUrl( + "http://example.com", { "foo": "bar", "bar": 'bazz' } + ) + ).toBe("http://example.com/?foo=bar&bar=bazz"); + }); +}); + +// These cases are based on the common choices and defaults in the UI, to simulate testing the +// frontend. describe("#genericBadge", () => { it("displays a badge given a message and a color", () => { expect(genericBadge("", "Bar", "green")).toBe( From bcfecf6b280413fc6b92a5f8ee1c9ef600d5f952 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:37:36 +0200 Subject: [PATCH 26/48] test: Add test for _formatTitle --- src/core/badges.ts | 4 ++-- tests/unit/core/badges.spec.ts | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 91a59125..ea552351 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -102,7 +102,7 @@ export function buildUrl( return decodeURI(url.href); } -function formatTitle(label: string, message: string) { +export function _formatTitle(label: string, message: string) { return label ? [label, message].join(" - ") : message; } @@ -202,7 +202,7 @@ export function genericBadge( logoColor = "", onlyQueryParams = false ) { - const title = formatTitle(label, message); + const title = _formatTitle(label, message); const styleParams = logoParams(isLarge, logo, logoColor), badgeFields = { label, message, color, styleParams }; diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 65478b97..aa138ebe 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,12 +1,13 @@ import { buildUrl, + genericBadge, markdownImage, markdownImageWithLink, markdownLink, _decodeAngleBrackets, _encodeParam, - _encodeSeparators + _encodeSeparators, _formatTitle } from "@/core/badges"; describe("#markdownLink", () => { @@ -164,6 +165,24 @@ describe("#buildUrl", () => { }); }); +describe("#_formatTitle", () => { + it("formats a message alone", () => { + expect( + _formatTitle( + "", "foo" + ) + ).toBe("foo"); + }); + + it("formats a label and message together", () => { + expect( + _formatTitle( + "bar", "foo" + ) + ).toBe("bar - foo"); + }); +}); + // These cases are based on the common choices and defaults in the UI, to simulate testing the // frontend. describe("#genericBadge", () => { From f850e706eb12f2673ee4a4fdecb4cb86d19b799b Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:46:48 +0200 Subject: [PATCH 27/48] test: Add tests for _dashShieldPath --- src/core/badges.ts | 13 +++--- tests/unit/core/badges.spec.ts | 79 ++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index ea552351..a1968664 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -59,8 +59,7 @@ export function _encodeSeparators(value: string, spaceToUnderscore: boolean) { * These are allowed in shields.io URLs so should not be encoded. */ export function _decodeAngleBrackets(value: string) { - return value.replace(/%3E/g, ">") - .replace(/%3C/g, "<"); + return value.replace(/%3E/g, ">").replace(/%3C/g, "<"); } /** @@ -107,14 +106,18 @@ export function _formatTitle(label: string, message: string) { } /** - * Prepare path for shields.io dash-based API. + * Create a URL path for the shields.io dash-based API. * * The API requires MESSAGE-COLOR at the least and also accepts LABEL-MESSAGE-COLOR. * * This appropriately escapes label and message for you, based on notes on the shields.io website. * So you can pass in more readable values. */ -function _dashShieldPath(message: string, color: string, label?: string) { +export function _dashShieldPath( + message: string, + color: string, + label?: string +) { message = _encodeParam(message); let pieces = [message, color]; @@ -170,7 +173,7 @@ function _staticParamsUrl({ return buildUrl(SHIELDS_STATIC, params); } -/** Image URL for dash-based static badge. */ +/** Image URL for a dash-based static badge. */ function _staticDashUrl({ label, message, color, styleParams }: GenericBadge) { const imgPath = _dashShieldPath(message, color, label), imgUrl = `${SHIELDS_BADGE}/${imgPath}`; diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index aa138ebe..bd76fcda 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,13 +1,14 @@ import { buildUrl, - genericBadge, markdownImage, markdownImageWithLink, markdownLink, + _dashShieldPath, _decodeAngleBrackets, _encodeParam, - _encodeSeparators, _formatTitle + _encodeSeparators, + _formatTitle, } from "@/core/badges"; describe("#markdownLink", () => { @@ -85,7 +86,9 @@ describe("#_encodeSeparators", () => { }); it("converts a mix of space, underscore and a dash correctly", () => { - expect(_encodeSeparators("Foo Bar_Baz-Buzz", true)).toBe("Foo_Bar__Baz--Buzz"); + expect(_encodeSeparators("Foo Bar_Baz-Buzz", true)).toBe( + "Foo_Bar__Baz--Buzz" + ); }); }); @@ -97,7 +100,7 @@ describe("#_decodeAngleBrackets", () => { it("decodes a right angle bracket", () => { expect(_decodeAngleBrackets("foo%3C1")).toBe("foo<1"); }); -}) +}); describe("#_encodeParam", () => { it("converts a space to an underscore", () => { @@ -129,57 +132,61 @@ describe("#_encodeParam", () => { }); }); - describe("#buildUrl", () => { it("handles empty query params", () => { - expect( - buildUrl( - "http://example.com", {} - ) - ).toBe("http://example.com/"); + expect(buildUrl("http://example.com", {})).toBe("http://example.com/"); }); it("ignores a param which is null", () => { - expect( - buildUrl( - "http://example.com", { "foo": "" } - ) - ).toBe("http://example.com/"); + expect(buildUrl("http://example.com", { foo: "" })).toBe( + "http://example.com/" + ); }); it("adds a single query param", () => { - expect( - buildUrl( - "http://example.com", { "foo": "bar" } - ) - ).toBe("http://example.com/?foo=bar"); + expect(buildUrl("http://example.com", { foo: "bar" })).toBe( + "http://example.com/?foo=bar" + ); }); - it("adds two query params", () => { - expect( - buildUrl( - "http://example.com", { "foo": "bar", "bar": 'bazz' } - ) - ).toBe("http://example.com/?foo=bar&bar=bazz"); + expect(buildUrl("http://example.com", { foo: "bar", bar: "bazz" })).toBe( + "http://example.com/?foo=bar&bar=bazz" + ); }); }); describe("#_formatTitle", () => { it("formats a message alone", () => { - expect( - _formatTitle( - "", "foo" - ) - ).toBe("foo"); + expect(_formatTitle("", "foo")).toBe("foo"); }); it("formats a label and message together", () => { - expect( - _formatTitle( - "bar", "foo" - ) - ).toBe("bar - foo"); + expect(_formatTitle("bar", "foo")).toBe("bar - foo"); + }); +}); + +describe("#_dashShieldPath", () => { + it("combines 2 fields", () => { + expect(_dashShieldPath("Foo", "green")).toBe("Foo-green"); + }); + + it("combines 2 fields", () => { + expect(_dashShieldPath("Foo", "green", "Bar")).toBe("Bar-Foo-green"); + }); + + it("combines 2 fields and applies encoding", () => { + expect(_dashShieldPath("Foo Bar", "green", "Baz")).toBe( + "Baz-Foo_Bar-green" + ); + + expect(_dashShieldPath("Foo", "green", "Baz-Buzz")).toBe( + "Baz--Buzz-Foo-green" + ); + + expect(_dashShieldPath(">=1.0.0", "green", "Foo")).toBe( + "Foo->%3D1.0.0-green" + ); }); }); From 9850d703cb02285a3a734c51548098f844f8cd98 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:54:45 +0200 Subject: [PATCH 28/48] test: Add tests for logoParams --- src/core/badges.ts | 4 +--- tests/unit/core/badges.spec.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index a1968664..f7ddb57b 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -130,9 +130,7 @@ export function _dashShieldPath( } /** - * Generate parametes to style a badge. - * - * Return as key-value pairs with appropriate size (large or standard) and optional logo. + * Generate parameters for stying a badge. */ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { let params: { [key: string]: string } = {}; diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index bd76fcda..509ed588 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,6 +1,7 @@ import { buildUrl, genericBadge, + logoParams, markdownImage, markdownImageWithLink, markdownLink, @@ -190,6 +191,39 @@ describe("#_dashShieldPath", () => { }); }); +describe("#logoParams", () => { + it("returns null params", () => { + expect(logoParams(false)).toStrictEqual({}); + }); + + it("returns a large badge", () => { + expect(logoParams(true)).toStrictEqual({ style: "for-the-badge" }); + }); + + it("returns a logo name", () => { + expect(logoParams(false, "foo")).toStrictEqual({ logo: "foo" }); + }); + + it("returns a logo name and logo color", () => { + expect(logoParams(false, "foo", "white")).toStrictEqual({ + logo: "foo", + logoColor: "white", + }); + }); + + it("returns a logo name and logo color for a large badge", () => { + expect(logoParams(true, "foo", "white")).toStrictEqual({ + style: "for-the-badge", + logo: "foo", + logoColor: "white", + }); + }); + + it("ignores a logo color with no logo name", () => { + expect(logoParams(false, "", "white")).toStrictEqual({}); + }); +}); + // These cases are based on the common choices and defaults in the UI, to simulate testing the // frontend. describe("#genericBadge", () => { From 2ce03433dd5d9ad0f51e9c6f96d964280dc8facb Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 16:58:05 +0200 Subject: [PATCH 29/48] refactor: Create badges.d.ts --- src/core/badges.d.ts | 6 ++++++ src/core/badges.ts | 8 +------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 src/core/badges.d.ts diff --git a/src/core/badges.d.ts b/src/core/badges.d.ts new file mode 100644 index 00000000..a40f3aaf --- /dev/null +++ b/src/core/badges.d.ts @@ -0,0 +1,6 @@ +export interface GenericBadge { + label: string; + message: string; + color: string; + styleParams: { [key: string]: string; }; +} diff --git a/src/core/badges.ts b/src/core/badges.ts index f7ddb57b..e1c0ec9e 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -1,6 +1,7 @@ /** * Handle rendering of each badge and all badges. */ +import { GenericBadge } from "./badges.d"; import { SHIELDS_BADGE, SHIELDS_STATIC } from "./constants"; // TODO combine link/target functions in a module. @@ -150,13 +151,6 @@ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { return params; } -interface GenericBadge { - label: string; - message: string; - color: string; - styleParams: { [key: string]: string }; -} - // TODO: Move business logic for specific badges to separate module from general markdown and URL // handling. /** Image URL for param-based static badge. */ From b82c0ba32da90788ec8de538136d36c83cae7598 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 17:14:11 +0200 Subject: [PATCH 30/48] refactor: Update badges.d.ts --- src/core/badges.d.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/badges.d.ts b/src/core/badges.d.ts index a40f3aaf..171cb3ff 100644 --- a/src/core/badges.d.ts +++ b/src/core/badges.d.ts @@ -1,6 +1,8 @@ -export interface GenericBadge { +type strMap = { [key: string]: string }; + +export type GenericBadge = { label: string; message: string; color: string; - styleParams: { [key: string]: string; }; -} + styleParams: strMap; +}; From 79c8a87e5c75d2b7259f756a11e7604381c1d949 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 17:31:10 +0200 Subject: [PATCH 31/48] refactor: Use type --- src/core/badges.d.ts | 4 ++-- src/core/badges.ts | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/badges.d.ts b/src/core/badges.d.ts index 171cb3ff..37f48d41 100644 --- a/src/core/badges.d.ts +++ b/src/core/badges.d.ts @@ -1,8 +1,8 @@ -type strMap = { [key: string]: string }; +type StrMap = { [key: string]: string }; export type GenericBadge = { label: string; message: string; color: string; - styleParams: strMap; + styleParams: StrMap; }; diff --git a/src/core/badges.ts b/src/core/badges.ts index e1c0ec9e..c40f9c91 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -1,7 +1,7 @@ /** * Handle rendering of each badge and all badges. */ -import { GenericBadge } from "./badges.d"; +import { GenericBadge, StrMap } from "./badges.d"; import { SHIELDS_BADGE, SHIELDS_STATIC } from "./constants"; // TODO combine link/target functions in a module. @@ -87,10 +87,7 @@ export function _encodeParam(value: string, spaceToUnderscore = true) { * The URL must have a protocol or it will be considered invalid. We drop any empty values to keep * the result short. */ -export function buildUrl( - urlStr: string, - params: { [key: string]: string } -): string { +export function buildUrl(urlStr: string, params: StrMap): string { let url = new URL(urlStr); for (const [key, value] of Object.entries(params)) { @@ -134,7 +131,7 @@ export function _dashShieldPath( * Generate parameters for stying a badge. */ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { - let params: { [key: string]: string } = {}; + let params: StrMap = {}; if (isLarge) { params.style = "for-the-badge"; From 5156e31eb14fa850a91d0ac24fc21b9aee128e38 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 17:38:35 +0200 Subject: [PATCH 32/48] test: Add tests for _staticParamsUrl --- src/core/badges.ts | 2 +- tests/unit/core/badges.spec.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index c40f9c91..2f9ce7bb 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -151,7 +151,7 @@ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { // TODO: Move business logic for specific badges to separate module from general markdown and URL // handling. /** Image URL for param-based static badge. */ -function _staticParamsUrl({ +export function _staticParamsUrl({ label, message, color, diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 509ed588..f9e95714 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -10,6 +10,7 @@ import { _encodeParam, _encodeSeparators, _formatTitle, + _staticParamsUrl, } from "@/core/badges"; describe("#markdownLink", () => { @@ -224,6 +225,34 @@ describe("#logoParams", () => { }); }); +describe("#_staticParamsUrl", () => { + it("returns a valid params URL with empty style params", () => { + expect( + _staticParamsUrl({ + label: "Foo", + message: "Bar", + color: "green", + styleParams: {}, + }) + ).toBe( + "https://img.shields.io/static/v1?label=Foo&message=Bar&color=green" + ); + }); + + it("returns a valid params URL with style params", () => { + expect( + _staticParamsUrl({ + label: "Foo", + message: "Bar", + color: "green", + styleParams: { fizz: "buzz" }, + }) + ).toBe( + "https://img.shields.io/static/v1?label=Foo&message=Bar&color=green&fizz=buzz" + ); + }); +}); + // These cases are based on the common choices and defaults in the UI, to simulate testing the // frontend. describe("#genericBadge", () => { From d002b392f57513c8fd61b57df2e4e07bc200c88a Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 17:42:29 +0200 Subject: [PATCH 33/48] Update badges.ts --- src/core/badges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/badges.ts b/src/core/badges.ts index 2f9ce7bb..6dd7ccdd 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -163,7 +163,7 @@ export function _staticParamsUrl({ } /** Image URL for a dash-based static badge. */ -function _staticDashUrl({ label, message, color, styleParams }: GenericBadge) { +export function _staticDashUrl({ label, message, color, styleParams }: GenericBadge) { const imgPath = _dashShieldPath(message, color, label), imgUrl = `${SHIELDS_BADGE}/${imgPath}`; From 02a30896e054dc35fab1029445d92917fcaaec95 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:01:47 +0200 Subject: [PATCH 34/48] refactor: Use GenericBadge and StrMap as types in badges.ts --- src/core/badges.d.ts | 3 +- src/core/badges.ts | 37 +++++++++++------------ tests/unit/core/badges.spec.ts | 54 +++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/core/badges.d.ts b/src/core/badges.d.ts index 37f48d41..67e44872 100644 --- a/src/core/badges.d.ts +++ b/src/core/badges.d.ts @@ -1,8 +1,7 @@ type StrMap = { [key: string]: string }; export type GenericBadge = { - label: string; + label?: string; message: string; color: string; - styleParams: StrMap; }; diff --git a/src/core/badges.ts b/src/core/badges.ts index 6dd7ccdd..54eb927a 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -111,14 +111,11 @@ export function _formatTitle(label: string, message: string) { * This appropriately escapes label and message for you, based on notes on the shields.io website. * So you can pass in more readable values. */ -export function _dashShieldPath( - message: string, - color: string, - label?: string -) { - message = _encodeParam(message); +export function _dashShieldPath(badge: GenericBadge) { + const message = _encodeParam(badge.message); + let label = badge.label; - let pieces = [message, color]; + let pieces = [message, badge.color]; if (label) { label = _encodeParam(label); pieces.unshift(label); @@ -151,20 +148,20 @@ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { // TODO: Move business logic for specific badges to separate module from general markdown and URL // handling. /** Image URL for param-based static badge. */ -export function _staticParamsUrl({ - label, - message, - color, - styleParams, -}: GenericBadge) { - const params = { label, message, color, ...styleParams }; +export function _staticParamsUrl(badge: GenericBadge, styleParams: StrMap) { + const params = { + label: badge.label!, + message: badge.message, + color: badge.color, + ...styleParams, + }; return buildUrl(SHIELDS_STATIC, params); } /** Image URL for a dash-based static badge. */ -export function _staticDashUrl({ label, message, color, styleParams }: GenericBadge) { - const imgPath = _dashShieldPath(message, color, label), +export function _staticDashUrl(badge: GenericBadge, styleParams: StrMap) { + const imgPath = _dashShieldPath(badge), imgUrl = `${SHIELDS_BADGE}/${imgPath}`; return buildUrl(imgUrl, styleParams); @@ -196,12 +193,12 @@ export function genericBadge( ) { const title = _formatTitle(label, message); - const styleParams = logoParams(isLarge, logo, logoColor), - badgeFields = { label, message, color, styleParams }; + const badgeFields = { label, message, color }, + styleParams = logoParams(isLarge, logo, logoColor); const fullImgUrl = onlyQueryParams - ? _staticParamsUrl(badgeFields) - : _staticDashUrl(badgeFields); + ? _staticParamsUrl(badgeFields, styleParams) + : _staticDashUrl(badgeFields, styleParams); return markdownImageWithLink(title, fullImgUrl, target); } diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index f9e95714..b77b7eb9 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -170,25 +170,29 @@ describe("#_formatTitle", () => { describe("#_dashShieldPath", () => { it("combines 2 fields", () => { - expect(_dashShieldPath("Foo", "green")).toBe("Foo-green"); + expect(_dashShieldPath({ message: "Foo", color: "green" })).toBe( + "Foo-green" + ); }); it("combines 2 fields", () => { - expect(_dashShieldPath("Foo", "green", "Bar")).toBe("Bar-Foo-green"); + expect( + _dashShieldPath({ message: "Foo", color: "green", label: "Bar" }) + ).toBe("Bar-Foo-green"); }); it("combines 2 fields and applies encoding", () => { - expect(_dashShieldPath("Foo Bar", "green", "Baz")).toBe( - "Baz-Foo_Bar-green" - ); + expect( + _dashShieldPath({ message: "Foo Bar", color: "green", label: "Baz" }) + ).toBe("Baz-Foo_Bar-green"); - expect(_dashShieldPath("Foo", "green", "Baz-Buzz")).toBe( - "Baz--Buzz-Foo-green" - ); + expect( + _dashShieldPath({ message: "Foo", color: "green", label: "Baz-Buzz" }) + ).toBe("Baz--Buzz-Foo-green"); - expect(_dashShieldPath(">=1.0.0", "green", "Foo")).toBe( - "Foo->%3D1.0.0-green" - ); + expect( + _dashShieldPath({ label: "Foo", message: ">=1.0.0", color: "green" }) + ).toBe("Foo->%3D1.0.0-green"); }); }); @@ -228,12 +232,14 @@ describe("#logoParams", () => { describe("#_staticParamsUrl", () => { it("returns a valid params URL with empty style params", () => { expect( - _staticParamsUrl({ - label: "Foo", - message: "Bar", - color: "green", - styleParams: {}, - }) + _staticParamsUrl( + { + label: "Foo", + message: "Bar", + color: "green", + }, + {} + ) ).toBe( "https://img.shields.io/static/v1?label=Foo&message=Bar&color=green" ); @@ -241,12 +247,14 @@ describe("#_staticParamsUrl", () => { it("returns a valid params URL with style params", () => { expect( - _staticParamsUrl({ - label: "Foo", - message: "Bar", - color: "green", - styleParams: { fizz: "buzz" }, - }) + _staticParamsUrl( + { + label: "Foo", + message: "Bar", + color: "green", + }, + { fizz: "buzz" } + ) ).toBe( "https://img.shields.io/static/v1?label=Foo&message=Bar&color=green&fizz=buzz" ); From c3db3245ba642b8288df76b0da3d993182949a1d Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:09:15 +0200 Subject: [PATCH 35/48] test: Add tests for _staticDashUrl --- tests/unit/core/badges.spec.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index b77b7eb9..24af2832 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -10,6 +10,7 @@ import { _encodeParam, _encodeSeparators, _formatTitle, + _staticDashUrl, _staticParamsUrl, } from "@/core/badges"; @@ -261,6 +262,34 @@ describe("#_staticParamsUrl", () => { }); }); +describe("#_staticDashUrl", () => { + it("returns a valid dash URL with empty style params", () => { + expect( + _staticDashUrl( + { + label: "Foo", + message: "Bar", + color: "green", + }, + {} + ) + ).toBe("https://img.shields.io/badge/Foo-Bar-green"); + }); + + it("returns a valid dash URL with style params", () => { + expect( + _staticDashUrl( + { + label: "Foo", + message: "Bar", + color: "green", + }, + { fizz: "buzz" } + ) + ).toBe("https://img.shields.io/badge/Foo-Bar-green?fizz=buzz"); + }); +}); + // These cases are based on the common choices and defaults in the UI, to simulate testing the // frontend. describe("#genericBadge", () => { From 1d291894a1cec6a4d20e90d7b691bec9258d923c Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:12:54 +0200 Subject: [PATCH 36/48] refactor: Use constants --- src/core/Repo.ts | 2 +- src/core/badges.ts | 4 ++-- src/core/constants.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/Repo.ts b/src/core/Repo.ts index 396c410c..eca96a64 100644 --- a/src/core/Repo.ts +++ b/src/core/Repo.ts @@ -146,7 +146,7 @@ export class Repo { } private _ghSocialShield(type: string) { - return `${SHIELDS_GH}/${type}/${this.username}/${this.repoName}${STYLES.SOCIAL}`; + return `${SHIELDS_GH}/${type}/${this.username}/${this.repoName}?style=${STYLES.SOCIAL}`; } /* Stars or forks counter */ diff --git a/src/core/badges.ts b/src/core/badges.ts index 54eb927a..752c8640 100644 --- a/src/core/badges.ts +++ b/src/core/badges.ts @@ -2,7 +2,7 @@ * Handle rendering of each badge and all badges. */ import { GenericBadge, StrMap } from "./badges.d"; -import { SHIELDS_BADGE, SHIELDS_STATIC } from "./constants"; +import { SHIELDS_BADGE, SHIELDS_STATIC, STYLES } from "./constants"; // TODO combine link/target functions in a module. export function markdownLink(altText: string, linkTarget: string) { @@ -131,7 +131,7 @@ export function logoParams(isLarge = false, logo?: string, logoColor?: string) { let params: StrMap = {}; if (isLarge) { - params.style = "for-the-badge"; + params.style = STYLES.FOR_THE_BADGE; } if (logo) { diff --git a/src/core/constants.ts b/src/core/constants.ts index 9e0d5f59..7576e0d6 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -17,8 +17,8 @@ export const GITHUB_DOMAIN = "https://github.com", // TODO handle as map to make it easy to add multiple params. export const STYLES = { - FOR_THE_BADGE: "?style=for-the-badge", - SOCIAL: "?style=social", + FOR_THE_BADGE: "for-the-badge", + SOCIAL: "social", }; // Excluding trailing slash makes URL joins more natural. From fc487ae2171713fbdfd31bb0de7a8145b7a9dddd Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:20:42 +0200 Subject: [PATCH 37/48] test: Add package test --- src/core/constants.ts | 3 +-- tests/unit/core/packages.spec.ts | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/unit/core/packages.spec.ts diff --git a/src/core/constants.ts b/src/core/constants.ts index 7576e0d6..ad96a9e0 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -11,7 +11,7 @@ export const GITHUB_DOMAIN = "https://github.com", GITHUB_IO = "github.io", DEFAULT_COLOR = "blue", GREEN = "green", - // From 'Use this template' or 'Merge' button. + // From 'Use this template' or 'Merge' button on GitHub. GITHUB_GREEN = "2ea44f", DEFAULT_BRANCH = "master"; @@ -21,7 +21,6 @@ export const STYLES = { SOCIAL: "social", }; -// Excluding trailing slash makes URL joins more natural. export enum REGISTRY { Python = "https://pypi.org/project", Node = "https://www.npmjs.com/package", diff --git a/tests/unit/core/packages.spec.ts b/tests/unit/core/packages.spec.ts new file mode 100644 index 00000000..6031fcb5 --- /dev/null +++ b/tests/unit/core/packages.spec.ts @@ -0,0 +1,10 @@ +import { REGISTRY } from "@/core/constants"; +import { dependency } from "@/core/packages"; + +describe("#dependency", () => { + it("returns a standard size static badge for a Node package", () => { + expect(dependency("react", REGISTRY.Node)).toBe( + "[![dependency - react](https://img.shields.io/badge/dependency-react-blue)](https://www.npmjs.com/package/react)" + ); + }); +}); From a0f4e5119c08ee7d99a8b1e4615348ed4a2dec2e Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:24:11 +0200 Subject: [PATCH 38/48] docs: Add comments --- src/core/packages.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/packages.ts b/src/core/packages.ts index b4dc5a7f..f5996e20 100644 --- a/src/core/packages.ts +++ b/src/core/packages.ts @@ -10,6 +10,9 @@ import { } from "./badges"; import { DEFAULT_COLOR, REGISTRY, SHIELDS_PACKAGE } from "./constants"; +/** + * Static dependency badge. + */ export function dependency(name: string, registry: REGISTRY) { const isLarge = false; const url = `${registry}/${name}`; @@ -18,9 +21,11 @@ export function dependency(name: string, registry: REGISTRY) { } /** - * Supports NPM packages. + * Dynamic NPM package badge. + * + * The badge will dynamically display given package's locked version number, using your repo's package.json file. * - * Shields.io supports Pipenv lock files but not requirements.txt file, it seems. And not Gemfile either. + * Shields.io does Pipenv lock files, but not requirements.txt file, it seems. And not Gemfile either. */ export function nodeVersionBadge( username: string, From fa8cf87bd975c31215f17e032115d21b75039f38 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:25:31 +0200 Subject: [PATCH 39/48] fix: Make package name required --- src/core/packages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/packages.ts b/src/core/packages.ts index f5996e20..7939e5c5 100644 --- a/src/core/packages.ts +++ b/src/core/packages.ts @@ -30,7 +30,7 @@ export function dependency(name: string, registry: REGISTRY) { export function nodeVersionBadge( username: string, repoName: string, - pkgName?: string, + pkgName: string, logo?: string, logoColor?: string ) { From 2fcf139610c08c1992dce273a1331eb324ce7703 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:38:20 +0200 Subject: [PATCH 40/48] docs: Update docstrings --- src/core/packages.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/packages.ts b/src/core/packages.ts index 7939e5c5..8acf57b6 100644 --- a/src/core/packages.ts +++ b/src/core/packages.ts @@ -21,11 +21,16 @@ export function dependency(name: string, registry: REGISTRY) { } /** - * Dynamic NPM package badge. + * Dynamic Node package badge. * - * The badge will dynamically display given package's locked version number, using your repo's package.json file. + * The badge will dynamically display given package's locked version number, using your repo's + * package.json file. * - * Shields.io does Pipenv lock files, but not requirements.txt file, it seems. And not Gemfile either. + * Note - the badge URL needs something added to work for dev dependencies. I'm happy to not support + * that now. + * + * Shields.io does Pipenv lock files, but not requirements.txt file, it seems. And not Gemfile + * either. */ export function nodeVersionBadge( username: string, From 747f7475b8517c0113218f45b276c0a376a6f6bf Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:38:39 +0200 Subject: [PATCH 41/48] test: Add test for nodeVersionBadge --- tests/unit/core/packages.spec.ts | 39 +++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/unit/core/packages.spec.ts b/tests/unit/core/packages.spec.ts index 6031fcb5..6f146a67 100644 --- a/tests/unit/core/packages.spec.ts +++ b/tests/unit/core/packages.spec.ts @@ -1,5 +1,5 @@ import { REGISTRY } from "@/core/constants"; -import { dependency } from "@/core/packages"; +import { dependency, nodeVersionBadge } from "@/core/packages"; describe("#dependency", () => { it("returns a standard size static badge for a Node package", () => { @@ -8,3 +8,40 @@ describe("#dependency", () => { ); }); }); + +describe("#nodeVersionBadge", () => { + const target = "https://www.npmjs.com/package/vue"; + + it("returns a dynamic Node badge", () => { + const imgUrl = + "https://img.shields.io/github/package-json/dependency-version/MichaelCurrin/badge-generator/vue"; + + expect(nodeVersionBadge("MichaelCurrin", "badge-generator", "vue")).toBe( + `[![Package - vue](${imgUrl})](${target})` + ); + }); + + it("returns a dynamic Node badge with a logo and no logo color", () => { + const imgUrl = + "https://img.shields.io/github/package-json/dependency-version/MichaelCurrin/badge-generator/vue?logo=vue.js"; + + expect( + nodeVersionBadge("MichaelCurrin", "badge-generator", "vue", "vue.js") + ).toBe(`[![Package - vue](${imgUrl})](${target})`); + }); + + it("returns a dynamic Node badge with a logo and logo color", () => { + const imgUrl = + "https://img.shields.io/github/package-json/dependency-version/MichaelCurrin/badge-generator/vue?logo=vue.js&logoColor=white"; + + expect( + nodeVersionBadge( + "MichaelCurrin", + "badge-generator", + "vue", + "vue.js", + "white" + ) + ).toBe(`[![Package - vue](${imgUrl})](${target})`); + }); +}); From 23215088887aa64317f7285d35a5607d49696f3a Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:46:43 +0200 Subject: [PATCH 42/48] refactor: Move tests to new file --- tests/unit/core/badges.spec.ts | 70 ------------------------------ tests/unit/genericBadges.spec.ts | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 70 deletions(-) create mode 100644 tests/unit/genericBadges.spec.ts diff --git a/tests/unit/core/badges.spec.ts b/tests/unit/core/badges.spec.ts index 24af2832..4f0483ca 100644 --- a/tests/unit/core/badges.spec.ts +++ b/tests/unit/core/badges.spec.ts @@ -1,6 +1,5 @@ import { buildUrl, - genericBadge, logoParams, markdownImage, markdownImageWithLink, @@ -289,72 +288,3 @@ describe("#_staticDashUrl", () => { ).toBe("https://img.shields.io/badge/Foo-Bar-green?fizz=buzz"); }); }); - -// These cases are based on the common choices and defaults in the UI, to simulate testing the -// frontend. -describe("#genericBadge", () => { - it("displays a badge given a message and a color", () => { - expect(genericBadge("", "Bar", "green")).toBe( - "![Bar](https://img.shields.io/badge/Bar-green)" - ); - }); - - it("displays a badge given label, message and a color", () => { - expect(genericBadge("Foo", "Bar", "green")).toBe( - "![Foo - Bar](https://img.shields.io/badge/Foo-Bar-green)" - ); - }); - - it("displays a badge point to external link", () => { - const target = "https://example.com"; - - expect(genericBadge("", "Bar", "green", false, target)).toBe( - "[![Bar](https://img.shields.io/badge/Bar-green)](https://example.com)" - ); - - expect(genericBadge("", "Bar", "green", false, target, "", "", true)).toBe( - "[![Bar](https://img.shields.io/static/v1?message=Bar&color=green)](https://example.com)" - ); - }); - - it("displays a large badge", () => { - const displayLarge = true; - - expect(genericBadge("", "Bar", "green", displayLarge)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?style=for-the-badge)" - ); - - expect( - genericBadge("", "Bar", "green", displayLarge, "", "", "", true) - ).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&style=for-the-badge)" - ); - }); - - it("displays a logo", () => { - const logo = "github"; - - expect(genericBadge("", "Bar", "green", false, "", logo)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?logo=github)" - ); - - expect(genericBadge("", "Bar", "green", false, "", logo, "", true)).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github)" - ); - }); - - it("displays a logo with a custom logo color", () => { - const logo = "github", - logoColor = "yellow"; - - expect(genericBadge("", "Bar", "green", false, "", logo, logoColor)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?logo=github&logoColor=yellow)" - ); - - expect( - genericBadge("", "Bar", "green", false, "", logo, logoColor, true) - ).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github&logoColor=yellow)" - ); - }); -}); diff --git a/tests/unit/genericBadges.spec.ts b/tests/unit/genericBadges.spec.ts new file mode 100644 index 00000000..9a1fbf07 --- /dev/null +++ b/tests/unit/genericBadges.spec.ts @@ -0,0 +1,73 @@ +/** + * Generic badges test module. + * + * Tes that the UI defaults and common choices associated with the Generic view are working. + */ +import { genericBadge } from "@/core/badges"; + +describe("#genericBadge", () => { + it("displays a badge given a message and a color", () => { + expect(genericBadge("", "Bar", "green")).toBe( + "![Bar](https://img.shields.io/badge/Bar-green)" + ); + }); + + it("displays a badge given label, message and a color", () => { + expect(genericBadge("Foo", "Bar", "green")).toBe( + "![Foo - Bar](https://img.shields.io/badge/Foo-Bar-green)" + ); + }); + + it("displays a badge point to external link", () => { + const target = "https://example.com"; + + expect(genericBadge("", "Bar", "green", false, target)).toBe( + "[![Bar](https://img.shields.io/badge/Bar-green)](https://example.com)" + ); + + expect(genericBadge("", "Bar", "green", false, target, "", "", true)).toBe( + "[![Bar](https://img.shields.io/static/v1?message=Bar&color=green)](https://example.com)" + ); + }); + + it("displays a large badge", () => { + const displayLarge = true; + + expect(genericBadge("", "Bar", "green", displayLarge)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?style=for-the-badge)" + ); + + expect( + genericBadge("", "Bar", "green", displayLarge, "", "", "", true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&style=for-the-badge)" + ); + }); + + it("displays a logo", () => { + const logo = "github"; + + expect(genericBadge("", "Bar", "green", false, "", logo)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github)" + ); + + expect(genericBadge("", "Bar", "green", false, "", logo, "", true)).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github)" + ); + }); + + it("displays a logo with a custom logo color", () => { + const logo = "github", + logoColor = "yellow"; + + expect(genericBadge("", "Bar", "green", false, "", logo, logoColor)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github&logoColor=yellow)" + ); + + expect( + genericBadge("", "Bar", "green", false, "", logo, logoColor, true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github&logoColor=yellow)" + ); + }); +}); From 7bd22fb0fea72fb527dfd22d3a2c9860607a64ed Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 18:53:43 +0200 Subject: [PATCH 43/48] test: Add groupings --- tests/unit/genericBadges.spec.ts | 114 ++++++++++++++++--------------- 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/tests/unit/genericBadges.spec.ts b/tests/unit/genericBadges.spec.ts index 9a1fbf07..a0041e47 100644 --- a/tests/unit/genericBadges.spec.ts +++ b/tests/unit/genericBadges.spec.ts @@ -1,73 +1,79 @@ -/** - * Generic badges test module. - * - * Tes that the UI defaults and common choices associated with the Generic view are working. - */ import { genericBadge } from "@/core/badges"; +/** +* Test that the UI defaults and common choices associated with the Generic view are working. + */ describe("#genericBadge", () => { - it("displays a badge given a message and a color", () => { - expect(genericBadge("", "Bar", "green")).toBe( - "![Bar](https://img.shields.io/badge/Bar-green)" - ); - }); + describe("Basic", () => { + it("displays a badge given a message and a color", () => { + expect(genericBadge("", "Bar", "green")).toBe( + "![Bar](https://img.shields.io/badge/Bar-green)" + ); + }); - it("displays a badge given label, message and a color", () => { - expect(genericBadge("Foo", "Bar", "green")).toBe( - "![Foo - Bar](https://img.shields.io/badge/Foo-Bar-green)" - ); - }); + it("displays a badge given label, message and a color", () => { + expect(genericBadge("Foo", "Bar", "green")).toBe( + "![Foo - Bar](https://img.shields.io/badge/Foo-Bar-green)" + ); + }); - it("displays a badge point to external link", () => { - const target = "https://example.com"; + it("displays a badge pointing to external link", () => { + const target = "https://example.com"; - expect(genericBadge("", "Bar", "green", false, target)).toBe( - "[![Bar](https://img.shields.io/badge/Bar-green)](https://example.com)" - ); + expect(genericBadge("", "Bar", "green", false, target)).toBe( + "[![Bar](https://img.shields.io/badge/Bar-green)](https://example.com)" + ); - expect(genericBadge("", "Bar", "green", false, target, "", "", true)).toBe( - "[![Bar](https://img.shields.io/static/v1?message=Bar&color=green)](https://example.com)" - ); - }); + expect( + genericBadge("", "Bar", "green", false, target, "", "", true) + ).toBe( + "[![Bar](https://img.shields.io/static/v1?message=Bar&color=green)](https://example.com)" + ); + }); - it("displays a large badge", () => { - const displayLarge = true; + describe("Size", () => { + it("displays a large badge", () => { + const displayLarge = true; - expect(genericBadge("", "Bar", "green", displayLarge)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?style=for-the-badge)" - ); + expect(genericBadge("", "Bar", "green", displayLarge)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?style=for-the-badge)" + ); - expect( - genericBadge("", "Bar", "green", displayLarge, "", "", "", true) - ).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&style=for-the-badge)" - ); + expect( + genericBadge("", "Bar", "green", displayLarge, "", "", "", true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&style=for-the-badge)" + ); + }); + }); }); - it("displays a logo", () => { - const logo = "github"; + describe("Logo", () => { + it("displays a logo", () => { + const logo = "github"; - expect(genericBadge("", "Bar", "green", false, "", logo)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?logo=github)" - ); + expect(genericBadge("", "Bar", "green", false, "", logo)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github)" + ); - expect(genericBadge("", "Bar", "green", false, "", logo, "", true)).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github)" - ); - }); + expect(genericBadge("", "Bar", "green", false, "", logo, "", true)).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github)" + ); + }); - it("displays a logo with a custom logo color", () => { - const logo = "github", - logoColor = "yellow"; + it("displays a logo with a custom logo color", () => { + const logo = "github", + logoColor = "yellow"; - expect(genericBadge("", "Bar", "green", false, "", logo, logoColor)).toBe( - "![Bar](https://img.shields.io/badge/Bar-green?logo=github&logoColor=yellow)" - ); + expect(genericBadge("", "Bar", "green", false, "", logo, logoColor)).toBe( + "![Bar](https://img.shields.io/badge/Bar-green?logo=github&logoColor=yellow)" + ); - expect( - genericBadge("", "Bar", "green", false, "", logo, logoColor, true) - ).toBe( - "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github&logoColor=yellow)" - ); + expect( + genericBadge("", "Bar", "green", false, "", logo, logoColor, true) + ).toBe( + "![Bar](https://img.shields.io/static/v1?message=Bar&color=green&logo=github&logoColor=yellow)" + ); + }); }); }); From 8adef4ef235caeb2d9452a5cff2d6ad1f1088f24 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:07:29 +0200 Subject: [PATCH 44/48] chore: Move and rename genericBadges.spec.ts to tests/unit/core/badgesGeneric.spec.ts --- .../unit/{genericBadges.spec.ts => core/badgesGeneric.spec.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/unit/{genericBadges.spec.ts => core/badgesGeneric.spec.ts} (96%) diff --git a/tests/unit/genericBadges.spec.ts b/tests/unit/core/badgesGeneric.spec.ts similarity index 96% rename from tests/unit/genericBadges.spec.ts rename to tests/unit/core/badgesGeneric.spec.ts index a0041e47..649cac7c 100644 --- a/tests/unit/genericBadges.spec.ts +++ b/tests/unit/core/badgesGeneric.spec.ts @@ -1,7 +1,7 @@ import { genericBadge } from "@/core/badges"; /** -* Test that the UI defaults and common choices associated with the Generic view are working. + * Test that the UI defaults and common choices associated with the Generic view are working. */ describe("#genericBadge", () => { describe("Basic", () => { From dd662a9e13daff866f95aeeaffddf06d9fa1d70b Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:19:54 +0200 Subject: [PATCH 45/48] test: Create Repo.spec.ts --- tests/unit/core/Repo.spec.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/unit/core/Repo.spec.ts diff --git a/tests/unit/core/Repo.spec.ts b/tests/unit/core/Repo.spec.ts new file mode 100644 index 00000000..b15931a4 --- /dev/null +++ b/tests/unit/core/Repo.spec.ts @@ -0,0 +1,21 @@ +import { Repo } from "@/core/Repo"; + +describe("#Repo", () => { + describe("#licenseBadge", () => { + const repo = new Repo("MichaelCurrin", "badge-generator"); + + it("return a badge for a local license", () => { + expect(repo.licenseBadge("MIT", true)).toBe( + "[![License - MIT](https://img.shields.io/badge/License-MIT-blue)](#license)" + ); + }); + + it("return a badge for a remote license", () => { + const target = + "https://github.com/MichaelCurrin/badge-generator/blob/master/LICENSE", + expectedBadge = `[![License - MIT](https://img.shields.io/badge/License-MIT-blue)](${target})`; + + expect(repo.licenseBadge("MIT", false)).toBe(expectedBadge); + }); + }); +}); From 3667a8c295111afbf3554b9c51c9ec0be00bec5c Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:24:59 +0200 Subject: [PATCH 46/48] refactor: Split out _licenseTarget as a method --- src/core/Repo.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/Repo.ts b/src/core/Repo.ts index eca96a64..37adfaed 100644 --- a/src/core/Repo.ts +++ b/src/core/Repo.ts @@ -103,6 +103,15 @@ export class Repo { return markdownImageWithLink(title, imgUrl, target); } + _licenseTarget(localLicense: boolean) { + if (localLicense) { + return "#license"; + } + const repoUrl = this.ghURL(); + + return `${repoUrl}/blob/${DEFAULT_BRANCH}/LICENSE`; + } + licenseBadge(licenseType: string, localLicense = true) { if (!licenseType || !this._isValid()) { return ""; @@ -112,13 +121,7 @@ export class Repo { color = DEFAULT_COLOR, isLarge = false; - let target; - if (localLicense) { - target = "#license"; - } else { - const repoUrl = this.ghURL(); - target = `${repoUrl}/blob/${DEFAULT_BRANCH}/LICENSE`; - } + const target = this._licenseTarget(localLicense); return genericBadge(label, message, color, isLarge, target); } From 16da3cfd17c9a012204fd6be8a3aabb7f030be35 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:29:09 +0200 Subject: [PATCH 47/48] refactor: Move value to constants.ts --- src/core/Repo.ts | 4 ++-- src/core/constants.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/Repo.ts b/src/core/Repo.ts index 37adfaed..8933aec4 100644 --- a/src/core/Repo.ts +++ b/src/core/Repo.ts @@ -9,6 +9,7 @@ import { GITHUB_GREEN, GITHUB_IO, GREEN, + LICENSE_LABEL, SHIELDS_GH, // eslint-disable-next-line prettier/prettier STYLES @@ -116,11 +117,10 @@ export class Repo { if (!licenseType || !this._isValid()) { return ""; } - const label = "License", + const label = LICENSE_LABEL, message = licenseType, color = DEFAULT_COLOR, isLarge = false; - const target = this._licenseTarget(localLicense); return genericBadge(label, message, color, isLarge, target); diff --git a/src/core/constants.ts b/src/core/constants.ts index ad96a9e0..3809b0ab 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -15,6 +15,8 @@ export const GITHUB_DOMAIN = "https://github.com", GITHUB_GREEN = "2ea44f", DEFAULT_BRANCH = "master"; +export const LICENSE_LABEL = "License"; + // TODO handle as map to make it easy to add multiple params. export const STYLES = { FOR_THE_BADGE: "for-the-badge", From 17b42df89eaaa3127f3d24f95e6c30aa171535e2 Mon Sep 17 00:00:00 2001 From: Michael Currin <18750745+MichaelCurrin@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:32:33 +0200 Subject: [PATCH 48/48] refactor: Update licenseBadge and constants.ts --- src/core/Repo.ts | 15 ++++++++------- src/core/constants.ts | 6 +++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/core/Repo.ts b/src/core/Repo.ts index 8933aec4..f8560dff 100644 --- a/src/core/Repo.ts +++ b/src/core/Repo.ts @@ -9,7 +9,7 @@ import { GITHUB_GREEN, GITHUB_IO, GREEN, - LICENSE_LABEL, + LICENSE, SHIELDS_GH, // eslint-disable-next-line prettier/prettier STYLES @@ -117,13 +117,14 @@ export class Repo { if (!licenseType || !this._isValid()) { return ""; } - const label = LICENSE_LABEL, - message = licenseType, - color = DEFAULT_COLOR, - isLarge = false; - const target = this._licenseTarget(localLicense); - return genericBadge(label, message, color, isLarge, target); + return genericBadge( + LICENSE.LABEL, + licenseType, + LICENSE.COLOR, + LICENSE.IS_LARGE, + this._licenseTarget(localLicense) + ); } gh() { diff --git a/src/core/constants.ts b/src/core/constants.ts index 3809b0ab..530e9846 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -15,7 +15,11 @@ export const GITHUB_DOMAIN = "https://github.com", GITHUB_GREEN = "2ea44f", DEFAULT_BRANCH = "master"; -export const LICENSE_LABEL = "License"; +export const LICENSE = { + LABEL: "License", + COLOR: DEFAULT_COLOR, + IS_LARGE: false, +}; // TODO handle as map to make it easy to add multiple params. export const STYLES = {