True 10.0.1

True

License

true (verb): To make even, accurate, or precise. “True the wheels of a bicycle. True up the sides of a door. True your Sass code before you deploy.”

True is a unit-testing tool for Sass code.

Installation

1. Install via npm

npm install --save-dev sass-true

2. Install Dart Sass (if needed)

True requires Dart Sass v1.45.0 or higher:

npm install --save-dev sass-embedded # or `sass`

3. Import in your Sass tests

With Node.js package importer:

@use 'pkg:sass-true' as *;

With JavaScript test runner:

@use 'true' as *;

Without package importer:

// Path may vary based on your project structure
@use '../node_modules/sass-true' as *;

Configuration

True has one configuration variable: $terminal-output (boolean, defaults to true)

Value Behavior
true (default) Shows detailed terminal output for debugging and results. Best for standalone Sass compilation.
false Disables Sass terminal output. Use with JavaScript test runners (they handle their own reporting).

Legacy @import Support

If you’re still using @import instead of @use, use the legacy import path with the prefixed variable name:

// Path may vary
@import '../node_modules/sass-true/sass/true';
// Variable is named $true-terminal-output

Usage

True uses familiar testing syntax inspired by JavaScript test frameworks:

Testing Values (Functions & Variables)

True can compare Sass values during compilation:

@include describe('Zip [function]') {
  @include it('Zips multiple lists into a single multi-dimensional list') {
    // Assert the expected results
    @include assert-equal(zip(a b c, 1 2 3), (a 1, b 2, c 3));
  }
}

Alternative syntax using test-module and test:

@include test-module('Zip [function]') {
  @include test('Zips multiple lists into a single multi-dimensional list') {
    // Assert the expected results
    @include assert-equal(zip(a b c, 1 2 3), (a 1, b 2, c 3));
  }
}

Testing CSS Output (Mixins)

CSS output tests require a different assertion structure, with an outer assert mixin, and a matching pair of output and expect to contain the output-values:

// Test CSS output from mixins
@include it('Outputs a font size and line height based on keyword') {
  @include assert {
    @include output {
      @include font-size('large');
    }

    @include expect {
      font-size: 2rem;
      line-height: 3rem;
    }
  }
}

Note: CSS output is compared after compilation. You can review changes manually with git diff or use a JavaScript test runner for automated comparison.

Optional Summary Report

Display a test summary in CSS output and/or terminal:

@include report;

Documentation & Changelog

JavaScript Test Runner Integration

Integrate True with your existing JS test runner for enhanced reporting and automated CSS output comparison.

Quick Start

1. Install dependencies

npm install --save-dev sass-true
npm install --save-dev sass-embedded # or `sass` (if not already installed)

2. Write Sass tests

Create your Sass test file (e.g., test/test.scss) using True’s syntax (see Usage).

3. Create JS test file

Create a JavaScript shim to run your Sass tests (e.g., test/sass.test.js):

import path from 'node:path';
import { fileURLToPath } from 'node:url';
import sassTrue from 'sass-true';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const sassFile = path.join(__dirname, 'test.scss');
sassTrue.runSass({ describe, it }, sassFile);

4. Run your tests

Run Mocha, Jest, Vitest, or your test runner. Sass tests will appear in the terminal output.

Enable Watch Mode for Sass Files

By default, vitest --watch and jest --watch don’t detect Sass file changes.

Vitest solution: Add Sass files to forceRerunTriggers:

// vitest.config.js
module.exports = defineConfig({
  test: {
    forceRerunTriggers: ['**/*.scss'],
  },
});

See Vitest documentation for details.

Jest solution: Add "scss" to moduleFileExtensions:

// jest.config.js
module.exports = {
  moduleFileExtensions: ['js', 'json', 'scss'],
};

See Jest documentation for details.

Advanced Configuration

runSass() API

sassTrue.runSass(testRunnerConfig, sassPathOrSource, sassOptions);

Arguments:

  1. testRunnerConfig (object, required)

    Option Type Required Description
    describe function Yes Your test runner’s describe function
    it function Yes Your test runner’s it function
    sass string or object No Sass implementation name ('sass' or 'sass-embedded') or instance. Auto-detected if not provided.
    sourceType 'string' or 'path' No Set to 'string' to compile inline Sass source instead of file path (default: 'path')
    contextLines number No Number of CSS context lines to show in parse errors (default: 10)
  2. sassPathOrSource ('string' or 'path', required)

    • File path to Sass test file, or
    • Inline Sass source code (if sourceType: 'string')
  3. sassOptions (object, optional)

    • Standard Sass compile options (importers, loadPaths, style, etc.)
    • Default modifications by True:
      • loadPaths: True’s sass directory is automatically added (allowing @use 'true';)
      • importers: Node.js package importer added if importers is not defined and Dart Sass ≥ v1.71 (allowing @use 'pkg:sass-true' as *;)
    • ⚠️ Warning: Must use style: 'expanded' (default). style: 'compressed' is not supported.

Multiple Test Files

Call runSass() multiple times to run separate test files:

sassTrue.runSass({ describe, it }, path.join(__dirname, 'functions.test.scss'));
sassTrue.runSass({ describe, it }, path.join(__dirname, 'mixins.test.scss'));

Other Test Runners

Any test runner with describe/it functions (or equivalents) works with True:

// Example with custom test runner
import { suite, test } from 'my-test-runner';

sassTrue.runSass(
  { describe: suite, it: test },
  path.join(__dirname, 'test.scss'),
);

Custom Importers

If you use custom import syntax (e.g., tilde notation @use '~accoutrement/sass/tools'), you’ll need to provide a custom importer:

import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import sassTrue from 'sass-true';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const importers = [
  {
    findFileUrl(url) {
      if (!url.startsWith('~')) {
        return null;
      }
      return new URL(
        pathToFileURL(path.resolve('node_modules', url.substring(1))),
      );
    },
  },
];

const sassFile = path.join(__dirname, 'test.scss');
sassTrue.runSass({ describe, it }, sassFile, { importers });

At OddBird, we love contributing to the languages and tools developers rely on. We’re currently working on:

  • Polyfills for new Popover & Anchor Positioning functionality
  • CSS specifications for functions, mixins, and responsive typography
  • Sass testing tools like True

Help us keep this work sustainable! Sponsor logos and avatars are featured on our website.

→ Sponsor OddBird on Open Collective