CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sass-true

Unit testing framework for Sass code with JavaScript test runner integration

Pending
Overview
Eval results
Files

css-output-testing.mddocs/

CSS Output Testing

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.

Capabilities

Basic Output Testing

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;
      }
    }
  }
}

Subset Matching

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
    }
  }
}

String Matching

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');
  }
}

Advanced Usage

Testing Without Selectors

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;
    }
  }
}

Testing Complex Nested Structures

@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;
      }
    }
  }
}

Testing Media Queries

@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;
        }
      }
    }
  }
}

Combining Different Assertion Types

@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');
  }
}

Testing Error Output

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 Formatting Notes

Whitespace and Formatting

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;
}

Property Order

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;
}

Using Contains for Flexibility

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;
  }
}

Integration with JavaScript Runners

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

docs

css-output-testing.md

error-handling.md

index.md

javascript-integration.md

test-structure.md

value-assertions.md

tile.json