@tokens-studio/tokenscript-schemas 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +31 -8
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +30 -8
- package/dist/cli/index.js.map +1 -1
- package/package.json +2 -1
- package/src/bundler/bundle-schema.ts +146 -0
- package/src/bundler/index.ts +151 -0
- package/src/bundler/schema-dependency-resolver.ts +299 -0
- package/src/bundler/selective-bundler.test.ts +94 -0
- package/src/bundler/selective-bundler.ts +159 -0
- package/src/bundler/types.ts +93 -0
- package/src/bundler/utils.ts +74 -0
- package/src/cli/commands/bundle.integration.test.ts +153 -0
- package/src/cli/commands/bundle.test.ts +57 -0
- package/src/cli/commands/bundle.ts +237 -0
- package/src/cli/commands/list.ts +109 -0
- package/src/cli/config-schema.ts +36 -0
- package/src/cli/index.ts +50 -0
- package/src/cli/output-generator.ts +63 -0
- package/src/downloader/index.ts +248 -0
- package/src/downloader/types.ts +48 -0
- package/src/index.ts +8 -0
- package/src/schemas/functions/adjust_chroma/adjust-chroma.tokenscript +27 -0
- package/src/schemas/functions/adjust_chroma/schema.json +48 -0
- package/src/schemas/functions/adjust_chroma/unit.test.ts +76 -0
- package/src/schemas/functions/adjust_hue/adjust-hue.tokenscript +32 -0
- package/src/schemas/functions/adjust_hue/schema.json +48 -0
- package/src/schemas/functions/adjust_hue/unit.test.ts +68 -0
- package/src/schemas/functions/adjust_lightness/adjust-lightness.tokenscript +31 -0
- package/src/schemas/functions/adjust_lightness/schema.json +48 -0
- package/src/schemas/functions/adjust_lightness/unit.test.ts +88 -0
- package/src/schemas/functions/adjust_to_contrast/adjust-to-contrast.tokenscript +131 -0
- package/src/schemas/functions/adjust_to_contrast/schema.json +56 -0
- package/src/schemas/functions/adjust_to_contrast/unit.test.ts +81 -0
- package/src/schemas/functions/alpha_blend/alpha-blend.tokenscript +46 -0
- package/src/schemas/functions/alpha_blend/schema.json +28 -0
- package/src/schemas/functions/alpha_blend/unit.test.ts +135 -0
- package/src/schemas/functions/alpha_scale/alpha-scale.tokenscript +38 -0
- package/src/schemas/functions/alpha_scale/schema.json +24 -0
- package/src/schemas/functions/alpha_scale/unit.test.ts +50 -0
- package/src/schemas/functions/analogous/analogous.tokenscript +47 -0
- package/src/schemas/functions/analogous/schema.json +28 -0
- package/src/schemas/functions/analogous/unit.test.ts +64 -0
- package/src/schemas/functions/apca_contrast/apca-contrast.tokenscript +129 -0
- package/src/schemas/functions/apca_contrast/schema.json +24 -0
- package/src/schemas/functions/apca_contrast/unit.test.ts +259 -0
- package/src/schemas/functions/are_similar/are-similar.tokenscript +24 -0
- package/src/schemas/functions/are_similar/schema.json +57 -0
- package/src/schemas/functions/are_similar/unit.test.ts +57 -0
- package/src/schemas/functions/auto_text_color/auto-text-color.tokenscript +41 -0
- package/src/schemas/functions/auto_text_color/schema.json +53 -0
- package/src/schemas/functions/auto_text_color/unit.test.ts +122 -0
- package/src/schemas/functions/best_contrast/best-contrast.tokenscript +66 -0
- package/src/schemas/functions/best_contrast/schema.json +24 -0
- package/src/schemas/functions/best_contrast/unit.test.ts +64 -0
- package/src/schemas/functions/chroma/chroma.tokenscript +12 -0
- package/src/schemas/functions/chroma/schema.json +44 -0
- package/src/schemas/functions/chroma/unit.test.ts +86 -0
- package/src/schemas/functions/clamp_chroma/clamp-chroma.tokenscript +21 -0
- package/src/schemas/functions/clamp_chroma/schema.json +52 -0
- package/src/schemas/functions/clamp_chroma/unit.test.ts +60 -0
- package/src/schemas/functions/clamp_lightness/clamp-lightness.tokenscript +21 -0
- package/src/schemas/functions/clamp_lightness/schema.json +52 -0
- package/src/schemas/functions/clamp_lightness/unit.test.ts +76 -0
- package/src/schemas/functions/clamp_to_gamut/clamp-to-gamut.tokenscript +41 -0
- package/src/schemas/functions/clamp_to_gamut/schema.json +20 -0
- package/src/schemas/functions/clamp_to_gamut/unit.test.ts +167 -0
- package/src/schemas/functions/complement/complement.tokenscript +21 -0
- package/src/schemas/functions/complement/schema.json +20 -0
- package/src/schemas/functions/complement/unit.test.ts +81 -0
- package/src/schemas/functions/contrast_ratio/contrast-ratio.tokenscript +36 -0
- package/src/schemas/functions/contrast_ratio/schema.json +24 -0
- package/src/schemas/functions/contrast_ratio/unit.test.ts +91 -0
- package/src/schemas/functions/cooler/cooler.tokenscript +45 -0
- package/src/schemas/functions/cooler/schema.json +43 -0
- package/src/schemas/functions/cooler/unit.test.ts +69 -0
- package/src/schemas/functions/darken/darken.tokenscript +37 -0
- package/src/schemas/functions/darken/schema.json +24 -0
- package/src/schemas/functions/darken/unit.test.ts +105 -0
- package/src/schemas/functions/delta_e_2000/delta-e-2000.tokenscript +184 -0
- package/src/schemas/functions/delta_e_2000/schema.json +36 -0
- package/src/schemas/functions/delta_e_2000/unit.test.ts +243 -0
- package/src/schemas/functions/delta_e_76/delta-e-76.tokenscript +45 -0
- package/src/schemas/functions/delta_e_76/schema.json +24 -0
- package/src/schemas/functions/delta_e_76/unit.test.ts +123 -0
- package/src/schemas/functions/delta_e_ok/delta-e-ok.tokenscript +43 -0
- package/src/schemas/functions/delta_e_ok/schema.json +24 -0
- package/src/schemas/functions/delta_e_ok/unit.test.ts +235 -0
- package/src/schemas/functions/desaturate/desaturate.tokenscript +32 -0
- package/src/schemas/functions/desaturate/schema.json +24 -0
- package/src/schemas/functions/desaturate/unit.test.ts +54 -0
- package/src/schemas/functions/distributed/distributed.tokenscript +54 -0
- package/src/schemas/functions/distributed/schema.json +32 -0
- package/src/schemas/functions/distributed/unit.test.ts +58 -0
- package/src/schemas/functions/diverging/diverging.tokenscript +58 -0
- package/src/schemas/functions/diverging/schema.json +32 -0
- package/src/schemas/functions/diverging/unit.test.ts +70 -0
- package/src/schemas/functions/grayscale/grayscale.tokenscript +17 -0
- package/src/schemas/functions/grayscale/schema.json +20 -0
- package/src/schemas/functions/grayscale/unit.test.ts +79 -0
- package/src/schemas/functions/harmonize/harmonize.tokenscript +61 -0
- package/src/schemas/functions/harmonize/schema.json +52 -0
- package/src/schemas/functions/harmonize/unit.test.ts +56 -0
- package/src/schemas/functions/hue/hue.tokenscript +12 -0
- package/src/schemas/functions/hue/schema.json +44 -0
- package/src/schemas/functions/hue/unit.test.ts +75 -0
- package/src/schemas/functions/hue_difference/hue-difference.tokenscript +42 -0
- package/src/schemas/functions/hue_difference/schema.json +24 -0
- package/src/schemas/functions/hue_difference/unit.test.ts +125 -0
- package/src/schemas/functions/in_gamut/in-gamut.tokenscript +51 -0
- package/src/schemas/functions/in_gamut/schema.json +24 -0
- package/src/schemas/functions/in_gamut/unit.test.ts +178 -0
- package/src/schemas/functions/interpolate/interpolate.tokenscript +61 -0
- package/src/schemas/functions/interpolate/schema.json +52 -0
- package/src/schemas/functions/interpolate/unit.test.ts +96 -0
- package/src/schemas/functions/invert/invert-initializer.tokenscript +29 -0
- package/src/schemas/functions/invert/schema.json +20 -0
- package/src/schemas/functions/invert/unit.test.ts +216 -0
- package/src/schemas/functions/is_cool/is-cool.tokenscript +41 -0
- package/src/schemas/functions/is_cool/schema.json +20 -0
- package/src/schemas/functions/is_cool/unit.test.ts +189 -0
- package/src/schemas/functions/is_dark/is-dark.tokenscript +16 -0
- package/src/schemas/functions/is_dark/schema.json +24 -0
- package/src/schemas/functions/is_dark/unit.test.ts +87 -0
- package/src/schemas/functions/is_light/is-light.tokenscript +16 -0
- package/src/schemas/functions/is_light/schema.json +24 -0
- package/src/schemas/functions/is_light/unit.test.ts +86 -0
- package/src/schemas/functions/is_neutral/is-neutral.tokenscript +16 -0
- package/src/schemas/functions/is_neutral/schema.json +53 -0
- package/src/schemas/functions/is_neutral/unit.test.ts +85 -0
- package/src/schemas/functions/is_warm/is-warm.tokenscript +62 -0
- package/src/schemas/functions/is_warm/schema.json +20 -0
- package/src/schemas/functions/is_warm/unit.test.ts +161 -0
- package/src/schemas/functions/lighten/lighten.tokenscript +37 -0
- package/src/schemas/functions/lighten/schema.json +24 -0
- package/src/schemas/functions/lighten/unit.test.ts +109 -0
- package/src/schemas/functions/lightness/lightness.tokenscript +12 -0
- package/src/schemas/functions/lightness/schema.json +49 -0
- package/src/schemas/functions/lightness/unit.test.ts +99 -0
- package/src/schemas/functions/luminance/luminance.tokenscript +16 -0
- package/src/schemas/functions/luminance/schema.json +20 -0
- package/src/schemas/functions/luminance/unit.test.ts +105 -0
- package/src/schemas/functions/meets_contrast/meets-contrast.tokenscript +49 -0
- package/src/schemas/functions/meets_contrast/schema.json +28 -0
- package/src/schemas/functions/meets_contrast/unit.test.ts +170 -0
- package/src/schemas/functions/mix/mix.tokenscript +47 -0
- package/src/schemas/functions/mix/schema.json +28 -0
- package/src/schemas/functions/mix/unit.test.ts +95 -0
- package/src/schemas/functions/monochromatic/monochromatic.tokenscript +72 -0
- package/src/schemas/functions/monochromatic/schema.json +24 -0
- package/src/schemas/functions/monochromatic/unit.test.ts +91 -0
- package/src/schemas/functions/muted/muted.tokenscript +25 -0
- package/src/schemas/functions/muted/schema.json +48 -0
- package/src/schemas/functions/muted/unit.test.ts +100 -0
- package/src/schemas/functions/neutral_variant/neutral-variant.tokenscript +23 -0
- package/src/schemas/functions/neutral_variant/schema.json +48 -0
- package/src/schemas/functions/neutral_variant/unit.test.ts +102 -0
- package/src/schemas/functions/relative_luminance/relative-luminance.tokenscript +15 -0
- package/src/schemas/functions/relative_luminance/schema.json +49 -0
- package/src/schemas/functions/relative_luminance/unit.test.ts +104 -0
- package/src/schemas/functions/rotate_hue/rotate-hue.tokenscript +20 -0
- package/src/schemas/functions/rotate_hue/schema.json +24 -0
- package/src/schemas/functions/rotate_hue/unit.test.ts +86 -0
- package/src/schemas/functions/saturate/saturate.tokenscript +33 -0
- package/src/schemas/functions/saturate/schema.json +24 -0
- package/src/schemas/functions/saturate/unit.test.ts +59 -0
- package/src/schemas/functions/scale_chroma/scale-chroma.tokenscript +22 -0
- package/src/schemas/functions/scale_chroma/schema.json +48 -0
- package/src/schemas/functions/scale_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/scale_lightness/scale-lightness.tokenscript +23 -0
- package/src/schemas/functions/scale_lightness/schema.json +48 -0
- package/src/schemas/functions/scale_lightness/unit.test.ts +73 -0
- package/src/schemas/functions/sepia/schema.json +48 -0
- package/src/schemas/functions/sepia/sepia.tokenscript +54 -0
- package/src/schemas/functions/sepia/unit.test.ts +88 -0
- package/src/schemas/functions/set_chroma/schema.json +24 -0
- package/src/schemas/functions/set_chroma/set-chroma.tokenscript +18 -0
- package/src/schemas/functions/set_chroma/unit.test.ts +79 -0
- package/src/schemas/functions/set_hue/schema.json +24 -0
- package/src/schemas/functions/set_hue/set-hue.tokenscript +18 -0
- package/src/schemas/functions/set_hue/unit.test.ts +90 -0
- package/src/schemas/functions/set_lightness/schema.json +24 -0
- package/src/schemas/functions/set_lightness/set-lightness.tokenscript +18 -0
- package/src/schemas/functions/set_lightness/unit.test.ts +80 -0
- package/src/schemas/functions/shade_scale/schema.json +24 -0
- package/src/schemas/functions/shade_scale/shade-scale.tokenscript +61 -0
- package/src/schemas/functions/shade_scale/unit.test.ts +64 -0
- package/src/schemas/functions/split_complement/schema.json +24 -0
- package/src/schemas/functions/split_complement/split-complement.tokenscript +38 -0
- package/src/schemas/functions/split_complement/unit.test.ts +53 -0
- package/src/schemas/functions/steps/schema.json +28 -0
- package/src/schemas/functions/steps/steps.tokenscript +54 -0
- package/src/schemas/functions/steps/unit.test.ts +71 -0
- package/src/schemas/functions/tetradic/schema.json +20 -0
- package/src/schemas/functions/tetradic/tetradic.tokenscript +40 -0
- package/src/schemas/functions/tetradic/unit.test.ts +50 -0
- package/src/schemas/functions/tint_scale/schema.json +32 -0
- package/src/schemas/functions/tint_scale/tint-scale.tokenscript +71 -0
- package/src/schemas/functions/tint_scale/unit.test.ts +64 -0
- package/src/schemas/functions/to_gamut/schema.json +48 -0
- package/src/schemas/functions/to_gamut/to-gamut.tokenscript +96 -0
- package/src/schemas/functions/to_gamut/unit.test.ts +97 -0
- package/src/schemas/functions/triadic/schema.json +20 -0
- package/src/schemas/functions/triadic/triadic.tokenscript +33 -0
- package/src/schemas/functions/triadic/unit.test.ts +64 -0
- package/src/schemas/functions/vibrant/schema.json +48 -0
- package/src/schemas/functions/vibrant/unit.test.ts +55 -0
- package/src/schemas/functions/vibrant/vibrant.tokenscript +29 -0
- package/src/schemas/functions/warmer/schema.json +43 -0
- package/src/schemas/functions/warmer/unit.test.ts +69 -0
- package/src/schemas/functions/warmer/warmer.tokenscript +45 -0
- package/src/schemas/functions/wcag_level/schema.json +48 -0
- package/src/schemas/functions/wcag_level/unit.test.ts +75 -0
- package/src/schemas/functions/wcag_level/wcag-level.tokenscript +50 -0
- package/src/schemas/types/css-color/from-hsl-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-hwb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-lch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklab-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-oklch-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-p3-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-rgb-color.tokenscript +15 -0
- package/src/schemas/types/css-color/from-srgb-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-srgb-linear-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d50-color.tokenscript +16 -0
- package/src/schemas/types/css-color/from-xyz-d65-color.tokenscript +16 -0
- package/src/schemas/types/css-color/initializer.tokenscript +13 -0
- package/src/schemas/types/css-color/schema.json +148 -0
- package/src/schemas/types/css-color/unit.test.ts +402 -0
- package/src/schemas/types/hex-color/initializer.tokenscript +3 -0
- package/src/schemas/types/hex-color/schema.json +24 -0
- package/src/schemas/types/hex-color/unit.test.ts +123 -0
- package/src/schemas/types/hsl-color/from-srgb.tokenscript +87 -0
- package/src/schemas/types/hsl-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsl-color/schema.json +48 -0
- package/src/schemas/types/hsl-color/unit.test.ts +201 -0
- package/src/schemas/types/hsv-color/from-srgb.tokenscript +80 -0
- package/src/schemas/types/hsv-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hsv-color/schema.json +48 -0
- package/src/schemas/types/hsv-color/unit.test.ts +162 -0
- package/src/schemas/types/hwb-color/from-hsv.tokenscript +31 -0
- package/src/schemas/types/hwb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/hwb-color/schema.json +48 -0
- package/src/schemas/types/hwb-color/unit.test.ts +150 -0
- package/src/schemas/types/lab-color/from-xyz-d50.tokenscript +78 -0
- package/src/schemas/types/lab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lab-color/schema.json +48 -0
- package/src/schemas/types/lab-color/unit.test.ts +263 -0
- package/src/schemas/types/lch-color/from-lab.tokenscript +44 -0
- package/src/schemas/types/lch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/lch-color/schema.json +48 -0
- package/src/schemas/types/lch-color/unit.test.ts +173 -0
- package/src/schemas/types/okhsl-color/from-oklab.tokenscript +410 -0
- package/src/schemas/types/okhsl-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsl-color/schema.json +48 -0
- package/src/schemas/types/okhsl-color/unit.test.ts +514 -0
- package/src/schemas/types/okhsv-color/from-oklab.tokenscript +286 -0
- package/src/schemas/types/okhsv-color/initializer.tokenscript +24 -0
- package/src/schemas/types/okhsv-color/schema.json +48 -0
- package/src/schemas/types/okhsv-color/unit.test.ts +499 -0
- package/src/schemas/types/oklab-color/from-okhsl.tokenscript +195 -0
- package/src/schemas/types/oklab-color/from-okhsv.tokenscript +197 -0
- package/src/schemas/types/oklab-color/from-oklch.tokenscript +39 -0
- package/src/schemas/types/oklab-color/from-xyz-d65.tokenscript +43 -0
- package/src/schemas/types/oklab-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklab-color/schema.json +78 -0
- package/src/schemas/types/oklab-color/unit.test.ts +345 -0
- package/src/schemas/types/oklch-color/from-oklab.tokenscript +45 -0
- package/src/schemas/types/oklch-color/initializer.tokenscript +16 -0
- package/src/schemas/types/oklch-color/schema.json +48 -0
- package/src/schemas/types/oklch-color/unit.test.ts +267 -0
- package/src/schemas/types/p3-color/from-p3-linear.tokenscript +59 -0
- package/src/schemas/types/p3-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-color/schema.json +48 -0
- package/src/schemas/types/p3-color/unit.test.ts +119 -0
- package/src/schemas/types/p3-linear-color/from-xyz-d65.tokenscript +47 -0
- package/src/schemas/types/p3-linear-color/initializer.tokenscript +16 -0
- package/src/schemas/types/p3-linear-color/schema.json +48 -0
- package/src/schemas/types/p3-linear-color/unit.test.ts +82 -0
- package/src/schemas/types/rgb-color/from-hex.tokenscript +43 -0
- package/src/schemas/types/rgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/rgb-color/schema.json +55 -0
- package/src/schemas/types/rgb-color/to-hex.tokenscript +42 -0
- package/src/schemas/types/rgb-color/unit.test.ts +302 -0
- package/src/schemas/types/srgb-color/from-hsl.tokenscript +106 -0
- package/src/schemas/types/srgb-color/from-linear.tokenscript +58 -0
- package/src/schemas/types/srgb-color/from-rgb.tokenscript +20 -0
- package/src/schemas/types/srgb-color/initializer.tokenscript +16 -0
- package/src/schemas/types/srgb-color/schema.json +68 -0
- package/src/schemas/types/srgb-color/unit.test.ts +303 -0
- package/src/schemas/types/srgb-linear-color/from-srgb.tokenscript +55 -0
- package/src/schemas/types/srgb-linear-color/from-xyz-d65.tokenscript +34 -0
- package/src/schemas/types/srgb-linear-color/initializer.tokenscript +13 -0
- package/src/schemas/types/srgb-linear-color/schema.json +58 -0
- package/src/schemas/types/srgb-linear-color/unit.test.ts +291 -0
- package/src/schemas/types/xyz-d50-color/from-xyz-d65.tokenscript +36 -0
- package/src/schemas/types/xyz-d50-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d50-color/schema.json +48 -0
- package/src/schemas/types/xyz-d50-color/unit.test.ts +240 -0
- package/src/schemas/types/xyz-d65-color/from-linear-p3.tokenscript +47 -0
- package/src/schemas/types/xyz-d65-color/from-linear-srgb.tokenscript +38 -0
- package/src/schemas/types/xyz-d65-color/from-oklab.tokenscript +44 -0
- package/src/schemas/types/xyz-d65-color/initializer.tokenscript +16 -0
- package/src/schemas/types/xyz-d65-color/schema.json +68 -0
- package/src/schemas/types/xyz-d65-color/unit.test.ts +319 -0
- package/src/utils/schema-uri.ts +192 -0
- package/src/utils/type.ts +194 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OKHSL Color Schema Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the OKHSL color space (Björn Ottosson's perceptually uniform HSL)
|
|
5
|
+
* Reference: https://bottosson.github.io/posts/colorpicker/
|
|
6
|
+
*
|
|
7
|
+
* Uses Ottosson's algorithm with:
|
|
8
|
+
* - Polynomial approximation for max saturation at each hue
|
|
9
|
+
* - Halley's method refinement for machine-precision gamut boundary
|
|
10
|
+
* - Toe function for perceptually uniform lightness
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { log } from "@tests/helpers/logger";
|
|
14
|
+
import { executeWithSchema, getBundledSchema } from "@tests/helpers/schema-test-utils";
|
|
15
|
+
import Color from "colorjs.io";
|
|
16
|
+
import "colorjs.io/fn"; // Register all color spaces including OKHSL
|
|
17
|
+
import { describe, expect, it } from "vitest";
|
|
18
|
+
import type { ColorSpecification } from "@/bundler/types";
|
|
19
|
+
|
|
20
|
+
// Tolerance for ColorJS parity
|
|
21
|
+
const HUE_TOLERANCE = 1; // 1 degree tolerance for hue
|
|
22
|
+
|
|
23
|
+
describe("OKHSL Color Schema", () => {
|
|
24
|
+
describe("Schema Definition", () => {
|
|
25
|
+
it("should have correct schema structure", async () => {
|
|
26
|
+
const schema = (await getBundledSchema("okhsl-color")) as ColorSpecification;
|
|
27
|
+
|
|
28
|
+
expect(schema.name).toBe("OKHSL");
|
|
29
|
+
expect(schema.type).toBe("color");
|
|
30
|
+
expect(schema.schema).toBeDefined();
|
|
31
|
+
expect(schema.schema?.properties).toHaveProperty("h");
|
|
32
|
+
expect(schema.schema?.properties).toHaveProperty("s");
|
|
33
|
+
expect(schema.schema?.properties).toHaveProperty("l");
|
|
34
|
+
expect(schema.schema?.required).toEqual(["h", "s", "l"]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("should have okhsl initializer", async () => {
|
|
38
|
+
const schema = (await getBundledSchema("okhsl-color")) as ColorSpecification;
|
|
39
|
+
|
|
40
|
+
expect(schema.initializers).toHaveLength(1);
|
|
41
|
+
expect(schema.initializers[0].keyword).toBe("okhsl");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should have lossless conversion from OKLab", async () => {
|
|
45
|
+
const schema = (await getBundledSchema("okhsl-color")) as ColorSpecification;
|
|
46
|
+
|
|
47
|
+
expect(schema.conversions).toHaveLength(1);
|
|
48
|
+
const oklabToOkhsl = schema.conversions.find((c: { source: string }) =>
|
|
49
|
+
c.source.includes("oklab-color"),
|
|
50
|
+
);
|
|
51
|
+
expect(oklabToOkhsl).toBeDefined();
|
|
52
|
+
expect(oklabToOkhsl?.lossless).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("OKHSL Initialization", () => {
|
|
57
|
+
it("should initialize OKHSL color directly", async () => {
|
|
58
|
+
const result = await executeWithSchema(
|
|
59
|
+
"okhsl-color",
|
|
60
|
+
"type",
|
|
61
|
+
`
|
|
62
|
+
variable c: Color.OKHSL;
|
|
63
|
+
c.h = 30;
|
|
64
|
+
c.s = 0.8;
|
|
65
|
+
c.l = 0.6;
|
|
66
|
+
c
|
|
67
|
+
`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect((result as any).value.h.value).toBe(30);
|
|
71
|
+
expect((result as any).value.s.value).toBe(0.8);
|
|
72
|
+
expect((result as any).value.l.value).toBe(0.6);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("Conversion from OKLab to OKHSL", () => {
|
|
77
|
+
it("should convert achromatic OKLab (gray) to OKHSL with zero saturation", async () => {
|
|
78
|
+
const result = await executeWithSchema(
|
|
79
|
+
"okhsl-color",
|
|
80
|
+
"type",
|
|
81
|
+
`
|
|
82
|
+
variable lab: Color.OKLab;
|
|
83
|
+
lab.l = 0.5;
|
|
84
|
+
lab.a = 0;
|
|
85
|
+
lab.b = 0;
|
|
86
|
+
lab.to.okhsl()
|
|
87
|
+
`,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Gray should have saturation of 0
|
|
91
|
+
expect((result as any).value.s.value).toBeCloseTo(0, 5);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should convert chromatic OKLab to OKHSL with non-zero saturation", async () => {
|
|
95
|
+
const result = await executeWithSchema(
|
|
96
|
+
"okhsl-color",
|
|
97
|
+
"type",
|
|
98
|
+
`
|
|
99
|
+
variable lab: Color.OKLab;
|
|
100
|
+
lab.l = 0.6;
|
|
101
|
+
lab.a = 0.15;
|
|
102
|
+
lab.b = 0.05;
|
|
103
|
+
lab.to.okhsl()
|
|
104
|
+
`,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Should have saturation > 0
|
|
108
|
+
expect((result as any).value.s.value).toBeGreaterThan(0);
|
|
109
|
+
// Hue should be in red-orange range (positive a, small positive b)
|
|
110
|
+
expect((result as any).value.h.value).toBeGreaterThanOrEqual(0);
|
|
111
|
+
expect((result as any).value.h.value).toBeLessThan(60);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("ColorJS Parity", () => {
|
|
116
|
+
it("should match ColorJS for sRGB red", async () => {
|
|
117
|
+
const result = await executeWithSchema(
|
|
118
|
+
"okhsl-color",
|
|
119
|
+
"type",
|
|
120
|
+
`
|
|
121
|
+
variable srgb: Color.SRGB;
|
|
122
|
+
srgb.r = 1;
|
|
123
|
+
srgb.g = 0;
|
|
124
|
+
srgb.b = 0;
|
|
125
|
+
srgb.to.okhsl()
|
|
126
|
+
`,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const colorJS = new Color("srgb", [1, 0, 0]).to("okhsl");
|
|
130
|
+
|
|
131
|
+
log.info(`\n=== sRGB RED → OKHSL ===`);
|
|
132
|
+
log.info(
|
|
133
|
+
`TokenScript: { h: ${(result as any).value.h.value.toFixed(2)}, s: ${(result as any).value.s.value.toFixed(4)}, l: ${(result as any).value.l.value.toFixed(4)} }`,
|
|
134
|
+
);
|
|
135
|
+
log.info(
|
|
136
|
+
`ColorJS: { h: ${colorJS.coords[0].toFixed(2)}, s: ${colorJS.coords[1].toFixed(4)}, l: ${colorJS.coords[2].toFixed(4)} }`,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Hue should match (red ≈ 29° in OKHSL)
|
|
140
|
+
expect(Math.abs((result as any).value.h.value - colorJS.coords[0])).toBeLessThan(
|
|
141
|
+
HUE_TOLERANCE,
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should match ColorJS for sRGB green", async () => {
|
|
146
|
+
const result = await executeWithSchema(
|
|
147
|
+
"okhsl-color",
|
|
148
|
+
"type",
|
|
149
|
+
`
|
|
150
|
+
variable srgb: Color.SRGB;
|
|
151
|
+
srgb.r = 0;
|
|
152
|
+
srgb.g = 1;
|
|
153
|
+
srgb.b = 0;
|
|
154
|
+
srgb.to.okhsl()
|
|
155
|
+
`,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const colorJS = new Color("srgb", [0, 1, 0]).to("okhsl");
|
|
159
|
+
|
|
160
|
+
log.info(`\n=== sRGB GREEN → OKHSL ===`);
|
|
161
|
+
log.info(
|
|
162
|
+
`TokenScript: { h: ${(result as any).value.h.value.toFixed(2)}, s: ${(result as any).value.s.value.toFixed(4)}, l: ${(result as any).value.l.value.toFixed(4)} }`,
|
|
163
|
+
);
|
|
164
|
+
log.info(
|
|
165
|
+
`ColorJS: { h: ${colorJS.coords[0].toFixed(2)}, s: ${colorJS.coords[1].toFixed(4)}, l: ${colorJS.coords[2].toFixed(4)} }`,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// Green ≈ 142° in OKHSL
|
|
169
|
+
expect(Math.abs((result as any).value.h.value - colorJS.coords[0])).toBeLessThan(
|
|
170
|
+
HUE_TOLERANCE,
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("should match ColorJS for sRGB blue", async () => {
|
|
175
|
+
const result = await executeWithSchema(
|
|
176
|
+
"okhsl-color",
|
|
177
|
+
"type",
|
|
178
|
+
`
|
|
179
|
+
variable srgb: Color.SRGB;
|
|
180
|
+
srgb.r = 0;
|
|
181
|
+
srgb.g = 0;
|
|
182
|
+
srgb.b = 1;
|
|
183
|
+
srgb.to.okhsl()
|
|
184
|
+
`,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const colorJS = new Color("srgb", [0, 0, 1]).to("okhsl");
|
|
188
|
+
|
|
189
|
+
log.info(`\n=== sRGB BLUE → OKHSL ===`);
|
|
190
|
+
log.info(
|
|
191
|
+
`TokenScript: { h: ${(result as any).value.h.value.toFixed(2)}, s: ${(result as any).value.s.value.toFixed(4)}, l: ${(result as any).value.l.value.toFixed(4)} }`,
|
|
192
|
+
);
|
|
193
|
+
log.info(
|
|
194
|
+
`ColorJS: { h: ${colorJS.coords[0].toFixed(2)}, s: ${colorJS.coords[1].toFixed(4)}, l: ${colorJS.coords[2].toFixed(4)} }`,
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Blue ≈ 264° in OKHSL
|
|
198
|
+
expect(Math.abs((result as any).value.h.value - colorJS.coords[0])).toBeLessThan(
|
|
199
|
+
HUE_TOLERANCE,
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("should match ColorJS for mid-gray", async () => {
|
|
204
|
+
const result = await executeWithSchema(
|
|
205
|
+
"okhsl-color",
|
|
206
|
+
"type",
|
|
207
|
+
`
|
|
208
|
+
variable srgb: Color.SRGB;
|
|
209
|
+
srgb.r = 0.5;
|
|
210
|
+
srgb.g = 0.5;
|
|
211
|
+
srgb.b = 0.5;
|
|
212
|
+
srgb.to.okhsl()
|
|
213
|
+
`,
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const colorJS = new Color("srgb", [0.5, 0.5, 0.5]).to("okhsl");
|
|
217
|
+
|
|
218
|
+
log.info(`\n=== sRGB MID-GRAY → OKHSL ===`);
|
|
219
|
+
log.info(
|
|
220
|
+
`TokenScript: { h: ${(result as any).value.h.value.toFixed(2)}, s: ${(result as any).value.s.value.toFixed(4)}, l: ${(result as any).value.l.value.toFixed(4)} }`,
|
|
221
|
+
);
|
|
222
|
+
// ColorJS returns null hue for achromatic colors
|
|
223
|
+
log.info(
|
|
224
|
+
`ColorJS: { h: ${colorJS.coords[0] ?? "null"}, s: ${colorJS.coords[1].toFixed(4)}, l: ${colorJS.coords[2].toFixed(4)} }`,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Gray should have S ≈ 0
|
|
228
|
+
expect((result as any).value.s.value).toBeCloseTo(colorJS.coords[1], 2);
|
|
229
|
+
// Lightness should match
|
|
230
|
+
expect((result as any).value.l.value).toBeCloseTo(colorJS.coords[2], 1);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe("Round-trip Conversion", () => {
|
|
235
|
+
it("should preserve hue through OKLab round-trip", async () => {
|
|
236
|
+
const result = await executeWithSchema(
|
|
237
|
+
"okhsl-color",
|
|
238
|
+
"type",
|
|
239
|
+
`
|
|
240
|
+
variable c: Color.OKHSL;
|
|
241
|
+
c.h = 180;
|
|
242
|
+
c.s = 0.5;
|
|
243
|
+
c.l = 0.6;
|
|
244
|
+
c.to.oklab().to.okhsl()
|
|
245
|
+
`,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
expect((result as any).value.h.value).toBeCloseTo(180, 0);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
253
|
+
// COMPREHENSIVE COLORJS PARITY TESTS
|
|
254
|
+
// Tests a wide range of colors against ColorJS reference implementation
|
|
255
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
256
|
+
describe("Comprehensive ColorJS Parity", () => {
|
|
257
|
+
/**
|
|
258
|
+
* Helper to test sRGB → OKHSL conversion against ColorJS
|
|
259
|
+
* Logs detailed comparison and asserts within tolerances
|
|
260
|
+
*/
|
|
261
|
+
async function testSRGBToOKHSL(r: number, g: number, b: number, label: string) {
|
|
262
|
+
const result = await executeWithSchema(
|
|
263
|
+
"okhsl-color",
|
|
264
|
+
"type",
|
|
265
|
+
`
|
|
266
|
+
variable srgb: Color.SRGB;
|
|
267
|
+
srgb.r = ${r};
|
|
268
|
+
srgb.g = ${g};
|
|
269
|
+
srgb.b = ${b};
|
|
270
|
+
srgb.to.okhsl()
|
|
271
|
+
`,
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
const colorJS = new Color("srgb", [r, g, b]).to("okhsl");
|
|
275
|
+
|
|
276
|
+
const tsH = (result as any).value.h.value;
|
|
277
|
+
const tsS = (result as any).value.s.value;
|
|
278
|
+
const tsL = (result as any).value.l.value;
|
|
279
|
+
|
|
280
|
+
const cjH = colorJS.coords[0];
|
|
281
|
+
const cjS = colorJS.coords[1];
|
|
282
|
+
const cjL = colorJS.coords[2];
|
|
283
|
+
|
|
284
|
+
log.info(`\n${label}: sRGB(${r}, ${g}, ${b})`);
|
|
285
|
+
log.info(` TokenScript: h=${tsH?.toFixed(2)}, s=${tsS?.toFixed(4)}, l=${tsL?.toFixed(4)}`);
|
|
286
|
+
log.info(
|
|
287
|
+
` ColorJS: h=${cjH?.toFixed(2) ?? "null"}, s=${cjS?.toFixed(4)}, l=${cjL?.toFixed(4)}`,
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
// Saturation comparison - with full findGamutIntersection, we achieve tight parity
|
|
291
|
+
const satDiff = Math.abs(tsS - cjS);
|
|
292
|
+
if (satDiff > 0.02) {
|
|
293
|
+
log.info(` ⚠️ Saturation delta: ${satDiff.toFixed(4)}`);
|
|
294
|
+
}
|
|
295
|
+
expect(satDiff).toBeLessThan(0.05); // Tight tolerance with full algorithm
|
|
296
|
+
|
|
297
|
+
// Lightness should always match closely
|
|
298
|
+
expect(tsL).toBeCloseTo(cjL, 1);
|
|
299
|
+
|
|
300
|
+
// Hue only matters if color is chromatic (S > 0.01)
|
|
301
|
+
if (cjS > 0.01 && cjH !== null) {
|
|
302
|
+
// Handle hue wrap-around (e.g., 359° vs 1°)
|
|
303
|
+
let hueDiff = Math.abs(tsH - cjH);
|
|
304
|
+
if (hueDiff > 180) hueDiff = 360 - hueDiff;
|
|
305
|
+
expect(hueDiff).toBeLessThan(HUE_TOLERANCE);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return { ts: { h: tsH, s: tsS, l: tsL }, cj: { h: cjH, s: cjS, l: cjL } };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
describe("Edge Cases", () => {
|
|
312
|
+
it("should handle black (0, 0, 0)", async () => {
|
|
313
|
+
await testSRGBToOKHSL(0, 0, 0, "BLACK");
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it("should handle white (1, 1, 1)", async () => {
|
|
317
|
+
await testSRGBToOKHSL(1, 1, 1, "WHITE");
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("should handle near-black (0.01, 0.01, 0.01)", async () => {
|
|
321
|
+
await testSRGBToOKHSL(0.01, 0.01, 0.01, "NEAR-BLACK");
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("should handle near-white (0.99, 0.99, 0.99)", async () => {
|
|
325
|
+
await testSRGBToOKHSL(0.99, 0.99, 0.99, "NEAR-WHITE");
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
describe("Primary Colors (Maximum Saturation)", () => {
|
|
330
|
+
it("should handle pure red (1, 0, 0)", async () => {
|
|
331
|
+
await testSRGBToOKHSL(1, 0, 0, "PURE RED");
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("should handle pure green (0, 1, 0)", async () => {
|
|
335
|
+
await testSRGBToOKHSL(0, 1, 0, "PURE GREEN");
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it("should handle pure blue (0, 0, 1)", async () => {
|
|
339
|
+
await testSRGBToOKHSL(0, 0, 1, "PURE BLUE");
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
describe("Secondary Colors (CMY)", () => {
|
|
344
|
+
it("should handle cyan (0, 1, 1)", async () => {
|
|
345
|
+
await testSRGBToOKHSL(0, 1, 1, "CYAN");
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("should handle magenta (1, 0, 1)", async () => {
|
|
349
|
+
await testSRGBToOKHSL(1, 0, 1, "MAGENTA");
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it("should handle yellow (1, 1, 0)", async () => {
|
|
353
|
+
await testSRGBToOKHSL(1, 1, 0, "YELLOW");
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
describe("Grayscale (Achromatic)", () => {
|
|
358
|
+
it("should handle 10% gray", async () => {
|
|
359
|
+
await testSRGBToOKHSL(0.1, 0.1, 0.1, "10% GRAY");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("should handle 25% gray", async () => {
|
|
363
|
+
await testSRGBToOKHSL(0.25, 0.25, 0.25, "25% GRAY");
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it("should handle 50% gray", async () => {
|
|
367
|
+
await testSRGBToOKHSL(0.5, 0.5, 0.5, "50% GRAY");
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("should handle 75% gray", async () => {
|
|
371
|
+
await testSRGBToOKHSL(0.75, 0.75, 0.75, "75% GRAY");
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("should handle 90% gray", async () => {
|
|
375
|
+
await testSRGBToOKHSL(0.9, 0.9, 0.9, "90% GRAY");
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
describe("Mid-Saturation Colors", () => {
|
|
380
|
+
it("should handle mid-saturation red", async () => {
|
|
381
|
+
await testSRGBToOKHSL(0.8, 0.3, 0.3, "MID-SAT RED");
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("should handle mid-saturation green", async () => {
|
|
385
|
+
await testSRGBToOKHSL(0.3, 0.8, 0.3, "MID-SAT GREEN");
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it("should handle mid-saturation blue", async () => {
|
|
389
|
+
await testSRGBToOKHSL(0.3, 0.3, 0.8, "MID-SAT BLUE");
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("should handle pastel pink", async () => {
|
|
393
|
+
await testSRGBToOKHSL(1, 0.7, 0.8, "PASTEL PINK");
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it("should handle olive", async () => {
|
|
397
|
+
await testSRGBToOKHSL(0.5, 0.5, 0, "OLIVE");
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should handle teal", async () => {
|
|
401
|
+
await testSRGBToOKHSL(0, 0.5, 0.5, "TEAL");
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
describe("Dark Colors", () => {
|
|
406
|
+
it("should handle dark red", async () => {
|
|
407
|
+
await testSRGBToOKHSL(0.3, 0, 0, "DARK RED");
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it("should handle dark green", async () => {
|
|
411
|
+
await testSRGBToOKHSL(0, 0.3, 0, "DARK GREEN");
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it("should handle dark blue", async () => {
|
|
415
|
+
await testSRGBToOKHSL(0, 0, 0.3, "DARK BLUE");
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it("should handle brown", async () => {
|
|
419
|
+
await testSRGBToOKHSL(0.4, 0.2, 0.1, "BROWN");
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it("should handle navy", async () => {
|
|
423
|
+
await testSRGBToOKHSL(0, 0, 0.3, "NAVY");
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
describe("Light Colors", () => {
|
|
428
|
+
it("should handle light red/salmon", async () => {
|
|
429
|
+
await testSRGBToOKHSL(1, 0.6, 0.6, "SALMON");
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it("should handle light green/mint", async () => {
|
|
433
|
+
await testSRGBToOKHSL(0.6, 1, 0.6, "MINT");
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it("should handle light blue/sky", async () => {
|
|
437
|
+
await testSRGBToOKHSL(0.6, 0.6, 1, "SKY BLUE");
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should handle cream", async () => {
|
|
441
|
+
await testSRGBToOKHSL(1, 0.98, 0.8, "CREAM");
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
describe("Problematic Hue Regions", () => {
|
|
446
|
+
// These test regions where polynomial approximation might be less accurate
|
|
447
|
+
|
|
448
|
+
it("should handle orange (hue transition R→Y)", async () => {
|
|
449
|
+
await testSRGBToOKHSL(1, 0.5, 0, "ORANGE");
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
it("should handle lime (hue transition Y→G)", async () => {
|
|
453
|
+
await testSRGBToOKHSL(0.5, 1, 0, "LIME");
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it("should handle spring green (hue transition G→C)", async () => {
|
|
457
|
+
await testSRGBToOKHSL(0, 1, 0.5, "SPRING GREEN");
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it("should handle azure (hue transition C→B)", async () => {
|
|
461
|
+
await testSRGBToOKHSL(0, 0.5, 1, "AZURE");
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it("should handle violet (hue transition B→M)", async () => {
|
|
465
|
+
await testSRGBToOKHSL(0.5, 0, 1, "VIOLET");
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it("should handle rose (hue transition M→R)", async () => {
|
|
469
|
+
await testSRGBToOKHSL(1, 0, 0.5, "ROSE");
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
describe("Low Chroma Colors (Near Achromatic)", () => {
|
|
474
|
+
it("should handle very desaturated red", async () => {
|
|
475
|
+
await testSRGBToOKHSL(0.52, 0.48, 0.48, "DESAT RED");
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
it("should handle very desaturated blue", async () => {
|
|
479
|
+
await testSRGBToOKHSL(0.48, 0.48, 0.52, "DESAT BLUE");
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it("should handle barely tinted gray", async () => {
|
|
483
|
+
await testSRGBToOKHSL(0.501, 0.5, 0.499, "BARELY TINTED");
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
describe("Real-World Colors", () => {
|
|
488
|
+
it("should handle Tailwind blue-500", async () => {
|
|
489
|
+
// #3b82f6 = rgb(59, 130, 246)
|
|
490
|
+
await testSRGBToOKHSL(59 / 255, 130 / 255, 246 / 255, "TAILWIND BLUE-500");
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it("should handle GitHub green", async () => {
|
|
494
|
+
// #238636 = rgb(35, 134, 54)
|
|
495
|
+
await testSRGBToOKHSL(35 / 255, 134 / 255, 54 / 255, "GITHUB GREEN");
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it("should handle Discord purple", async () => {
|
|
499
|
+
// #5865f2 = rgb(88, 101, 242)
|
|
500
|
+
await testSRGBToOKHSL(88 / 255, 101 / 255, 242 / 255, "DISCORD PURPLE");
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it("should handle Slack aubergine", async () => {
|
|
504
|
+
// #4a154b = rgb(74, 21, 75)
|
|
505
|
+
await testSRGBToOKHSL(74 / 255, 21 / 255, 75 / 255, "SLACK AUBERGINE");
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it("should handle Twitter blue", async () => {
|
|
509
|
+
// #1da1f2 = rgb(29, 161, 242)
|
|
510
|
+
await testSRGBToOKHSL(29 / 255, 161 / 255, 242 / 255, "TWITTER BLUE");
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
});
|