Permalink
Fetching contributors…
Cannot retrieve contributors at this time
432 lines (391 sloc) 11.8 KB
// Assert
// ======
// Assert True
// -----------
/// Assert that a parameter is truthy.
/// - Empty lists and strings are excluded from default Sass truthyness.
/// Assertions are used inside the `test()` mixin
///
/// @group api-assert-values
///
/// @param {*} $assert -
/// Asserted value to test
/// @param {string} $description [null] -
/// Description of the assertion being tested.
/// A `null` of `false` value generates a default description.
///
/// @example scss -
/// @include test('Non-empty strings are truthy') {
/// @include assert-true(
/// 'Hello World',
/// 'You can optionally describe the assertion...');
/// }
@mixin assert-true(
$assert,
$description: null
) {
$default: _true-context('test');
$truthy: _true-is-truthy($assert);
@include _true-context('assert', '[assert-true] #{$description or $default}');
@include _true-assert-results($truthy, true);
}
// Assert False
// ------------
/// Assert that a parameter is falsey.
/// - Empty lists and strings are added to default Sass falseyness.
/// to define the expected results of the test.
///
/// @group api-assert-values
///
/// @param {*} $assert -
/// Asserted value to test
/// @param {string} $description [null] -
/// Description of the assertion being tested.
/// A `null` of `false` value generates a default description.
///
/// @example scss -
/// @include test('Empty strings are falsey') {
/// @include assert-false(
/// '',
/// 'You can optionally describe the assertion...');
/// }
@mixin assert-false(
$assert,
$description: null
) {
$default: _true-context('test');
$falsey: not _true-is-truthy($assert);
@include _true-context('assert', '[assert-false] #{$description or $default}');
@include _true-assert-results($falsey, true);
}
// Assert Equal
// ------------
/// Assert that two parameters are `equal`
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
///
/// @group api-assert-values
///
/// @param {*} $assert -
/// Asserted value to test
/// @param {*} $expected -
/// Expected match
/// @param {string} $description [null] -
/// Description of the assertion being tested
/// (a `null` of `false` value generates a default description)
/// @param {bool} $inspect [false] -
/// Optionally compare inspected values
/// (useful for comparing CSS output rather than Sass values)
///
/// @example scss -
/// @include test('Division works as expected in Sass') {
/// @include assert-equal(
/// 8 / 2,
/// 4,
/// 'You can optionally describe the assertion...');
/// }
@mixin assert-equal(
$assert,
$expected,
$description: null,
$inspect: false
) {
$default: _true-context('test');
@if $inspect {
$assert: inspect($assert);
$expected: inspect($expected);
}
@include _true-context('assert', '[assert-equal] #{$description or $default}');
@include _true-assert-results($assert, $expected);
}
// Assert UnEqual
// --------------
/// Assert that two parameters are `unequal`
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
///
/// @group api-assert-values
///
/// @param {*} $assert -
/// Asserted value to test
/// @param {*} $expected -
/// Expected mismatch
/// @param {string} $description [null] -
/// Description of the assertion being tested.
/// A `null` of `false` value generates a default description.
/// @param {bool} $inspect [false] -
/// Optionally compare inspected values
/// (useful for comparing CSS output rather than Sass values)
///
/// @example scss -
/// @include test('Strings and numbers hare not the same') {
/// @include assert-unequal(
/// 1em,
/// '1em');
/// }
@mixin assert-unequal(
$assert,
$expected,
$description: null,
$inspect: false
) {
$default: _true-context('test');
@if $inspect {
$assert: inspect($assert);
$expected: inspect($expected);
}
@include _true-context('assert', '[assert-unequal] #{$description or $default}');
@include _true-assert-results($assert, $expected, 'unequal');
}
// Assert [output]
// ---------------
/// Define a CSS-output assertion.
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
/// - The `assert()` mixin is a wrapper,
/// and should contain one `output()` block and one `expect()` block
/// as nested contents.
/// - These three mixins together describe a single
/// `assert-equal` comparison on output CSS.
/// The compiled CSS-results of the `output()` mixin
/// will be compared against the results of the `expect()` mixin.
/// - When using Mocha integration, the output comparison is automated –
/// otherwise you will have to compare the output manually.
/// Using `git diff` is a great way to watch for changes in output.
///
/// @group api-assert-output
///
/// @param {string} $description [null] -
/// Description of the assertion being tested.
/// A `null` of `false` value generates a default description.
///
/// @content Use `output()` and `expect()` mixins
/// to define blocks for comparison
///
/// @example scss -
/// @include test('Sass math compiles before output') {
/// @include assert('You can also describe the assertion...') {
/// @include output {
/// width: 14em + 2;
/// }
/// @include expect {
/// width: 16em;
/// }
/// }
/// }
@mixin assert(
$description: null
) {
$default: _true-context('test');
@include _true-output-context('assert');
@include _true-context('assert', '[output] #{$description or $default}');
@include _true-message(' ASSERT: #{$description} ', 'comments');
@content;
@include _true-output-context(null);
@include _true-update-test('output-to-css');
@include _true-update-stats-count('assertions');
@include _true-context-pop;
@include _true-message(' END_ASSERT ', 'comments');
}
// Output
// ------
/// Describe the test content to be evaluated
/// against the paired `expect()` block.
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
/// - The `output()` mixin requires a content block,
/// and should be nested inside the `assert()` mixin
/// along with a single `expect()` block.
/// - These three mixins together describe a single
/// `assert-equal` comparison on output CSS.
/// The compiled CSS-results of the `output()` mixin
/// will be compared against the results of the `expect()` mixin.
/// - When using Mocha integration, the output comparison is automated –
/// otherwise you will have to compare the output manually.
/// Using `git diff` is a great way to watch for changes in output.
///
/// @group api-assert-output
///
/// @param {bool} $selector [true] -
/// Optionally wrap the contents in a `.test-output` selector block,
/// so you can test property-value output directly.
///
/// @content Define the test content to be checked
///
/// @example scss -
/// @include test('Sass math compiles before output') {
/// @include assert {
/// @include output {
/// width: 14em + 2;
/// }
/// @include expect {
/// width: 16em;
/// }
/// }
/// }
@mixin output(
$selector: true
) {
@include _true-output-context('output');
@include _true-message(' OUTPUT ', 'comments');
@if $selector {
.test-output {
@content;
}
} @else {
@content;
}
@include _true-message(' END_OUTPUT ', 'comments');
}
// Expect
// ------
/// Describe the expected results of the paired `output()` block.
/// The `expect()` mixin requires a content block,
/// and should be nested inside the `assert()` mixin,
/// along with a single `output()` block.
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
/// - These three mixins together describe a single
/// `assert-equal` comparison on output CSS.
/// The compiled CSS-results of the `output()` mixin
/// will be compared against the results of the `expect()` mixin.
/// - When using Mocha integration, the output comparison is automated –
/// otherwise you will have to compare the output manually.
/// Using `git diff` is a great way to watch for changes in output.
///
/// @group api-assert-output
///
/// @param {bool} $selector [true] -
/// Optionally wrap the contents in a `.test-output` selector block,
/// so you can test property-value output directly.
///
/// @content Define the expected results of a sibling `output()` mixin
///
/// @example scss -
/// @include test('Sass math compiles before output') {
/// @include assert {
/// @include output {
/// width: 14em + 2;
/// }
/// @include expect {
/// width: 16em;
/// }
/// }
/// }
@mixin expect(
$selector: true
) {
@include _true-output-context('expect');
@include _true-message(' EXPECTED ', 'comments');
@if $selector {
.test-output {
@content;
}
} @else {
@content;
}
@include _true-message(' END_EXPECTED ', 'comments');
}
// Contains
// ------
/// Describe the expected results of the paired `output()` block.
/// The `contains()` mixin requires a content block,
/// and should be nested inside the `assert()` mixin,
/// along with a single `output()` block.
/// Assertions are used inside the `test()` mixin
/// to define the expected results of the test.
/// - These three mixins together describe a single
/// comparison on output CSS.
/// The compiled CSS-results of the `contains()` mixin
/// will be compared against the results of the `output()` mixin
/// to see if all of the `contains` CSS is within the `output` CSS.
/// - When using Mocha integration, the output comparison is automated –
/// otherwise you will have to compare the output manually.
/// Using `git diff` is a great way to watch for changes in output.
///
/// @group api-assert-output
///
/// @param {bool} $selector [true] -
/// Optionally wrap the contents in a `.test-output` selector block,
/// so you can test property-value output directly.
///
/// @content Define the expected results of a sibling `output()` mixin
///
/// @example scss -
/// @include test('Sass math compiles before output') {
/// @include assert {
/// @include output {
/// height: 100%;
/// width: 14em + 2;
/// }
/// @include contains {
/// width: 16em;
/// }
/// }
/// }
@mixin contains(
$selector: true
) {
@include _true-output-context('contains');
@include _true-message(' CONTAINED ', 'comments');
@if $selector {
.test-output {
@content;
}
} @else {
@content;
}
@include _true-message(' END_CONTAINED ', 'comments');
}
// Assert Results
// --------------
/// Get an official result,
/// record it in the database and output,
/// provide details as necessary,
/// and end the assertion.
///
/// @access private
/// @group private-assert
///
/// @param {*} $assert - Value to consider
/// @param {*} $expected - Expected match
/// @param {bool} $unequal [false] -
/// Set to `true` if the comparison is expected to fail
///
/// @output - Document the passing or failing result of the test
@mixin _true-assert-results(
$assert,
$expected,
$unequal: false,
$terminal: $true-terminal-output
) {
$result: _true-get-result($assert, $expected, $unequal);
@if $result == 'pass' {
@include _true-pass-details;
} @else {
@include _true-fail-details($assert, $expected, $terminal);
}
@include _true-update-test($result);
@include _true-update-stats-count('assertions');
@include _true-context-pop;
}
// Is Truthy
// ---------
/// Check that a value is truthy
/// (empty lists and strings return false)
///
/// @access private
/// @group private-assert
///
/// @param {*} $assert - Value to consider
///
/// @return {bool}
@function _true-is-truthy(
$assert
) {
$not: (not not $assert);
$list: ($assert != ());
$string: ($assert != '');
$truthy: if(($not and $list and $string), true, false);
@return $truthy;
}