You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature Request: Support for intended fail-scenario #146
There is no way to build this into True's testing-syntax directly, since the @error declaration stops Sass compilation. It would require changes to how you write functions and mixins in the first place. You can see how we've done that for both True and Susy – by passing all our errors through a function or mixin that toggles between returning the error message as a string (in tests), or triggering the Sass @error (in producion).
The best we could do is provide those functions/mixins as a plugin that you can include in your primary Sass, rather than copy-pasting the functions yourself. That should be doable. In the meantime, feel free to copy/paste, and let me know if you have questions.
Would you consider allowing special comments to wrap around tests which should throw? Tests might be written like this:
@includedescribe('some-mixin') {
@includeit('should work') {
/* normal test omitted for brevity */
}
/** START_EXPECT_ERROR: Maybe the expected error message could go here */@includesome-mixin(bad, params);
/** END_EXPECT_ERROR */
}
You would then have a multi-phase parse:
Strip out all EXPECT_ERROR blocks - easily done with regex.
Replace each error block with some /* unique_token */ so it can be re-injected later
Parse the file without any error blocks
For each error block... one at a time... inject the code and parse again using try/catch
Validate the error message inside the catch block
I would gladly help with this if this seems like a viable solution. My main objective is to allow people to write SASS and not have to learn a separate error mixin and global variables. Thanks again for such a wonderful tool.
@DesignByOnyx I'm open to discussing something like that.
While it requires less change to your project code (no special mixin), it also removes the ability to run your tests in pure Sass. I wonder if we could work around that by doing something like (pseudo-sass):
// - regex should work just as well with a mixin, so we don't add a completely new syntax// - by default, it won't compile. Users or True can pass in $compile: true when it should// - if a message is given, error message must match// - if no message is given, any error will pass the test@mixinassert-error(
$message: null,
$compile: false
) {
/* we can supply the necessary output comments here… */@if$compile {
@content;
} @else {
/* whatever output we want for pure-Sass compilation */
}
}
// usage…@includeassert-error(`<optional error message>`) {
/* code-block that should error */
}
// also handle warnings?@includeassert-warn(`<optional warning message>`) {
/* code-block that should warn */
}
Would True loop through each assertion and dynamically set $compile: true one at a time? If so, I think that's an excellent idea. Personally, I wouldn't even document the second parameter and leave it to True. There's talk of introducing @try/@catch directives into the language itself - though it seems a long ways off, and I'm not quite sure if the language needs more API just for the sake of testing.
Would True loop through each assertion and dynamically set $compile: true one at a time?
Yep, exactly.
The second parameter might be useful when authoring tests?
If not, we should probably remove it as a parameter entirely, and use a global variable instead.
There's talk of introducing @try/@catch directives into the language itself
Yeah, Nex3 asked me if it would be useful, and I pointed her to our current ugly workaround as the clear use-case. Not sure what will come of it, but agree we shouldn't count on it any time soon.
Next Steps: Do you want to work on a PR for the entire thing? Or helpful for me to start some of the Sass end? Up to you.
If you can give some pointers on where to start, I'd appreciate it as it would save me some time. The biggest unknown to me is how to figure out the describe/it block in which the assertion was made and appending the results to the correct context. Let's start with a simple block of code for discussion:
$not-a-color: #gggggg;
@includedescribe('some-mixin') {
@includeit('should work') {
/* normal test omitted for brevity */
}
@includeit('should fail on bad params') {
@includeassert-error('Must pass a valid color value') {
@includesome-mixin($not-a-color);
}
}
}
On first run, the assert-error mixin is a no-op and it never renders its $content, thus never triggering the error.
Then, we must somehow discover each assert-error call and render the $content inside of a try/catch:
consterrorAssertions=findAllErrorAssertions(sourceFile);errorAssersions.forEach(assertion=>{constdata=sourceFile.replace(/* do the thing to render the mixin $content */);try{sass.renderSync({ data });// figure out the describe/it context and `assert(false)` as the error was not triggered}catch(ex){// compare error messages if one was provided// figure out the describe/it context and `assert(true)` if all looks good}});
I can stub out the Sass in a branch so you have a real sample to work from. I think the JS currently works by parsing that CSS output, so:
Yes, but also the assert-error mixin will generate a comment in the output CSS. We can play with what information needs to be in that comment, but I'll start with something basic: the module, test, assertion-type, and assertion-message.
Sounds right. I'm not an expert on the JS side of this project - so we can pull in @jgerigmeyer for questions or review on that side of things.
I've been digging through the code I think I figured out a good strategy for this and am going to take a stab at it. Feel free to save your time on stubbing things for right now as I think what I'm doing should work well and not require any difficult parsing.
Activity
mirisuzanne commentedon Jun 4, 2019
There is no way to build this into True's testing-syntax directly, since the
@errordeclaration stops Sass compilation. It would require changes to how you write functions and mixins in the first place. You can see how we've done that for both True and Susy – by passing all our errors through a function or mixin that toggles between returning the error message as a string (in tests), or triggering the Sass@error(in producion).The best we could do is provide those functions/mixins as a plugin that you can include in your primary Sass, rather than copy-pasting the functions yourself. That should be doable. In the meantime, feel free to copy/paste, and let me know if you have questions.
shani-terminus commentedon Jun 5, 2019
Thanks! I will look into implementing in our next sprint.
DesignByOnyx commentedon Jun 18, 2019
Would you consider allowing special comments to wrap around tests which should throw? Tests might be written like this:
You would then have a multi-phase parse:
EXPECT_ERRORblocks - easily done with regex./* unique_token */so it can be re-injected laterI would gladly help with this if this seems like a viable solution. My main objective is to allow people to write SASS and not have to learn a separate error mixin and global variables. Thanks again for such a wonderful tool.
mirisuzanne commentedon Jun 18, 2019
@DesignByOnyx I'm open to discussing something like that.
While it requires less change to your project code (no special mixin), it also removes the ability to run your tests in pure Sass. I wonder if we could work around that by doing something like (pseudo-sass):
DesignByOnyx commentedon Jun 21, 2019
Would
Trueloop through each assertion and dynamically set$compile: trueone at a time? If so, I think that's an excellent idea. Personally, I wouldn't even document the second parameter and leave it toTrue. There's talk of introducing@try/@catchdirectives into the language itself - though it seems a long ways off, and I'm not quite sure if the language needs more API just for the sake of testing.mirisuzanne commentedon Jun 21, 2019
Yep, exactly.
Yeah, Nex3 asked me if it would be useful, and I pointed her to our current ugly workaround as the clear use-case. Not sure what will come of it, but agree we shouldn't count on it any time soon.
Next Steps: Do you want to work on a PR for the entire thing? Or helpful for me to start some of the Sass end? Up to you.
DesignByOnyx commentedon Jun 21, 2019
If you can give some pointers on where to start, I'd appreciate it as it would save me some time. The biggest unknown to me is how to figure out the
describe/itblock in which the assertion was made and appending the results to the correct context. Let's start with a simple block of code for discussion:assert-errormixin is a no-op and it never renders its $content, thus never triggering the error.assert-errorcall and render the $content inside of a try/catch:mirisuzanne commentedon Jun 21, 2019
I can stub out the Sass in a branch so you have a real sample to work from. I think the JS currently works by parsing that CSS output, so:
assert-errormixin will generate a comment in the output CSS. We can play with what information needs to be in that comment, but I'll start with something basic: the module, test, assertion-type, and assertion-message.DesignByOnyx commentedon Jun 21, 2019
I've been digging through the code I think I figured out a good strategy for this and am going to take a stab at it. Feel free to save your time on stubbing things for right now as I think what I'm doing should work well and not require any difficult parsing.