diff --git a/styl/true/_context.styl b/styl/true/_context.styl index 879274c..9fb5c82 100644 --- a/styl/true/_context.styl +++ b/styl/true/_context.styl @@ -1,191 +1,191 @@ -// unwrap-list($list) -// -// **[private:{list}]** Transforms a wrapped list into a unwrapped one -// -// Weight: 0 -// -// $list - **{list}** ***List to be unwrapped*** -// -// Styleguide Functions.unwrap-list -use('lib/unwrap-list.js'); - -// $_true-context = { buffer } -// -// **[private]** Stores the current module/test/assertion context stack -// -// Weight: 0 -// -// $buffer = () - **{list}** ***List to use as buffer for parsing*** -// -// Styleguide Variables.$_true-context -$_true-context = { - buffer: () -}; - -// _true-context-mixin($scope, $name) -// -// **[private:{void}]** Update the current context for a given scope -// -// Weight: 0 -// -// $scope - **{string}** ***Either `module`, `test` or `assert`*** -// $name - **{string}** ***Name or description of the current scope*** -// -// Styleguide Functions._true-context-mixin -_true-context-mixin($scope, $name) { - push($_true-context.buffer, '%s|%s' % (unquote($scope) unquote($name))); - - $_true-context.buffer = unwrap-list($_true-context.buffer); -} - -// _true-context-pop($type) -// -// **[private:{void}]** Remove the deepest context layer from `$_true-context.buffer` -// -// Weight: 0 -// -// Styleguide Functions._true-output-pop -_true-context-pop($type = null) { - $new = (); - - if ($type == null) { - for $i in 0 .. (length($_true-context.buffer) - 1) { - push($new, $_true-context.buffer[$i]); - } - - $_true-context.buffer = $new; - } else { - $_true-context.buffer = (); - } -} - -$_true-output-context = { - value: () -}; - -// _true-output-context($new, $context) -// -// **[private:{void}]** Add `assert`, `output`, `expect`, or `contains` context to an output test, or check to make sure they all exist before resetting the context. -// -// Weight: 0 -// -// $new - **{'assert'|'output'|'expect'|'contains'|null}** ***Add a new `assert`, `output`, `expect`, or `contains` layer to the context of an output-test, or use `null` to check that all context is properly formed and then reset it at the end of a test*** -// $context = $_true-output-context.value - **{list}** ***The current output context*** -// -// Styleguide Functions._true-output-context -_true-output-context($new, $context = $_true-output-context.value) { - $valid = 'assert' 'expect' 'output' 'contains'; - - $_true-output-context.value = _true-validate-output-context($new, $context); -} - -// _true-validate-output-context($new, $context) -// -// **[private:{string}]** Validate the new context, and return an updated context value -// -// Weight: 0 -// -// $new - **{'assert'|'output'|'expect'|'contains'|null}** ***Add a new `assert`, `output`, `expect`, or `contains` layer to the context of an output-test, or use `null` to check that all context is properly formed and then reset it at the end of a test*** -// $context = $_true-output-context.value - **{list}** ***The current output context*** -// -// Styleguide Functions._true-validate-output-context -_true-validate-output-context($new, $context = $_true-output-context.value) { - $valid = 'assert' 'expect' 'output' 'contains'; - - $validIndex = index($valid, $new); - $contextIndex = index($context, $new); - $assertIndex = index($context, 'assert') - - if ($new && $validIndex == null || $validIndex < 0 ) { - $error = $new + ' is not a valid context for output tests: ' + $valid; - - return _true-error($error, 'output-context'); - } else if ($contextIndex != null && $contextIndex >= 0 ) { - if ($new == 'assert') { - $error = 'The `assert()` mixin can not contain another `assert()`'; - - return _true-error($error, 'output-context'); - } - - $error = 'The `%s()` mixin must only be used once per `assert()`' % unquote($new); - - return _true-error($error, 'output-context'); - } else if ($new) { - $is-sub = index('expect' 'output' 'contains', $new); - $is-sub = $is-sub != null && $is-sub >= 0; - - // if ($is-sub && !($assertIndex != null && $assertIndex >= 0)) { - // $error = 'The `assert()` wrapper is required'; - - // return _true-error($error, 'output-context'); - // } - - push($context, $new); - return $context - } - - $length = length($context); - $has-expect = index($context, 'expect') || index($context, 'contains'); - $has-both = index($context, 'output') && $has-expect; - - // if ($length != 3 || !$has-both) { - // $required = 'one `output()`, and one `expect()` or `contains()`'; - // $error = 'Each `assert()` must contain %s' % $required; - - // return _true-error($error, 'output-context'); - // } - - return (); -} - -// _true-context($scope) -// -// **[private:{string}]** Get information on current context for a given scope -// -// Weight: 0 -// -// $scope - **{string}** ***Scope to search for*** -// -// Styleguide Functions._true-context -_true-context($scope) { - $value = null; - - for $entry in ($_true-context.buffer) { - $entries = split('|', $entry); - - $entry-scope = $entries[0]; - $entry-value = $entries[1]; - } - - if ($entry-scope == $scope) { - $value = $entry-value; - } - - return $value; -} - -// _true-context-all($scope) -// -// **[private:{list}]** Get list of context names for a given scope -// -// Weight: 0 -// -// $scope - **{string}** ***Scope to search for*** -// -// Styleguide Functions._true-context-all -_true-context-all($scope) { - $list = (); - - for $entry in ($_true-context.buffer) { - $entries = split('|', $entry); - - $entry-scope = $entries[0]; - $entry-value = $entries[1]; - - if ($entry-scope == $scope) { - push($list, $entry-value); - } - } - - return $list; -} +// unwrap-list($list) +// +// **[private:{list}]** Transforms a wrapped list into a unwrapped one +// +// Weight: 0 +// +// $list - **{list}** ***List to be unwrapped*** +// +// Styleguide Functions.unwrap-list +use('../../lib/unwrap-list.js'); + +// $_true-context = { buffer } +// +// **[private]** Stores the current module/test/assertion context stack +// +// Weight: 0 +// +// $buffer = () - **{list}** ***List to use as buffer for parsing*** +// +// Styleguide Variables.$_true-context +$_true-context = { + buffer: () +}; + +// _true-context-mixin($scope, $name) +// +// **[private:{void}]** Update the current context for a given scope +// +// Weight: 0 +// +// $scope - **{string}** ***Either `module`, `test` or `assert`*** +// $name - **{string}** ***Name or description of the current scope*** +// +// Styleguide Functions._true-context-mixin +_true-context-mixin($scope, $name) { + push($_true-context.buffer, '%s|%s' % (unquote($scope) unquote($name))); + + $_true-context.buffer = unwrap-list($_true-context.buffer); +} + +// _true-context-pop($type) +// +// **[private:{void}]** Remove the deepest context layer from `$_true-context.buffer` +// +// Weight: 0 +// +// Styleguide Functions._true-output-pop +_true-context-pop($type = null) { + $new = (); + + if ($type == null) { + for $i in 0 .. (length($_true-context.buffer) - 1) { + push($new, $_true-context.buffer[$i]); + } + + $_true-context.buffer = $new; + } else { + $_true-context.buffer = (); + } +} + +$_true-output-context = { + value: () +}; + +// _true-output-context($new, $context) +// +// **[private:{void}]** Add `assert`, `output`, `expect`, or `contains` context to an output test, or check to make sure they all exist before resetting the context. +// +// Weight: 0 +// +// $new - **{'assert'|'output'|'expect'|'contains'|null}** ***Add a new `assert`, `output`, `expect`, or `contains` layer to the context of an output-test, or use `null` to check that all context is properly formed and then reset it at the end of a test*** +// $context = $_true-output-context.value - **{list}** ***The current output context*** +// +// Styleguide Functions._true-output-context +_true-output-context($new, $context = $_true-output-context.value) { + $valid = 'assert' 'expect' 'output' 'contains'; + + $_true-output-context.value = _true-validate-output-context($new, $context); +} + +// _true-validate-output-context($new, $context) +// +// **[private:{string}]** Validate the new context, and return an updated context value +// +// Weight: 0 +// +// $new - **{'assert'|'output'|'expect'|'contains'|null}** ***Add a new `assert`, `output`, `expect`, or `contains` layer to the context of an output-test, or use `null` to check that all context is properly formed and then reset it at the end of a test*** +// $context = $_true-output-context.value - **{list}** ***The current output context*** +// +// Styleguide Functions._true-validate-output-context +_true-validate-output-context($new, $context = $_true-output-context.value) { + $valid = 'assert' 'expect' 'output' 'contains'; + + $validIndex = index($valid, $new); + $contextIndex = index($context, $new); + $assertIndex = index($context, 'assert') + + if ($new && $validIndex == null || $validIndex < 0 ) { + $error = $new + ' is not a valid context for output tests: ' + $valid; + + return _true-error($error, 'output-context'); + } else if ($contextIndex != null && $contextIndex >= 0 ) { + if ($new == 'assert') { + $error = 'The `assert()` mixin can not contain another `assert()`'; + + return _true-error($error, 'output-context'); + } + + $error = 'The `%s()` mixin must only be used once per `assert()`' % unquote($new); + + return _true-error($error, 'output-context'); + } else if ($new) { + $is-sub = index('expect' 'output' 'contains', $new); + $is-sub = $is-sub != null && $is-sub >= 0; + + // if ($is-sub && !($assertIndex != null && $assertIndex >= 0)) { + // $error = 'The `assert()` wrapper is required'; + + // return _true-error($error, 'output-context'); + // } + + push($context, $new); + return $context + } + + $length = length($context); + $has-expect = index($context, 'expect') || index($context, 'contains'); + $has-both = index($context, 'output') && $has-expect; + + // if ($length != 3 || !$has-both) { + // $required = 'one `output()`, and one `expect()` or `contains()`'; + // $error = 'Each `assert()` must contain %s' % $required; + + // return _true-error($error, 'output-context'); + // } + + return (); +} + +// _true-context($scope) +// +// **[private:{string}]** Get information on current context for a given scope +// +// Weight: 0 +// +// $scope - **{string}** ***Scope to search for*** +// +// Styleguide Functions._true-context +_true-context($scope) { + $value = null; + + for $entry in ($_true-context.buffer) { + $entries = split('|', $entry); + + $entry-scope = $entries[0]; + $entry-value = $entries[1]; + } + + if ($entry-scope == $scope) { + $value = $entry-value; + } + + return $value; +} + +// _true-context-all($scope) +// +// **[private:{list}]** Get list of context names for a given scope +// +// Weight: 0 +// +// $scope - **{string}** ***Scope to search for*** +// +// Styleguide Functions._true-context-all +_true-context-all($scope) { + $list = (); + + for $entry in ($_true-context.buffer) { + $entries = split('|', $entry); + + $entry-scope = $entries[0]; + $entry-value = $entries[1]; + + if ($entry-scope == $scope) { + push($list, $entry-value); + } + } + + return $list; +} diff --git a/styl/true/_messages.styl b/styl/true/_messages.styl index 1bef853..ae2a309 100644 --- a/styl/true/_messages.styl +++ b/styl/true/_messages.styl @@ -1,65 +1,65 @@ -// stdout($string, $type) -// -// **[private:{output}]** Output to terminal -// -// Weight: 0 -// -// $string - **{string}** ***Text to output to terminal*** -// $type - **{'debug'|'warn'|'error'}** ***Type of output*** -// -// Styleguide Functions.stdout -use('lib/stdout.js'); - -// comment($string) -// -// **[private:{output}]** Output a message to CSS comments -// -// Weight: -10 -// -// $string - **{string}** ***Message to output*** -// -// Styleguide Mixins.comment -comment($string) { - unquote('/* ' + replace('(?![\t ])\s\s*', '\n * ', $string) + ' */'); -} - -// _true-message($message, $output, $comment-padding) -// -// **[private:{output}]** Output a message to CSS comments, or commandline terminal (via debug/warn) -// -// Weight: 0 -// -// $message - **{string}** ***Message to output*** -// $output = 'comments' - **{string}** ***Type of output, either `comments`, `terminal`, `debug` or `warn`*** -// -// Styleguide Mixins._true-message -_true-message($message, $output = 'comments', $comment-padding = 0) { - $pad = ''; - - if ($comment-padding > 0) { - for $i in ((0)..(($comment-padding) - 1)) { - $pad = $pad + ' '; - } - } - - for $line in ($message) { - $comments = index($output, 'comments'); - - if ($comments != null && $comments >= 0) { - $tmp = $pad + $line; - - comment($tmp); - } - - $debug = index($output, 'debug'); - $terminal = index($output, 'terminal'); - if (($debug != null && $debug >= 0) || ($terminal != null && $terminal >= 0)) { - stdout($line); - } - - $warn = index($output, 'warn'); - if ($warn != null && $warn >= 0) { - stdout($line, 'warn'); - } - } -} +// stdout($string, $type) +// +// **[private:{output}]** Output to terminal +// +// Weight: 0 +// +// $string - **{string}** ***Text to output to terminal*** +// $type - **{'debug'|'warn'|'error'}** ***Type of output*** +// +// Styleguide Functions.stdout +use('../../lib/stdout.js'); + +// comment($string) +// +// **[private:{output}]** Output a message to CSS comments +// +// Weight: -10 +// +// $string - **{string}** ***Message to output*** +// +// Styleguide Mixins.comment +comment($string) { + unquote('/* ' + replace('(?![\t ])\s\s*', '\n * ', $string) + ' */'); +} + +// _true-message($message, $output, $comment-padding) +// +// **[private:{output}]** Output a message to CSS comments, or commandline terminal (via debug/warn) +// +// Weight: 0 +// +// $message - **{string}** ***Message to output*** +// $output = 'comments' - **{string}** ***Type of output, either `comments`, `terminal`, `debug` or `warn`*** +// +// Styleguide Mixins._true-message +_true-message($message, $output = 'comments', $comment-padding = 0) { + $pad = ''; + + if ($comment-padding > 0) { + for $i in ((0)..(($comment-padding) - 1)) { + $pad = $pad + ' '; + } + } + + for $line in ($message) { + $comments = index($output, 'comments'); + + if ($comments != null && $comments >= 0) { + $tmp = $pad + $line; + + comment($tmp); + } + + $debug = index($output, 'debug'); + $terminal = index($output, 'terminal'); + if (($debug != null && $debug >= 0) || ($terminal != null && $terminal >= 0)) { + stdout($line); + } + + $warn = index($output, 'warn'); + if ($warn != null && $warn >= 0) { + stdout($line, 'warn'); + } + } +} diff --git a/styl/true/_modules.styl b/styl/true/_modules.styl index 45deed5..6f20c66 100644 --- a/styl/true/_modules.styl +++ b/styl/true/_modules.styl @@ -1,153 +1,153 @@ -// str-length($list) -// -// **[private:{number|'NOT_A_STRING'}]** Return the desired string length -// -// Weight: 0 -// -// $list - **{list}** ***string to check length*** -// -// Styleguide Functions.str-length -use('lib/str-length.js'); - -// arrange-test-list($test-list) -// -// **[private:{void}]** Fix the test list order to work with currently used order -// -// Weight: 0 -// -// $test-list - **{list}** ***List to reorganize*** -// -// Styleguide Functions.arrange-test-list -use('lib/arrange-test-list.js'); - -// test-module($name) -// -// **[public:{void}]** Test Modules are optional, and can be used to group tests and other modules for organizational purposes. -// -// Weight: -10 -// -// Parameters: -// -// -// ~ -// -// **Usage:** -// ```stylus -// +test-module('zip [function]') { -// // Test 1 -// +test('Returns two lists zipped together') { -// assert-equal( -// zip(a b c, 1 2 3), -// (a 1, b 2, c 3) -// ); -// } - -// // Test 2 -// +test('Returns three zipped lists') { -// assert-equal( -// zip(1px 1px 3px, solid dashed solid, red green blue), -// (1px solid red, 1px dashed green, 3px solid blue) -// ); -// } -// } -// ``` -// -// Styleguide Mixins.test-module -test-module($name) { - _true-module-start($name); - - {block}; - - _true-module-stop(); -} - -// describe($name) -// -// **[public:{void}]** Describe the unit to be tested. This works just like a test module, allowing you to group one or more related tests. -// -// Weight: -10 -// -// Parameters: -// -// -// ~ -// -// **Usage:** -// ```stylus -// +describe('zip [function]') { -// // Test 1 -// +it('Returns two lists zipped together') { -// assert-equal( -// zip(a b c, 1 2 3), -// (a 1, b 2, c 3) -// ); -// } - -// // Test 2 -// +it('Returns three zipped lists') { -// assert-equal( -// zip(1px 1px 3px, solid dashed solid, red green blue), -// (1px solid red, 1px dashed green, 3px solid blue) -// ); -// } -// } -// ``` -// -// Styleguide Mixins.describe -describe($name) { - +test-module($name) { - {block}; - } -} - -// _true-module-start($name) -// -// **[private:{output}]** Module start helper -// -// Weight: 0 -// -// $name - **{string}** ***Module name*** -// -// Styleguide Mixins._true-module-start -_true-module-start($name) { - _true-context-mixin(module, $name); - $_true-context.buffer = arrange-test-list($_true-context.buffer); - $module-list = _true-context-all('module'); - - $modules = $module-list[0]; - $length = length($module-list); - - // if ($length > 1) { - // for $i in ((2)..($length)) { - // $modules = $modules + ' :: ' + $module-list[$i]; - // } - // } - - _true-message('# Module: %s' % unquote($modules), 'comments'); - $underline = '----------'; - - for $i in ((0)..(str-length(unquote($modules)) - 1)) { - $underline = '%s-' % unquote($underline); - } - - _true-message($underline, 'comments'); -} - -// _true-module-stop() -// -// **[private:{output}]** Module stop helper -// -// Weight: 0 -// -// Styleguide Mixins._true-module-stop -_true-module-stop() { - _true-update-stats-count('modules'); - // _true-context-pop('modules') - _true-message('', 'comments'); -} +// str-length($list) +// +// **[private:{number|'NOT_A_STRING'}]** Return the desired string length +// +// Weight: 0 +// +// $list - **{list}** ***string to check length*** +// +// Styleguide Functions.str-length +use('../../lib/str-length.js'); + +// arrange-test-list($test-list) +// +// **[private:{void}]** Fix the test list order to work with currently used order +// +// Weight: 0 +// +// $test-list - **{list}** ***List to reorganize*** +// +// Styleguide Functions.arrange-test-list +use('../../lib/arrange-test-list.js'); + +// test-module($name) +// +// **[public:{void}]** Test Modules are optional, and can be used to group tests and other modules for organizational purposes. +// +// Weight: -10 +// +// Parameters: +// +// +// ~ +// +// **Usage:** +// ```stylus +// +test-module('zip [function]') { +// // Test 1 +// +test('Returns two lists zipped together') { +// assert-equal( +// zip(a b c, 1 2 3), +// (a 1, b 2, c 3) +// ); +// } + +// // Test 2 +// +test('Returns three zipped lists') { +// assert-equal( +// zip(1px 1px 3px, solid dashed solid, red green blue), +// (1px solid red, 1px dashed green, 3px solid blue) +// ); +// } +// } +// ``` +// +// Styleguide Mixins.test-module +test-module($name) { + _true-module-start($name); + + {block}; + + _true-module-stop(); +} + +// describe($name) +// +// **[public:{void}]** Describe the unit to be tested. This works just like a test module, allowing you to group one or more related tests. +// +// Weight: -10 +// +// Parameters: +// +// +// ~ +// +// **Usage:** +// ```stylus +// +describe('zip [function]') { +// // Test 1 +// +it('Returns two lists zipped together') { +// assert-equal( +// zip(a b c, 1 2 3), +// (a 1, b 2, c 3) +// ); +// } + +// // Test 2 +// +it('Returns three zipped lists') { +// assert-equal( +// zip(1px 1px 3px, solid dashed solid, red green blue), +// (1px solid red, 1px dashed green, 3px solid blue) +// ); +// } +// } +// ``` +// +// Styleguide Mixins.describe +describe($name) { + +test-module($name) { + {block}; + } +} + +// _true-module-start($name) +// +// **[private:{output}]** Module start helper +// +// Weight: 0 +// +// $name - **{string}** ***Module name*** +// +// Styleguide Mixins._true-module-start +_true-module-start($name) { + _true-context-mixin(module, $name); + $_true-context.buffer = arrange-test-list($_true-context.buffer); + $module-list = _true-context-all('module'); + + $modules = $module-list[0]; + $length = length($module-list); + + // if ($length > 1) { + // for $i in ((2)..($length)) { + // $modules = $modules + ' :: ' + $module-list[$i]; + // } + // } + + _true-message('# Module: %s' % unquote($modules), 'comments'); + $underline = '----------'; + + for $i in ((0)..(str-length(unquote($modules)) - 1)) { + $underline = '%s-' % unquote($underline); + } + + _true-message($underline, 'comments'); +} + +// _true-module-stop() +// +// **[private:{output}]** Module stop helper +// +// Weight: 0 +// +// Styleguide Mixins._true-module-stop +_true-module-stop() { + _true-update-stats-count('modules'); + // _true-context-pop('modules') + _true-message('', 'comments'); +} diff --git a/styl/true/_output.styl b/styl/true/_output.styl index d5be01b..3b34b26 100644 --- a/styl/true/_output.styl +++ b/styl/true/_output.styl @@ -1,200 +1,200 @@ -use('lib/str-length.js'); - -// _true-pass-details() -// -// **[private:{output}]** Ouptut a success message for passing tests -// -// Weight: 0 -// -// Styleguide Mixins._true-pass-details -_true-pass-details() { - $assertion = _true-context('assert'); - $message = '✔ %s' % unquote($assertion); - _true-message($message, 'comments', 2); -} - -// _true-fail-details($assert, $expected, $terminal) -// -// **[private:{output}]** Failure message, with appropriate details to help you debug various common problems. -// -// Weight: 0 -// -// $assert - **{any}** ***The assertion value*** -// $expected - **{any}** ***The expected value*** -// $terminal = $true-terminal-output.value - **{boolean}** ***Whether to use the terminal as an output stream*** -// -// Styleguide Mixins._true-fail-details -_true-fail-details($assert, $expected, $terminal = $true-terminal-output.value) { - $list = 'comments', 'debug'; - $location = $terminal ? $list : 'comments'; - - // Title Messages - $assertion = _true-context('assert'); - $string = typeof($assertion) == 'string' ? unquote($assertion) : $assertion; - $title = 'FAILED: %s' % $string; - $message = '✖ %s' % $title; - _true-message($message, $location, 2); - - // Details Message - $out = _true-variable-details($assert); - $exp = _true-variable-details($expected); - - $details = '- Output: %s' % $out, '- Expected: %s' % $exp; - _true-message($details, $location, 4); - - // Edge Failure Notes - - $assert-equal = index($assertion, '[assert-equal]'); - if ($assert-equal != null && $assert-equal >= 0) { - $notes = _true-edgefail-notes($assert, $expected); - if ($notes) { - _true-message($notes, $location, 4); - } - } - - // Context Message - // $module = _true-context('module'); - // $test = _true-context('test'); - // $context = '- Module: %s' % $module, '- Test: %s' % $test; - // _true-message($context, $location, 4); - - // Terminal Warning - if ($terminal) { - _true-message($assertion, 'warn'); - } -} - -// _true-variable-details($var) -// -// **[private:{string}]** Provide the details (type, list-separator, quotation) for a given variable - used to provide context in failure reporting. -// -// Weight: 0 -// -// $var - **{any}** ***Pass in asserted and expected values individually to retrieve comparable details for both*** -// -// Styleguide Functions._true-variable-details -_true-variable-details($var) { - $inspect = s('%s' % $var); - $type = type-of($var); - - if (is-list($var)) { - $inspect = unquote('' + $var + ''); - $inspect = s('%s' % ($inspect)); - $separator = list-separator($var); - $buffer = ''; - - if (unquote($separator) == unquote(',')) { - $separator = comma; - - for $line in (arguments) { - $buffer = $buffer + $line + list-separator($var) + ' '; - } - - $inspect = substr($buffer, 0, (str-length($buffer) - 2)); - } - - if (unquote($separator) == unquote(' ')) { - $separator = space; - } - - $type = '%s-list' % $separator; - } - - if ($type == 'string') { - if ($var != unquote($var)) { - $type = 'quoted-%s' % unquote($type); - } - - return '`[' + unquote($type) + '] %s`' % $inspect; - } - - $return = '[' + $type + '] ' + $inspect; - return $return; -} - -// _true-edgefail-notes($one, $two) -// -// **[private:{null|string}]** There are some common test failures that can be confusing, where results look identical in the output, but represent different values internally. This function looks for those edge-case failures and adds a clarifying note in the results. -// -// Weight: 0 -// -// $one - **{any}** ***One of the values being compared*** -// $two - **{any}** ***The other calue being compared*** -// -// Styleguide Functions._true-edgefail-notes -_true-edgefail-notes($lists...) { - $one = arguments[0]; - $two = arguments[1]; - $one-type = type-of($one); - $two-type = type-of($two); - - if (is-list($one)) { - $one-type = 'list' - } - - if (is-list($two)) { - $two-type = 'list' - } - - $note = null; - $pre = '- Details: '; - $inspect = '(set `$inspect: true` to compare output values)'; - - $test-string = 'test'; - // List Separators - if (is-list($one) && is-list($two)) { - if (join(', ', $one, $test-string) == join(', ', $two, $test-string)) { - $message = 'list-separators do not match'; - $note = $pre + $message; - } - } - - // String Quotes - if (($one-type == 'string' && $two-type == 'string') && (!is-list($one) && !is-list($two))) { - if (unquote($one) == unquote($two)) { - $message = 'string quotations do not match'; - $note = $pre + $message; - } - } - - $one = $one-type == 'string' ? unquote($one) : $one; - $two = $two-type == 'string' ? unquote($two) : $two; - - if (is-list($one)) { - $str = '' + $one + '' - $one = s('%s' % unquote($str)); - } - - if (is-list($two)) { - $str = '' + $two + '' - $two = s('%s' % unquote($str)); - } - - if (s('%s' % $one) == s('%s' % $two)) { - $number = false; - - // Type - if ($one-type != $two-type) { - $message = 'variable types do not match'; - $note = $pre + $message + ' ' + $inspect; - } - - // Rounding - $unit = $one-type == 'unit' && $two-type == 'unit'; - $string = $one-type == 'string' && $two-type == 'string'; - $number = $unit && !$string ? (unit($one) == '' && unit($two) == '') : false - $color = $one-type == 'rgba' && $two-type == 'rgba'; - if ($number or $color) { - $type = $unit ? numbers : colors; - $message = '%s may need to be rounded before comparison' % $type; - $note = $pre + $message + ' ' + $inspect; - } - - // Catch-All (I think this may not be currently possible) - if (!$note) { - $note = $pre + $inspect; - } - } - - return $note; -} +use('../../lib/str-length.js'); + +// _true-pass-details() +// +// **[private:{output}]** Ouptut a success message for passing tests +// +// Weight: 0 +// +// Styleguide Mixins._true-pass-details +_true-pass-details() { + $assertion = _true-context('assert'); + $message = '✔ %s' % unquote($assertion); + _true-message($message, 'comments', 2); +} + +// _true-fail-details($assert, $expected, $terminal) +// +// **[private:{output}]** Failure message, with appropriate details to help you debug various common problems. +// +// Weight: 0 +// +// $assert - **{any}** ***The assertion value*** +// $expected - **{any}** ***The expected value*** +// $terminal = $true-terminal-output.value - **{boolean}** ***Whether to use the terminal as an output stream*** +// +// Styleguide Mixins._true-fail-details +_true-fail-details($assert, $expected, $terminal = $true-terminal-output.value) { + $list = 'comments', 'debug'; + $location = $terminal ? $list : 'comments'; + + // Title Messages + $assertion = _true-context('assert'); + $string = typeof($assertion) == 'string' ? unquote($assertion) : $assertion; + $title = 'FAILED: %s' % $string; + $message = '✖ %s' % $title; + _true-message($message, $location, 2); + + // Details Message + $out = _true-variable-details($assert); + $exp = _true-variable-details($expected); + + $details = '- Output: %s' % $out, '- Expected: %s' % $exp; + _true-message($details, $location, 4); + + // Edge Failure Notes + + $assert-equal = index($assertion, '[assert-equal]'); + if ($assert-equal != null && $assert-equal >= 0) { + $notes = _true-edgefail-notes($assert, $expected); + if ($notes) { + _true-message($notes, $location, 4); + } + } + + // Context Message + // $module = _true-context('module'); + // $test = _true-context('test'); + // $context = '- Module: %s' % $module, '- Test: %s' % $test; + // _true-message($context, $location, 4); + + // Terminal Warning + if ($terminal) { + _true-message($assertion, 'warn'); + } +} + +// _true-variable-details($var) +// +// **[private:{string}]** Provide the details (type, list-separator, quotation) for a given variable - used to provide context in failure reporting. +// +// Weight: 0 +// +// $var - **{any}** ***Pass in asserted and expected values individually to retrieve comparable details for both*** +// +// Styleguide Functions._true-variable-details +_true-variable-details($var) { + $inspect = s('%s' % $var); + $type = type-of($var); + + if (is-list($var)) { + $inspect = unquote('' + $var + ''); + $inspect = s('%s' % ($inspect)); + $separator = list-separator($var); + $buffer = ''; + + if (unquote($separator) == unquote(',')) { + $separator = comma; + + for $line in (arguments) { + $buffer = $buffer + $line + list-separator($var) + ' '; + } + + $inspect = substr($buffer, 0, (str-length($buffer) - 2)); + } + + if (unquote($separator) == unquote(' ')) { + $separator = space; + } + + $type = '%s-list' % $separator; + } + + if ($type == 'string') { + if ($var != unquote($var)) { + $type = 'quoted-%s' % unquote($type); + } + + return '`[' + unquote($type) + '] %s`' % $inspect; + } + + $return = '[' + $type + '] ' + $inspect; + return $return; +} + +// _true-edgefail-notes($one, $two) +// +// **[private:{null|string}]** There are some common test failures that can be confusing, where results look identical in the output, but represent different values internally. This function looks for those edge-case failures and adds a clarifying note in the results. +// +// Weight: 0 +// +// $one - **{any}** ***One of the values being compared*** +// $two - **{any}** ***The other calue being compared*** +// +// Styleguide Functions._true-edgefail-notes +_true-edgefail-notes($lists...) { + $one = arguments[0]; + $two = arguments[1]; + $one-type = type-of($one); + $two-type = type-of($two); + + if (is-list($one)) { + $one-type = 'list' + } + + if (is-list($two)) { + $two-type = 'list' + } + + $note = null; + $pre = '- Details: '; + $inspect = '(set `$inspect: true` to compare output values)'; + + $test-string = 'test'; + // List Separators + if (is-list($one) && is-list($two)) { + if (join(', ', $one, $test-string) == join(', ', $two, $test-string)) { + $message = 'list-separators do not match'; + $note = $pre + $message; + } + } + + // String Quotes + if (($one-type == 'string' && $two-type == 'string') && (!is-list($one) && !is-list($two))) { + if (unquote($one) == unquote($two)) { + $message = 'string quotations do not match'; + $note = $pre + $message; + } + } + + $one = $one-type == 'string' ? unquote($one) : $one; + $two = $two-type == 'string' ? unquote($two) : $two; + + if (is-list($one)) { + $str = '' + $one + '' + $one = s('%s' % unquote($str)); + } + + if (is-list($two)) { + $str = '' + $two + '' + $two = s('%s' % unquote($str)); + } + + if (s('%s' % $one) == s('%s' % $two)) { + $number = false; + + // Type + if ($one-type != $two-type) { + $message = 'variable types do not match'; + $note = $pre + $message + ' ' + $inspect; + } + + // Rounding + $unit = $one-type == 'unit' && $two-type == 'unit'; + $string = $one-type == 'string' && $two-type == 'string'; + $number = $unit && !$string ? (unit($one) == '' && unit($two) == '') : false + $color = $one-type == 'rgba' && $two-type == 'rgba'; + if ($number or $color) { + $type = $unit ? numbers : colors; + $message = '%s may need to be rounded before comparison' % $type; + $note = $pre + $message + ' ' + $inspect; + } + + // Catch-All (I think this may not be currently possible) + if (!$note) { + $note = $pre + $inspect; + } + } + + return $note; +} diff --git a/styl/true/_results.styl b/styl/true/_results.styl index 4bb7ec1..70e0416 100644 --- a/styl/true/_results.styl +++ b/styl/true/_results.styl @@ -1,150 +1,150 @@ -use('lib/str-length.js') -// _true-get-result($assert, $expected, $unequal) -// -// **[private:{'pass' | 'fail'}]** Compare two values, and return a `pass` or `fail` result. -// -// Weight: 0 -// -// $assert - **{any}** ***Value to consider*** -// $expected - **{any}** ***Expected match*** -// $unequal = false - **{boolean}** ***Set to `true` if the comparison is expected to fail*** -// -// Styleguide Functions._true-get-result -_true-get-result($assert, $expected, $unequal = false) { - $equal = $assert == $expected; - $pass = $unequal ? !$equal : $equal; - - return $pass ? 'pass' : 'fail'; -} - -// $_true-results = { value } -// -// **[private]** Global test-results map -// -// Weight: 0 -// -// $value = { 'run': 0, 'pass': 0, 'fail': 0, 'output-to-css': 0 } - **{boolean}** ***Enable or disables terminal report while compiling to css*** -// -// Styleguide Variables.$_true-results -$_true-results = { - value: { - 'run': 0, - 'pass': 0, - 'fail': 0, - 'output-to-css': 0 - } -} - -// _true-update($result) -// -// **[private:{void}]** Update global results data -// -// Weight: 0 -// -// $result - **{'pass'|'fail'|'output-to-css' }** **The current status to update global results** -// -// Styleguide Functions._true-update -_true-update($result) { - $update = { - 'run': 1 - }; - - $successful = true; - - if (str-length($map.asserts) == 'NOT_A_STRING') { - for $i in ((1)..(length($map.asserts) - 1)) { - if ($map.asserts[$i] == 'output-to-css' || $successful == 'output-to-css') { - $successful = 'output-to-css'; - } else { - $successful = $successful && $map.asserts[$i] == 'pass'; - } - } - } - - if ($successful == 'output-to-css') { - $result = 'output-to-css'; - } else if (length($map.asserts) == 0) { - $result = $result; - } else { - $result = $successful ? 'pass' : 'fail'; - } - - $update[$result] = 1; - $_true-results.value = _true-map-increment($_true-results.value, $update); - - $map.asserts = (); -} - -// $_true-test-result = { value } -// -// **[private]** Local flags for tracking assertion results in a test. -// -// Weight: 0 -// -// $value = null - **{boolean}** ***Enable or disables assertion reports*** -// -// Styleguide Variables.$_true-test-result -$_true-test-result = { - value: null -} - -// _true-update-test($result) -// -// **[private:{void}]** Update test result flag with new data -// -// Weight: 0 -// -// $result - **{'pass'|'fail'|'output-to-css'}** ***The current status to update test stats*** -// -// Styleguide Functions._true-update-test -_true-update-test($result) { - push($map.asserts, $result); - - if ($result == 'fail' || $_true-test-result.value == 'fail') { - $_true-test-result.value = 'fail'; - } else if ($_true-test-result.value != 'output-to-css') { - $_true-test-result.value = $result; - } -} - -// _true-results-message($linebreak, $results) -// -// **[private:{string}]** Report message -// -// Weight: 0 -// -// $linebreak = false - **{boolean}** ***Return message either as a single line or in multiple lines*** -// $results = $_true-results.value - **{hash}** ***A map of run, pass, fail, and output-to-css results*** -// -// Styleguide Functions._true-results-message -_true-results-message($linebreak = false, $results = $_true-results.value) { - $run = $results.run; - $pass = $results.pass; - $fail = $results.fail; - $output-to-css = $results.output-to-css; - - $items = $run == 1 ? 'Test' : 'Tests'; - $items = '%s %s' % ($run unquote($items)); - $passed = '%s Passed' % ($pass); - $failed = '%s Failed' % ($fail); - $compiled = $output-to-css > 0 ? '%s Output to CSS' % $output-to-css : false; - - // Linebreaks - if ($linebreak) { - $message = '\n%s:' % $items, '\n- %s' % $passed, '\n- %s' % $failed; - - if ($compiled) { - push($message, '\n- %s' % $compiled); - } - - return $message; - } - - // No Linebreaks - $message = '%s, ' % $items; - $message = $message + '%s, ' % $passed; - $message = $message + '%s' % $failed; - $message = $compiled ? $message + ', %s' % $compiled : $message; - - return $message; -} +use('../../lib/str-length.js') +// _true-get-result($assert, $expected, $unequal) +// +// **[private:{'pass' | 'fail'}]** Compare two values, and return a `pass` or `fail` result. +// +// Weight: 0 +// +// $assert - **{any}** ***Value to consider*** +// $expected - **{any}** ***Expected match*** +// $unequal = false - **{boolean}** ***Set to `true` if the comparison is expected to fail*** +// +// Styleguide Functions._true-get-result +_true-get-result($assert, $expected, $unequal = false) { + $equal = $assert == $expected; + $pass = $unequal ? !$equal : $equal; + + return $pass ? 'pass' : 'fail'; +} + +// $_true-results = { value } +// +// **[private]** Global test-results map +// +// Weight: 0 +// +// $value = { 'run': 0, 'pass': 0, 'fail': 0, 'output-to-css': 0 } - **{boolean}** ***Enable or disables terminal report while compiling to css*** +// +// Styleguide Variables.$_true-results +$_true-results = { + value: { + 'run': 0, + 'pass': 0, + 'fail': 0, + 'output-to-css': 0 + } +} + +// _true-update($result) +// +// **[private:{void}]** Update global results data +// +// Weight: 0 +// +// $result - **{'pass'|'fail'|'output-to-css' }** **The current status to update global results** +// +// Styleguide Functions._true-update +_true-update($result) { + $update = { + 'run': 1 + }; + + $successful = true; + + if (str-length($map.asserts) == 'NOT_A_STRING') { + for $i in ((1)..(length($map.asserts) - 1)) { + if ($map.asserts[$i] == 'output-to-css' || $successful == 'output-to-css') { + $successful = 'output-to-css'; + } else { + $successful = $successful && $map.asserts[$i] == 'pass'; + } + } + } + + if ($successful == 'output-to-css') { + $result = 'output-to-css'; + } else if (length($map.asserts) == 0) { + $result = $result; + } else { + $result = $successful ? 'pass' : 'fail'; + } + + $update[$result] = 1; + $_true-results.value = _true-map-increment($_true-results.value, $update); + + $map.asserts = (); +} + +// $_true-test-result = { value } +// +// **[private]** Local flags for tracking assertion results in a test. +// +// Weight: 0 +// +// $value = null - **{boolean}** ***Enable or disables assertion reports*** +// +// Styleguide Variables.$_true-test-result +$_true-test-result = { + value: null +} + +// _true-update-test($result) +// +// **[private:{void}]** Update test result flag with new data +// +// Weight: 0 +// +// $result - **{'pass'|'fail'|'output-to-css'}** ***The current status to update test stats*** +// +// Styleguide Functions._true-update-test +_true-update-test($result) { + push($map.asserts, $result); + + if ($result == 'fail' || $_true-test-result.value == 'fail') { + $_true-test-result.value = 'fail'; + } else if ($_true-test-result.value != 'output-to-css') { + $_true-test-result.value = $result; + } +} + +// _true-results-message($linebreak, $results) +// +// **[private:{string}]** Report message +// +// Weight: 0 +// +// $linebreak = false - **{boolean}** ***Return message either as a single line or in multiple lines*** +// $results = $_true-results.value - **{hash}** ***A map of run, pass, fail, and output-to-css results*** +// +// Styleguide Functions._true-results-message +_true-results-message($linebreak = false, $results = $_true-results.value) { + $run = $results.run; + $pass = $results.pass; + $fail = $results.fail; + $output-to-css = $results.output-to-css; + + $items = $run == 1 ? 'Test' : 'Tests'; + $items = '%s %s' % ($run unquote($items)); + $passed = '%s Passed' % ($pass); + $failed = '%s Failed' % ($fail); + $compiled = $output-to-css > 0 ? '%s Output to CSS' % $output-to-css : false; + + // Linebreaks + if ($linebreak) { + $message = '\n%s:' % $items, '\n- %s' % $passed, '\n- %s' % $failed; + + if ($compiled) { + push($message, '\n- %s' % $compiled); + } + + return $message; + } + + // No Linebreaks + $message = '%s, ' % $items; + $message = $message + '%s, ' % $passed; + $message = $message + '%s' % $failed; + $message = $compiled ? $message + ', %s' % $compiled : $message; + + return $message; +} diff --git a/styl/true/_utilities.styl b/styl/true/_utilities.styl index 7c89d73..0240a42 100644 --- a/styl/true/_utilities.styl +++ b/styl/true/_utilities.styl @@ -1,156 +1,156 @@ -use('lib/str-length.js'); - -// map-keys($hash) -// -// **[private:{list}]** Returns a list with only the keys of the selected hash -// -// Weight: 0 -// -// $hash - **{hash}** ***Hash to extract the keys from*** -// -// Styleguide Functions.map-keys -use('lib/map-keys.js'); - -// $_true-error-output-override = { value } -// -// **[public]** Value key stores the desired value -// -// Weight: -10 -// -// $value = true - **{boolean}** ***The actual output override value*** -// -// Styleguide Variables.$_true-error-output-override -$_true-error-output-override = { - value: true -}; - -// is-list($list) -// -// **[private:{boolean}]** Returns whether an argument is a list or not -// -// Weight: 0 -// -// $list - **{list}** ***The list to analyze*** -// -// Styleguide Functions.is-list -is-list() { - // arguments is injected by stylus - if (type(arguments) == 'object') { - return type(keys(arguments)[0]) == 'object'; - } else { - return str-length(arguments) == 'NOT_A_STRING' && length(arguments) > 1 && type(arguments) != 'rgba'; - } -} - -// _true-error($message, $source, $override) -// -// **[private:{void|string}]** Throw or returns an error with a message detailing the source and error -// -// Weight: 0 -// -// $message - **{string}** ***The error to report*** -// $source - **{string}** ***The source of the error*** -// $override = $_true-error-output-override.value - **{boolean}** ***Optionally override error-output for testing failure-cases*** -// -// Styleguide Functions._true-error -_true-error($message, $source, $override = $_true-error-output-override.value) { - $error = 'ERROR [' + $source + '] ' + $message; - - if ($override) { - return $error; - } - - $error = '' + $error + ''; - error($error); -} - -// _true-error-mixin($message, $source, $override) -// -// **[private:{void}]** Outputs an error with a message detailing the source and error -// -// Weight: 0 -// -// $message - **{string}** ***The error to report*** -// $source - **{string}** ***The source of the error*** -// $override = $_true-error-output-override.value - **{boolean}** ***Optionally override error-output for testing failure-cases*** -// -// Styleguide Mixins._true-error-mixin -_true-error-mixin($message, $source, $override = $_true-error-output-override.value) { - $error = 'ERROR [' + $source + '] ' + $message; - - if ($override) { - _true-message($error, 'comments'); - } else { - error($error); - } -} - - -// _true-map-increment($base, $add) -// -// **[private:{string}]** Add hash values together -// -// Weight: 0 -// -// $base - **{string}** ***Initial map to add values to*** -// $add - **{string}** ***Map of values to be added*** -// -// Styleguide Functions._true-map-increment -_true-map-increment($base, $add) { - for $key in (map-keys($add)) { - $value = $add[$key]; - - if ($value) { - $base-value = $base[$key]; - $new-value = $base-value ? ($base-value + $value) : $value; - $base[$key] = $new-value; - } - } - - return $base; -} - -// _true-join-multiple($lists...) -// -// **[private:{list}]** Any number of lists to be joined, with an optional final argument describing the desired list-separator ('space' or 'comma') -// -// Weight: 0 -// -// $lists - **{list[]}** ***Lists*** -// -// Styleguide Functions._true-join-multiple -_true-join-multiple($lists...) { - $return = (); - $last = $lists[-1]; - $length = length($lists); - - if (unquote($last) == unquote(' ') || unquote($last) == unquote(',')) { - $length = $length - 1; - } - - if ($length < 2) { - $error = 'Must provide at least 2 lists'; - return _true-error($error, '_true-join-multiple'); - } - - for $i in (0 .. ($length - 1)) { - if (is-list($lists[$i])) { - for $j in (0 .. (length($lists[$i]) - 1)) { - push($return, $lists[$i][$j]); - } - } else { - push($return, $lists[$i]); - } - } - - $first = slice($return, 0, 1); - if (unquote($first) == unquote(' ')) { - $return = substr($return, 1, str-length($return)); - } - - if (unquote($first) == unquote(',')) { - $return = substr($return, 2, str-length($return)); - } - - return $return; -} +use('../../lib/str-length.js'); + +// map-keys($hash) +// +// **[private:{list}]** Returns a list with only the keys of the selected hash +// +// Weight: 0 +// +// $hash - **{hash}** ***Hash to extract the keys from*** +// +// Styleguide Functions.map-keys +use('../../lib/map-keys.js'); + +// $_true-error-output-override = { value } +// +// **[public]** Value key stores the desired value +// +// Weight: -10 +// +// $value = true - **{boolean}** ***The actual output override value*** +// +// Styleguide Variables.$_true-error-output-override +$_true-error-output-override = { + value: true +}; + +// is-list($list) +// +// **[private:{boolean}]** Returns whether an argument is a list or not +// +// Weight: 0 +// +// $list - **{list}** ***The list to analyze*** +// +// Styleguide Functions.is-list +is-list() { + // arguments is injected by stylus + if (type(arguments) == 'object') { + return type(keys(arguments)[0]) == 'object'; + } else { + return str-length(arguments) == 'NOT_A_STRING' && length(arguments) > 1 && type(arguments) != 'rgba'; + } +} + +// _true-error($message, $source, $override) +// +// **[private:{void|string}]** Throw or returns an error with a message detailing the source and error +// +// Weight: 0 +// +// $message - **{string}** ***The error to report*** +// $source - **{string}** ***The source of the error*** +// $override = $_true-error-output-override.value - **{boolean}** ***Optionally override error-output for testing failure-cases*** +// +// Styleguide Functions._true-error +_true-error($message, $source, $override = $_true-error-output-override.value) { + $error = 'ERROR [' + $source + '] ' + $message; + + if ($override) { + return $error; + } + + $error = '' + $error + ''; + error($error); +} + +// _true-error-mixin($message, $source, $override) +// +// **[private:{void}]** Outputs an error with a message detailing the source and error +// +// Weight: 0 +// +// $message - **{string}** ***The error to report*** +// $source - **{string}** ***The source of the error*** +// $override = $_true-error-output-override.value - **{boolean}** ***Optionally override error-output for testing failure-cases*** +// +// Styleguide Mixins._true-error-mixin +_true-error-mixin($message, $source, $override = $_true-error-output-override.value) { + $error = 'ERROR [' + $source + '] ' + $message; + + if ($override) { + _true-message($error, 'comments'); + } else { + error($error); + } +} + + +// _true-map-increment($base, $add) +// +// **[private:{string}]** Add hash values together +// +// Weight: 0 +// +// $base - **{string}** ***Initial map to add values to*** +// $add - **{string}** ***Map of values to be added*** +// +// Styleguide Functions._true-map-increment +_true-map-increment($base, $add) { + for $key in (map-keys($add)) { + $value = $add[$key]; + + if ($value) { + $base-value = $base[$key]; + $new-value = $base-value ? ($base-value + $value) : $value; + $base[$key] = $new-value; + } + } + + return $base; +} + +// _true-join-multiple($lists...) +// +// **[private:{list}]** Any number of lists to be joined, with an optional final argument describing the desired list-separator ('space' or 'comma') +// +// Weight: 0 +// +// $lists - **{list[]}** ***Lists*** +// +// Styleguide Functions._true-join-multiple +_true-join-multiple($lists...) { + $return = (); + $last = $lists[-1]; + $length = length($lists); + + if (unquote($last) == unquote(' ') || unquote($last) == unquote(',')) { + $length = $length - 1; + } + + if ($length < 2) { + $error = 'Must provide at least 2 lists'; + return _true-error($error, '_true-join-multiple'); + } + + for $i in (0 .. ($length - 1)) { + if (is-list($lists[$i])) { + for $j in (0 .. (length($lists[$i]) - 1)) { + push($return, $lists[$i][$j]); + } + } else { + push($return, $lists[$i]); + } + } + + $first = slice($return, 0, 1); + if (unquote($first) == unquote(' ')) { + $return = substr($return, 1, str-length($return)); + } + + if (unquote($first) == unquote(',')) { + $return = substr($return, 2, str-length($return)); + } + + return $return; +}