From cd099c09f68ed38cda5449c8aa4ae804de9e12d1 Mon Sep 17 00:00:00 2001 From: Ross Clark <6961242+rossclarkartist@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:26:31 +0100 Subject: [PATCH] fix: Update use path in .styl files Update "use" path in .styl files to correct any "failed to locate plugin file" errors that prevent usage of the provided stylus interface. See, https://github.com/ghaschel/stylus-true/issues/34, for further info On branch master - Your branch is up to date with 'origin/master'. - Changes to be committed: - modified: styl/true/_context.styl - modified: styl/true/_messages.styl - modified: styl/true/_modules.styl - modified: styl/true/_output.styl - modified: styl/true/_results.styl --- styl/true/_context.styl | 382 ++++++++++++++++++------------------ styl/true/_messages.styl | 130 ++++++------- styl/true/_modules.styl | 306 ++++++++++++++--------------- styl/true/_output.styl | 400 +++++++++++++++++++------------------- styl/true/_results.styl | 300 ++++++++++++++-------------- styl/true/_utilities.styl | 312 ++++++++++++++--------------- 6 files changed, 915 insertions(+), 915 deletions(-) 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; +}