Skip to content

Commit

Permalink
feat: support for other runtimes
Browse files Browse the repository at this point in the history
Merge pull request #54 from crayon-js/node-support
  • Loading branch information
Im-Beast authored Jun 29, 2024
2 parents 3cf73f5 + 1964778 commit da723d8
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 65 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deno.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
run: deno publish --dry-run

- name: Run benchmarks
# TODO: Cross-runtime benchmarks
run: deno task bench

- name: Check license headers
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Node.js

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
node: [21.x, 22.x]

steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: 'echo ''{ "type": "module" }'' > package.json'
- run: npx jsr add @beast/compat @std/assert
- run: npx --yes tsx --test **/*.test.ts
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
coverage
.vscode
.vscode
package.json
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,12 @@ Crayon's extensions are stored in [src/extensions](./src/extensions/)

## 🤝 Contributing

**Crayon** is open for any contributions. <br /> If you feel like you can enhance this project -
please open an issue and/or pull request. <br /> Code should be well document and easy to follow
what's going on.

Since the start of development on **Crayon 4.0** this project follows
[conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) spec.
<br /> If your pull request's code could introduce understandability trouble, please add comments to
it.
**Crayon** is open for any contributions.\
If you feel like you can enhance this project - please open an issue and/or pull request.\
Code should be well document and easy to follow what's going on.

**Crayon 4.x** follows [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).\
If your pull request's code could introduce understandability trouble, please add comments to it.

## 📝 Licensing

Expand Down
14 changes: 10 additions & 4 deletions deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"version": "4.0.0-alpha.2",

"imports": {
"@std/assert": "jsr:@std/assert@0.221.0"
// tests
"@std/assert": "jsr:@std/assert@0.221.0",
"@beast/compat": "jsr:@beast/compat@^0.2.5",
// bench
"@crayon/literal": "jsr:@crayon/literal@1.0.0-alpha.1"
},

"exports": {
Expand All @@ -22,10 +26,12 @@
"tasks": {
"test": "deno test --coverage --fail-fast=1 --allow-env",

"bench": "deno bench --allow-read --ignore=node --allow-env",
"bench": "deno bench --no-check --allow-read --allow-env",
"bench-nocolor": "NO_COLOR=1 deno task bench",
"bench-colorless": "COLORTERM='' TERM='' deno task bench",
"bench-colorless": "COLORTERM='' TERM='' deno task bench"
},

"gen-badges": "deno run -A build/gen_coverage_badge.ts && deno run -A build/gen_bench_badge.ts"
"compilerOptions": {
"lib": ["es2023", "dom"]
}
}
13 changes: 13 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion src/crayon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,17 @@ interface CrayonPrototypePrivate extends CrayonPrototype {
$recache: [Crayon, string, () => string][];
}

const NO_COLOR = "Deno" in globalThis
// @ts-expect-error Deno specific code
? Deno.noColor
: "process" in globalThis
// @ts-expect-error Node specific code
? process.env["NO_COLOR"]
: undefined;

export const prototype: CrayonPrototypePrivate = {
$recache: [],
$colorSupport: Deno.noColor ? ColorSupport.NoColor : ColorSupport.TrueColor,
$colorSupport: NO_COLOR && NO_COLOR !== "0" ? ColorSupport.NoColor : ColorSupport.TrueColor,

get colorSupport(): ColorSupport {
return prototype.$colorSupport;
Expand Down
73 changes: 34 additions & 39 deletions tests/base.test.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,64 @@
// Copyright 2024 Im-Beast. All rights reserved. MIT license.
import crayon, { buildCrayon, ColorSupport } from "../main.ts";
import { assertEquals } from "@std/assert";
import { env, test } from "@beast/compat";

Deno.test("Color support", async (t) => {
const otherCrayon = buildCrayon<typeof crayon>("", false);
import crayon, { buildCrayon, ColorSupport } from "../main.ts";

const NO_COLOR = !!(env("NO_COLOR") && env("NO_COLOR") !== "0");

test("Color support", async (t) => {
const otherCrayon = buildCrayon<typeof crayon>("", false);
// Crayon should default to TrueColor
await t.step("Default values", () => {
const DEFAULT_VALUE = Deno.noColor ? ColorSupport.NoColor : ColorSupport.TrueColor;
const DEFAULT_VALUE = NO_COLOR ? ColorSupport.NoColor : ColorSupport.TrueColor;
assertEquals(crayon.colorSupport, DEFAULT_VALUE);
assertEquals(otherCrayon.colorSupport, DEFAULT_VALUE);
});

// Changing color support should affect all built crayons
await t.step({
name: "Modifying color support",
ignore: Deno.noColor,
fn: () => {
crayon.colorSupport = ColorSupport.FourBit;
assertEquals(crayon.colorSupport, ColorSupport.FourBit);
assertEquals(otherCrayon.colorSupport, ColorSupport.FourBit);

crayon.colorSupport = ColorSupport.HighColor;
assertEquals(crayon.colorSupport, ColorSupport.HighColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.HighColor);

crayon.colorSupport = ColorSupport.TrueColor;
assertEquals(crayon.colorSupport, ColorSupport.TrueColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.TrueColor);
},
await t.step.ignoreIf(NO_COLOR)("Modifying color support", () => {
crayon.colorSupport = ColorSupport.FourBit;
assertEquals(crayon.colorSupport, ColorSupport.FourBit);
assertEquals(otherCrayon.colorSupport, ColorSupport.FourBit);

crayon.colorSupport = ColorSupport.HighColor;
assertEquals(crayon.colorSupport, ColorSupport.HighColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.HighColor);

crayon.colorSupport = ColorSupport.TrueColor;
assertEquals(crayon.colorSupport, ColorSupport.TrueColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.TrueColor);
});

// This test should only run when NO_COLOR is set
//
// If ColorSupport is set to NoColor all crayons should be the same
// and should not style the text in any way.
await t.step({
name: "NO_COLOR",
ignore: !Deno.noColor,
fn: () => {
assertEquals(crayon.colorSupport, ColorSupport.NoColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.NoColor);
await t.step.ignoreIf(!NO_COLOR)("NO_COLOR", () => {
assertEquals(crayon.colorSupport, ColorSupport.NoColor);
assertEquals(otherCrayon.colorSupport, ColorSupport.NoColor);

assertEquals(crayon("test"), "test");
assertEquals(otherCrayon("test"), "test");
assertEquals(crayon("test"), "test");
assertEquals(otherCrayon("test"), "test");

assertEquals(crayon.red("test"), "test");
assertEquals(otherCrayon.red("test"), "test");
assertEquals(crayon.red("test"), "test");
assertEquals(otherCrayon.red("test"), "test");

assertEquals(crayon.bgRed("test"), "test");
assertEquals(otherCrayon.bgRed("test"), "test");
assertEquals(crayon.bgRed("test"), "test");
assertEquals(otherCrayon.bgRed("test"), "test");

assertEquals(crayon.bold("test"), "test");
assertEquals(otherCrayon.bold("test"), "test");
assertEquals(crayon.bold("test"), "test");
assertEquals(otherCrayon.bold("test"), "test");

assertEquals(crayon.rgb(1, 1, 1), crayon);
assertEquals(otherCrayon.rgb(1, 1, 1), crayon);
assertEquals(crayon.rgb(1, 1, 1), crayon);
assertEquals(otherCrayon.rgb(1, 1, 1), crayon);

assertEquals(crayon.bold.red.bgBlue, crayon);
},
assertEquals(crayon.bold.red.bgBlue, crayon);
});
});

// These tests only test functionality for terminals that support at least 4 colors
Deno.test("Colored tests", { ignore: Deno.noColor }, async (t) => {
test.ignoreIf(NO_COLOR)("Colored tests", async (t) => {
await t.step("Styling", async (t) => {
await t.step("Basic", () => {
assertEquals(crayon.red("test"), "\x1b[31mtest\x1b[0m\x1b[0m");
Expand Down
14 changes: 7 additions & 7 deletions tests/bench.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2024 Im-Beast. All rights reserved. MIT license.
import crayon, { buildCrayon } from "../main.ts";
// TODO: Add literal benchmarks after literal extension has been published
import "@crayon/literal";

import chalk4 from "npm:chalk@^4";
import chalk5, { Chalk } from "npm:chalk@^5";
Expand Down Expand Up @@ -266,7 +266,7 @@ async function chainFunctions() {
// Kleur and Ansi-colors don't have color functions
}

async function _shortLiteral() {
async function shortLiteral() {
const group = "short-literal";

await Deno.bench({
Expand All @@ -288,7 +288,7 @@ async function _shortLiteral() {
// Cliffy, Kleur and Ansi-colors don't support literal templating
}

async function _longLiteral() {
async function longLiteral() {
const group = "long-literal";

await Deno.bench({
Expand All @@ -310,7 +310,7 @@ async function _longLiteral() {
// Cliffy, Kleur and Ansi-colors don't support literal templating
}

async function _longTextLiteral() {
async function longTextLiteral() {
const group = "long-text-literal";

await Deno.bench({
Expand Down Expand Up @@ -360,8 +360,8 @@ cachedShortChain();
cachedLongChain();
chainFunctions();

// shortLiteral();
// longLiteral();
// longTextLiteral();
shortLiteral();
longLiteral();
longTextLiteral();

generateInstance();
11 changes: 6 additions & 5 deletions tests/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
// Copyright 2024 Im-Beast. All rights reserved. MIT license.
import { assertEquals } from "@std/assert";
import { test } from "@beast/compat";

import { capitalize } from "../src/utils/capitalize.ts";
import { replace, replaceAll } from "../src/utils/strings.ts";

import { assertEquals } from "@std/assert";

Deno.test("capitalize()", () => {
test("capitalize()", () => {
assertEquals(capitalize("dog"), "Dog");
assertEquals(capitalize("d"), "D");
assertEquals(capitalize("big fluffy dog"), "Big fluffy dog");
});

Deno.test("replace()", () => {
test("replace()", () => {
assertEquals(replace("Hello world", " world", ""), "Hello");
assertEquals(replace("Cat likes pets", "Cat", "Dog"), "Dog likes pets");
assertEquals(replace("", "a", ""), "");
assertEquals(replace("a", "a", ""), "");
assertEquals(replace("dog dog dog dog dog", "dog", ""), " dog dog dog dog");
});

Deno.test("replaceAll()", () => {
test("replaceAll()", () => {
assertEquals(replaceAll("Hello worldy world", " world", ""), "Helloy");
assertEquals(replaceAll("Cat likes pets", "Cat", "Dog"), "Dog likes pets");
assertEquals(replaceAll("", "a", ""), "");
Expand Down

0 comments on commit da723d8

Please sign in to comment.