Skip to content

Commit

Permalink
Add tests for parsing and serializing missing channels from Sass (#2023)
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 authored Oct 1, 2024
1 parent 58ae7fd commit 754b799
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
44 changes: 42 additions & 2 deletions js-api-spec/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

/* eslint-disable @typescript-eslint/no-explicit-any */

import {info} from 'sass';
import * as sass from 'sass';

/* Whether the tests are running in a browser context. */
export const isBrowser = !global.process;

/** The name of the implementation of Sass being tested. */
export const sassImpl = info.split('\t')[0] as 'dart-sass' | 'sass-embedded';
export const sassImpl = sass.info.split('\t')[0] as
| 'dart-sass'
| 'sass-embedded';

type Implementation = 'dart-sass' | 'sass-embedded' | 'browser';

Expand Down Expand Up @@ -116,3 +118,41 @@ export async function captureStdioAsync(

return {out, err};
}

/**
* Parses {@link expression} as a Sass expression, evaluates it, and returns its
* value. The expression has access to all the built-in modules at their usual
* URLs.
*/
export function evaluateExpression(expression: string): sass.Value {
let value: sass.Value | undefined;
sass.compileString(
`
@use "sass:color";
@use "sass:list";
@use "sass:map";
@use "sass:math";
@use "sass:meta";
@use "sass:selector";
@use "sass:string";
$_: fn((${expression}));
`,
{
functions: {
'fn($arg)': args => {
value = args[0];
return sass.sassNull;
},
},
}
);
return value!;
}

/** Converts {@link value} to its serialized Sass representation. */
export function serializeValue(value: sass.Value): string {
const result = sass.compileString('a {b: fn()}', {
functions: {'fn()': () => value},
});
return result.css.match(/b: ?(.*);/)![1];
}
47 changes: 47 additions & 0 deletions js-api-spec/value/color/color-4-channels.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {List} from 'immutable';

import {spaces} from './spaces';
import {channelCases, channelNames} from './utils';
import {evaluateExpression, serializeValue} from '../../utils';

const spaceNames = Object.keys(spaces) as KnownColorSpace[];

Expand Down Expand Up @@ -311,6 +312,52 @@ describe('Color 4 SassColor Channels', () => {
);
});
});

describe('parsed from Sass code', () => {
it('parses defined values', () => {
const color = evaluateExpression(
`color(display-p3 ${spaces['display-p3'].pink.join(' ')} / 0.5)`
) as SassColor;
expect(color.channels).toFuzzyEqualList(spaces['display-p3'].pink);
expect(color.alpha).toFuzzyEqual(0.5);
});

// Regression test for sass/sass#3950
it('parses missing values', () => {
const color = evaluateExpression(
'color(display-p3 0 none 1 / none)'
) as SassColor;
expect(color.channelsOrNull).toFuzzyEqualList([0, null, 1]);
expect(color.isChannelMissing('alpha')).toBeTrue();
});
});

describe('serialized to CSS', () => {
it('with defined values', () =>
expect(
serializeValue(
spaces['display-p3']
.constructor(...spaces['display-p3'].pink)
.change({alpha: 0.5})
)
).toEqual(
'color(display-p3 0.9510333334 0.6749909746 0.7568568354 / 0.5)'
));

// Regression test for sass/sass#3950
it('with missing values', () =>
expect(
serializeValue(
new SassColor({
red: 0,
green: null,
blue: 1,
alpha: null,
space: 'display-p3',
})
)
).toEqual('color(display-p3 0 none 1 / none)'));
});
});

/**
Expand Down

0 comments on commit 754b799

Please sign in to comment.