Unit testing framework for Sass code with JavaScript test runner integration
—
Testing compiled CSS output from mixins and complex Sass expressions, with exact matching, subset matching, and string matching capabilities. These assertions compare the final CSS output after compilation.
Tests that CSS output matches exactly between actual and expected results.
/**
* Wrapper for CSS output assertions containing output and expect blocks
* @param $description - Optional description of the assertion
* @content Must contain exactly one @include output and one @include expect
*/
@mixin assert($description: null);
/**
* Defines the actual CSS output to test
* @param $selector - Whether to wrap output in .test-output selector (default: true)
* @content CSS rules and properties to test
*/
@mixin output($selector: true);
/**
* Defines the expected CSS output for comparison
* @param $selector - Whether to wrap output in .test-output selector (default: true)
* @content Expected CSS rules and properties
*/
@mixin expect($selector: true);Usage Examples:
@use 'pkg:sass-true' as *;
@include test('Button mixin generates correct CSS') {
@include assert('Should generate primary button styles') {
@include output {
@include button('primary', 'large');
}
@include expect {
padding: 1rem 2rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 0.25rem;
font-size: 1.25rem;
}
}
}
@include test('Responsive mixin works correctly') {
@include assert {
@include output {
@include responsive('mobile') {
font-size: 14px;
}
}
@include expect {
@media (max-width: 767px) {
font-size: 14px;
}
}
}
}Tests that expected CSS is contained within the actual output (subset matching).
/**
* Tests that expected CSS is contained within the actual output
* @param $selector - Whether to wrap output in .test-output selector
* @content Expected CSS that should be present in the output
*/
@mixin contains($selector: true);Usage Examples:
@use 'pkg:sass-true' as *;
@include test('Mixin includes required properties') {
@include assert('Should contain essential button properties') {
@include output {
@include button('primary', 'large');
// This might generate additional properties like:
// display: inline-block;
// cursor: pointer;
// transition: all 0.2s;
// etc.
}
@include contains {
// We only care that these specific properties are present
background-color: #007bff;
padding: 1rem 2rem;
border: none;
}
}
}
@include test('Complex layout contains grid properties') {
@include assert {
@include output {
@include grid-container;
}
@include contains {
display: grid;
grid-template-columns: repeat(12, 1fr);
// Don't care about other properties that might be generated
}
}
}Tests that a specific substring is present in the CSS output.
/**
* Tests that CSS output contains a specific substring
* @param $string-to-find - The substring to search for in the output
*/
@mixin contains-string($string-to-find);Usage Examples:
@use 'pkg:sass-true' as *;
@include test('Generated CSS contains expected strings') {
@include assert('Should contain flexbox properties') {
@include output {
@include flex-center;
}
@include contains-string('display: flex');
@include contains-string('justify-content: center');
@include contains-string('align-items: center');
}
}
@include test('Custom property names are generated') {
@include assert {
@include output {
@include theme-colors('dark');
}
@include contains-string('--theme-bg:');
@include contains-string('--theme-text:');
@include contains-string('#1a1a1a');
}
}For testing raw CSS properties without wrapper selectors:
@use 'pkg:sass-true' as *;
@include test('Raw property output') {
@include assert {
@include output($selector: false) {
// Generates raw CSS without .test-output wrapper
color: red;
font-size: 16px;
}
@include expect($selector: false) {
color: red;
font-size: 16px;
}
}
}@use 'pkg:sass-true' as *;
@include test('Nested selector output') {
@include assert('Should generate BEM-style selectors') {
@include output {
@include bem-block('card') {
@include bem-element('title') {
font-size: 1.5rem;
font-weight: bold;
}
@include bem-modifier('featured') {
border: 2px solid gold;
}
}
}
@include expect {
.card__title {
font-size: 1.5rem;
font-weight: bold;
}
.card--featured {
border: 2px solid gold;
}
}
}
}@use 'pkg:sass-true' as *;
@include test('Responsive utilities') {
@include assert('Should generate mobile-first breakpoints') {
@include output {
@include breakpoint('tablet') {
.container {
max-width: 768px;
}
}
}
@include expect {
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
}
}
}@use 'pkg:sass-true' as *;
@include test('Comprehensive output testing') {
@include assert('Full button test') {
@include output {
@include button('primary', 'large', $rounded: true);
}
// Test exact match for critical properties
@include expect {
padding: 1rem 2rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 0.5rem;
font-size: 1.25rem;
cursor: pointer;
}
}
// Also test that it contains hover state
@include assert('Should include hover state') {
@include output {
@include button('primary', 'large', $rounded: true);
}
@include contains-string(':hover');
@include contains-string('background-color: #0056b3');
}
}When testing mixins that might generate CSS comments for errors:
@use 'pkg:sass-true' as *;
@include test('Error handling in mixins') {
@include assert('Should output error comment for invalid input') {
@include output {
@include color-scheme('invalid-scheme');
}
@include contains-string('ERROR');
@include contains-string('invalid-scheme');
}
}CSS output testing is sensitive to formatting. The compiled CSS from both output and expect blocks is compared exactly, including whitespace and property order.
// These might not match due to different formatting:
@include expect {
margin:0;
padding:0;
}
@include expect {
margin: 0;
padding: 0;
}Properties should generally be in the same order:
// Preferred - consistent order
@include expect {
display: flex;
justify-content: center;
align-items: center;
}
// May fail if actual output has different order
@include expect {
align-items: center;
display: flex;
justify-content: center;
}When exact formatting or property order is uncertain, use contains for more flexible testing:
@include assert {
@include output {
@include flex-center; // Might generate properties in any order
}
@include contains {
display: flex;
}
@include contains {
justify-content: center;
}
@include contains {
align-items: center;
}
}When using JavaScript test runners (Mocha, Jest), CSS output comparison is automated. The JavaScript integration parses the compiled CSS and runs the comparisons, providing detailed diff output for failures.
Install with Tessl CLI
npx tessl i tessl/npm-sass-true