increase code coverage
This commit is contained in:
parent
ef7d188062
commit
23abe152bd
@ -165,8 +165,6 @@ pub(crate) fn adjust_hue(mut args: ArgumentResult, visitor: &mut Visitor) -> Sas
|
||||
.assert_color_with_name("color", args.span())?;
|
||||
let degrees = angle_value(args.get_err(1, "degrees")?, "degrees", args.span())?;
|
||||
|
||||
dbg!(degrees);
|
||||
|
||||
Ok(Value::Color(Arc::new(color.adjust_hue(degrees))))
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,6 @@ pub(crate) fn alpha(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResu
|
||||
pub(crate) fn opacity(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||
args.max_args(1)?;
|
||||
match args.get_err(0, "color")? {
|
||||
Value::Dimension(SassNumber { num: n, .. }) if n.is_nan() => todo!(),
|
||||
Value::Color(c) => Ok(Value::Dimension(SassNumber::new_unitless(c.alpha()))),
|
||||
Value::Dimension(SassNumber {
|
||||
num,
|
||||
|
@ -56,12 +56,7 @@ pub(crate) fn nth(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult
|
||||
pub(crate) fn list_separator(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||
args.max_args(1)?;
|
||||
Ok(Value::String(
|
||||
match args.get_err(0, "list")? {
|
||||
Value::List(_, sep, ..) => sep.name(),
|
||||
Value::Map(..) | Value::ArgList(..) => ListSeparator::Comma.name(),
|
||||
_ => ListSeparator::Space.name(),
|
||||
}
|
||||
.to_owned(),
|
||||
args.get_err(0, "list")?.separator().name().to_owned(),
|
||||
QuoteKind::None,
|
||||
))
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ impl Environment {
|
||||
for name in (*self.scopes.global_variables()).borrow().keys() {
|
||||
if (*module).borrow().var_exists(*name) {
|
||||
return Err((
|
||||
format!("This module and the new module both define a variable named \"{name}\".", name = name)
|
||||
format!("This module and the new module both define a variable named \"${name}\".", name = name)
|
||||
, span).into());
|
||||
}
|
||||
}
|
||||
|
@ -829,13 +829,7 @@ impl<'a> Visitor<'a> {
|
||||
span: Span,
|
||||
) -> SassResult<StyleSheet> {
|
||||
if let Some(name) = self.find_import(url.as_ref()) {
|
||||
// assumption: most users use regular file paths for their imports.
|
||||
// we do support importing syntactically invalid paths and paths that
|
||||
// do not exist through the `Options::fs` API, so we fallback to the
|
||||
// original name if necessary
|
||||
let canonical = std::fs::canonicalize(&name).unwrap_or_else(|_| name.to_path_buf());
|
||||
|
||||
if let Some(style_sheet) = self.import_cache.get(&canonical) {
|
||||
if let Some(style_sheet) = self.import_cache.get(&name) {
|
||||
return Ok(style_sheet.clone());
|
||||
}
|
||||
|
||||
@ -853,10 +847,10 @@ impl<'a> Visitor<'a> {
|
||||
self.flags
|
||||
.set(ContextFlags::IS_USE_ALLOWED, old_is_use_allowed);
|
||||
|
||||
if self.files_seen.contains(&canonical) {
|
||||
self.import_cache.insert(canonical, style_sheet.clone());
|
||||
if self.files_seen.contains(&name) {
|
||||
self.import_cache.insert(name, style_sheet.clone());
|
||||
} else {
|
||||
self.files_seen.insert(canonical);
|
||||
self.files_seen.insert(name);
|
||||
}
|
||||
|
||||
return Ok(style_sheet);
|
||||
@ -2079,16 +2073,14 @@ impl<'a> Visitor<'a> {
|
||||
touched: BTreeSet::new(),
|
||||
})
|
||||
}
|
||||
v => {
|
||||
return Err((
|
||||
format!(
|
||||
"Variable keyword arguments must be a map (was {}).",
|
||||
v.inspect(arguments.span)?
|
||||
),
|
||||
arguments.span,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
v => Err((
|
||||
format!(
|
||||
"Variable keyword arguments must be a map (was {}).",
|
||||
v.inspect(arguments.span)?
|
||||
),
|
||||
arguments.span,
|
||||
)
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ grass input.scss
|
||||
```
|
||||
*/
|
||||
|
||||
#![warn(clippy::all, clippy::cargo)]
|
||||
#![warn(clippy::all, clippy::cargo, clippy::dbg_macro)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![allow(
|
||||
clippy::use_self,
|
||||
|
@ -2,8 +2,7 @@ use std::{
|
||||
convert::From,
|
||||
fmt, mem,
|
||||
ops::{
|
||||
Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub,
|
||||
SubAssign,
|
||||
Add, AddAssign, Deref, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
|
||||
},
|
||||
};
|
||||
|
||||
@ -231,12 +230,6 @@ impl Deref for Number {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Number {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! from_integer {
|
||||
($ty:ty) => {
|
||||
impl From<$ty> for Number {
|
||||
|
@ -32,7 +32,7 @@ grass input.scss
|
||||
*/
|
||||
|
||||
#![cfg_attr(doc, feature(doc_cfg))]
|
||||
#![warn(clippy::all, clippy::cargo)]
|
||||
#![warn(clippy::all, clippy::cargo, clippy::dbg_macro)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![allow(
|
||||
clippy::use_self,
|
||||
|
@ -690,7 +690,75 @@ test!(
|
||||
"a {\n color: #0000z;\n}\n",
|
||||
"a {\n color: rgba(0, 0, 0, 0) z;\n}\n"
|
||||
);
|
||||
test!(
|
||||
opacity_nan,
|
||||
"a {\n color: opacity(0/0);\n}\n",
|
||||
"a {\n color: opacity(NaN);\n}\n"
|
||||
);
|
||||
test!(
|
||||
change_color_no_change,
|
||||
"a {\n color: change-color(red);\n}\n",
|
||||
"a {\n color: red;\n}\n"
|
||||
);
|
||||
test!(
|
||||
change_color_hwb_hue,
|
||||
"a {\n color: change-color(red, $whiteness: 50%, $hue: 230);\n}\n",
|
||||
"a {\n color: #8095ff;\n}\n"
|
||||
);
|
||||
error!(
|
||||
hex_color_starts_with_number_non_hex_digit_at_position_6,
|
||||
"a {\n color: #00000z;\n}\n", "Error: Expected hex digit."
|
||||
);
|
||||
error!(
|
||||
opacity_arg_not_color_or_number,
|
||||
"a {\n color: opacity(a);\n}\n", "Error: $color: a is not a color."
|
||||
);
|
||||
error!(
|
||||
ie_hex_str_no_args,
|
||||
"a {\n color: ie-hex-str();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
opacify_no_args,
|
||||
"a {\n color: opacify();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
opacify_one_arg,
|
||||
"a {\n color: opacify(red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
transparentize_no_args,
|
||||
"a {\n color: transparentize();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
transparentize_one_arg,
|
||||
"a {\n color: transparentize(red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
adjust_color_sl_and_wb,
|
||||
"a {\n color: adjust-color(red, $saturation: 50%, $whiteness: 50%);\n}\n",
|
||||
"Error: HSL parameters may not be passed along with HWB parameters."
|
||||
);
|
||||
error!(
|
||||
adjust_color_rgb_and_sl,
|
||||
"a {\n color: adjust-color(red, $red: 50%, $saturation: 50%);\n}\n",
|
||||
"Error: RGB parameters may not be passed along with HSL parameters."
|
||||
);
|
||||
error!(
|
||||
adjust_color_rgb_and_wb,
|
||||
"a {\n color: adjust-color(red, $red: 50%, $whiteness: 50%);\n}\n",
|
||||
"Error: RGB parameters may not be passed along with HWB parameters."
|
||||
);
|
||||
error!(
|
||||
adjust_color_two_unknown_named_args,
|
||||
"a {\n color: adjust-color(red, $foo: 50%, $bar: 50%);\n}\n",
|
||||
"Error: No arguments named $foo or $bar."
|
||||
);
|
||||
error!(
|
||||
adjust_color_two_positional_args,
|
||||
"a {\n color: adjust-color(red, 50%);\n}\n",
|
||||
"Error: Only one positional argument is allowed. All other arguments must be passed by name."
|
||||
);
|
||||
error!(
|
||||
adjust_color_no_args,
|
||||
"a {\n color: adjust-color();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
|
@ -203,7 +203,7 @@ test!(
|
||||
"a {\n color: 100%;\n}\n"
|
||||
);
|
||||
test!(
|
||||
saturate_one_arg,
|
||||
saturate_one_named_arg,
|
||||
"a {\n color: saturate($amount: 50%);\n}\n",
|
||||
"a {\n color: saturate(50%);\n}\n"
|
||||
);
|
||||
@ -356,3 +356,84 @@ test!(
|
||||
"a {\n color: hsl(60rad, 100%, 50%);\n}\n",
|
||||
"a {\n color: hsl(197.7467707849deg, 100%, 50%);\n}\n"
|
||||
);
|
||||
error!(
|
||||
hsl_one_arg_bracketed,
|
||||
"a {\n color: hsl([1, 2, 3]);\n}\n",
|
||||
"Error: $channels must be an unbracketed, space-separated list."
|
||||
);
|
||||
error!(
|
||||
hue_arg_not_color,
|
||||
"a {\n color: hue(1);\n}\n", "Error: $color: 1 is not a color."
|
||||
);
|
||||
error!(
|
||||
saturation_arg_not_color,
|
||||
"a {\n color: saturation(1);\n}\n", "Error: $color: 1 is not a color."
|
||||
);
|
||||
error!(
|
||||
lightness_arg_not_color,
|
||||
"a {\n color: lightness(1);\n}\n", "Error: $color: 1 is not a color."
|
||||
);
|
||||
error!(
|
||||
adjust_hue_first_arg_not_color,
|
||||
"a {\n color: adjust-hue(1, 5deg);\n}\n", "Error: $color: 1 is not a color."
|
||||
);
|
||||
error!(
|
||||
hue_no_args,
|
||||
"a {\n color: hue();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
saturation_no_args,
|
||||
"a {\n color: saturation();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
lightness_no_args,
|
||||
"a {\n color: lightness();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
adjust_hue_no_args,
|
||||
"a {\n color: adjust-hue();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
adjust_hue_one_arg,
|
||||
"a {\n color: adjust-hue(red);\n}\n", "Error: Missing argument $degrees."
|
||||
);
|
||||
error!(
|
||||
lighten_no_args,
|
||||
"a {\n color: lighten();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
lighten_one_arg,
|
||||
"a {\n color: lighten(red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
darken_no_args,
|
||||
"a {\n color: darken();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
darken_one_arg,
|
||||
"a {\n color: darken(red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
saturate_single_named_arg_not_amount,
|
||||
"a {\n color: saturate($a: red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
saturate_no_args,
|
||||
"a {\n color: saturate();\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
saturate_one_arg,
|
||||
"a {\n color: saturate(red);\n}\n", "Error: $amount: red is not a number."
|
||||
);
|
||||
error!(
|
||||
desaturate_no_args,
|
||||
"a {\n color: desaturate();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
desaturate_one_arg,
|
||||
"a {\n color: desaturate(red);\n}\n", "Error: Missing argument $amount."
|
||||
);
|
||||
error!(
|
||||
complement_no_args,
|
||||
"a {\n color: complement();\n}\n", "Error: Missing argument $color."
|
||||
);
|
||||
|
@ -11,6 +11,17 @@ test!(
|
||||
"@use \"sass:color\";\na {\n color: color.blackness(white);\n}\n",
|
||||
"a {\n color: 0%;\n}\n"
|
||||
);
|
||||
|
||||
test!(
|
||||
whiteness_black,
|
||||
"@use \"sass:color\";\na {\n color: color.whiteness(black);\n}\n",
|
||||
"a {\n color: 0%;\n}\n"
|
||||
);
|
||||
test!(
|
||||
whiteness_white,
|
||||
"@use \"sass:color\";\na {\n color: color.whiteness(white);\n}\n",
|
||||
"a {\n color: 100%;\n}\n"
|
||||
);
|
||||
test!(
|
||||
blackness_approx_50_pct,
|
||||
"@use \"sass:color\";\na {\n color: color.blackness(color.hwb(0, 0%, 50%));\n}\n",
|
||||
@ -111,3 +122,18 @@ error!(
|
||||
"@use \"sass:color\";\na {\n color: color.hwb(0, 30%, 101%, 0.5);\n}\n",
|
||||
"Error: $blackness: Expected 101% to be within 0% and 100%."
|
||||
);
|
||||
error!(
|
||||
blackness_no_args,
|
||||
"@use \"sass:color\";\na {\n color: color.blackness();\n}\n",
|
||||
"Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
whiteness_no_args,
|
||||
"@use \"sass:color\";\na {\n color: color.whiteness();\n}\n",
|
||||
"Error: Missing argument $color."
|
||||
);
|
||||
error!(
|
||||
hwb_var_channels,
|
||||
"@use \"sass:color\";\na {\n color: color.hwb(var(--foo));\n}\n",
|
||||
"Error: Expected numeric channels, got \"hwb(var(--foo))\"."
|
||||
);
|
||||
|
@ -3,3 +3,10 @@ mod macros;
|
||||
|
||||
test!(simple_debug, "@debug 2", "");
|
||||
test!(simple_debug_with_semicolon, "@debug 2;", "");
|
||||
test!(
|
||||
// todo: test stdout
|
||||
debug_while_quiet,
|
||||
"@debug 2;",
|
||||
"",
|
||||
grass::Options::default().quiet(true)
|
||||
);
|
||||
|
@ -317,6 +317,23 @@ fn member_as_variable_assignment_toplevel() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forward_module_with_error() {
|
||||
let mut fs = TestFs::new();
|
||||
|
||||
fs.add_file("_error.scss", r#"a { color: 1 + red; }"#);
|
||||
|
||||
let input = r#"
|
||||
@forward "error";
|
||||
"#;
|
||||
|
||||
assert_err!(
|
||||
input,
|
||||
r#"Error: Undefined operation "1 + red"."#,
|
||||
grass::Options::default().fs(&fs)
|
||||
);
|
||||
}
|
||||
|
||||
error!(
|
||||
after_style_rule,
|
||||
r#"
|
||||
|
@ -315,6 +315,41 @@ fn imports_absolute_scss() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_same_file_twice() {
|
||||
let mut fs = TestFs::new();
|
||||
|
||||
fs.add_file("a.scss", r#"a { color: red; }"#);
|
||||
|
||||
let input = r#"
|
||||
@import "a";
|
||||
@import "a";
|
||||
"#;
|
||||
|
||||
assert_eq!(
|
||||
"a {\n color: red;\n}\n\na {\n color: red;\n}\n",
|
||||
&grass::from_string(input.to_string(), &grass::Options::default().fs(&fs)).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_same_file_thrice() {
|
||||
let mut fs = TestFs::new();
|
||||
|
||||
fs.add_file("a.scss", r#"a { color: red; }"#);
|
||||
|
||||
let input = r#"
|
||||
@import "a";
|
||||
@import "a";
|
||||
@import "a";
|
||||
"#;
|
||||
|
||||
assert_eq!(
|
||||
"a {\n color: red;\n}\n\na {\n color: red;\n}\n\na {\n color: red;\n}\n",
|
||||
&grass::from_string(input.to_string(), &grass::Options::default().fs(&fs)).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_explicit_file_extension() {
|
||||
let mut fs = TestFs::new();
|
||||
|
@ -437,6 +437,31 @@ test!(
|
||||
"a {\n color: a, A, \"Noto Color Emoji\";\n}\n",
|
||||
"a {\n color: a, A, \"Noto Color Emoji\";\n}\n"
|
||||
);
|
||||
test!(
|
||||
list_separator_of_map,
|
||||
"a {\n color: list-separator((a: b, c: d));\n}\n",
|
||||
"a {\n color: comma;\n}\n"
|
||||
);
|
||||
test!(
|
||||
list_separator_of_empty_parens,
|
||||
"a {\n color: list-separator(());\n}\n",
|
||||
"a {\n color: space;\n}\n"
|
||||
);
|
||||
test!(
|
||||
list_separator_of_unquoted_string,
|
||||
"a {\n color: list-separator(a);\n}\n",
|
||||
"a {\n color: space;\n}\n"
|
||||
);
|
||||
test!(
|
||||
list_separator_of_arglist,
|
||||
"@function foo($a...) {
|
||||
@return list-separator($a);
|
||||
}
|
||||
a {
|
||||
color: foo();
|
||||
}",
|
||||
"a {\n color: comma;\n}\n"
|
||||
);
|
||||
test!(
|
||||
list_separator_of_empty_list_after_join,
|
||||
"a {
|
||||
|
@ -112,6 +112,19 @@ macro_rules! assert_err {
|
||||
),
|
||||
}
|
||||
};
|
||||
($input:expr, $err:expr, $options:expr) => {
|
||||
match grass::from_string($input.to_string(), &$options) {
|
||||
Ok(..) => panic!("did not fail"),
|
||||
Err(e) => assert_eq!(
|
||||
$err,
|
||||
e.to_string()
|
||||
.chars()
|
||||
.take_while(|c| *c != '\n')
|
||||
.collect::<String>()
|
||||
.as_str()
|
||||
),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Suitable for simple import tests. Does not properly implement path resolution --
|
||||
|
@ -158,3 +158,31 @@ error!(
|
||||
comparable_non_number_arg_last,
|
||||
"a {\n color: comparable(1, b);\n}\n", "Error: $number2: b is not a number."
|
||||
);
|
||||
error!(
|
||||
percentage_no_args,
|
||||
"a {\n color: percentage();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
round_no_args,
|
||||
"a {\n color: round();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
ceil_no_args,
|
||||
"a {\n color: ceil();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
floor_no_args,
|
||||
"a {\n color: floor();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
abs_no_args,
|
||||
"a {\n color: abs();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
comparable_no_args,
|
||||
"a {\n color: comparable();\n}\n", "Error: Missing argument $number1."
|
||||
);
|
||||
error!(
|
||||
comparable_one_arg,
|
||||
"a {\n color: comparable(1);\n}\n", "Error: Missing argument $number2."
|
||||
);
|
||||
|
@ -26,6 +26,23 @@ test!(
|
||||
"a {\n color: if(false, 1, 2);\n}\n",
|
||||
"a {\n color: 2;\n}\n"
|
||||
);
|
||||
test!(
|
||||
if_is_global_fn,
|
||||
"a {
|
||||
$a: get-function(if);
|
||||
color: call($a, true, 2, 3);
|
||||
color: call($a, false, 2, 3);
|
||||
}",
|
||||
"a {\n color: 2;\n color: 3;\n}\n"
|
||||
);
|
||||
error!(
|
||||
if_inside_call_does_not_lazily_eval_args,
|
||||
"a {
|
||||
$a: get-function(if);
|
||||
color: call($a, true, 2, red % 5);
|
||||
}",
|
||||
"Error: Undefined operation \"red % 5\"."
|
||||
);
|
||||
test!(
|
||||
feature_exists_dbl_quoted,
|
||||
"a {\n color: feature-exists(\"at-error\")\n}\n",
|
||||
@ -359,5 +376,17 @@ test!(
|
||||
}",
|
||||
"a {\n color: get-function(\"empty\");\n}\n"
|
||||
);
|
||||
error!(
|
||||
feature_exists_no_args,
|
||||
"a {\n color: feature-exists();\n}\n", "Error: Missing argument $feature."
|
||||
);
|
||||
error!(
|
||||
unit_no_args,
|
||||
"a {\n color: unit();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
error!(
|
||||
unitless_no_args,
|
||||
"a {\n color: unitless();\n}\n", "Error: Missing argument $number."
|
||||
);
|
||||
|
||||
// todo: if() with different combinations of named and positional args
|
||||
|
@ -175,6 +175,11 @@ test!(
|
||||
"a {\n color: -5 % (-1/0);\n}\n",
|
||||
"a {\n color: NaN;\n}\n"
|
||||
);
|
||||
test!(
|
||||
zero_mod_negative,
|
||||
"a {\n color: 0 % -5;\n}\n",
|
||||
"a {\n color: 0;\n}\n"
|
||||
);
|
||||
error!(
|
||||
calculation_mod_calculation,
|
||||
"a {\n color: calc(1rem + 1px) % calc(1rem + 1px);\n}\n",
|
||||
|
@ -81,6 +81,16 @@ test!(
|
||||
"a {\n color: or(foo);\n}\n",
|
||||
"a {\n color: or(foo);\n}\n"
|
||||
);
|
||||
test!(
|
||||
rest_arg,
|
||||
"a {
|
||||
color: foo(red...);
|
||||
color: foo(a, red...);
|
||||
color: f#{o}o(red...);
|
||||
color: f#{o}o(a, red...);
|
||||
}",
|
||||
"a {\n color: foo(red);\n color: foo(a, red);\n color: foo(red);\n color: foo(a, red);\n}\n"
|
||||
);
|
||||
error!(
|
||||
denies_keyword_arguments_to_interpolated_function,
|
||||
"a {\n color: f#{o}o($a: red);\n}\n",
|
||||
|
@ -251,6 +251,16 @@ test!(
|
||||
"a {\n color: calc(1% + 3px - 2px);\n}\n",
|
||||
"a {\n color: calc(1% + 3px - 2px);\n}\n"
|
||||
);
|
||||
test!(
|
||||
inspect_calc,
|
||||
"a {\n color: inspect(calc(1% + 3px - 2px));\n}\n",
|
||||
"a {\n color: calc(1% + 3px - 2px);\n}\n"
|
||||
);
|
||||
test!(
|
||||
calc_ne_number,
|
||||
"a {\n color: calc(1% + 3px - 2px) == 1px;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
calc_num_plus_interpolation,
|
||||
"a {\n color: calc(1 + #{c});\n}\n",
|
||||
|
@ -254,3 +254,48 @@ test!(
|
||||
"a {\n color: str-index(\"c\\0308 a\", \"a\");\n}\n",
|
||||
"a {\n color: 3;\n}\n"
|
||||
);
|
||||
error!(
|
||||
to_lower_case_no_args,
|
||||
"a {\n color: to_lower_case();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
str_length_no_args,
|
||||
"a {\n color: str_length();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
quote_no_args,
|
||||
"a {\n color: quote();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
unquote_no_args,
|
||||
"a {\n color: unquote();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
str_slice_no_args,
|
||||
"a {\n color: str_slice();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
str_index_no_args,
|
||||
"a {\n color: str_index();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
error!(
|
||||
str_insert_no_args,
|
||||
"a {\n color: str_insert();\n}\n", "Error: Missing argument $string."
|
||||
);
|
||||
test!(
|
||||
unique_id_is_unique,
|
||||
"$init: unique-id();
|
||||
@for $_ from 0 to 100 {
|
||||
@if $init == unique-id() {
|
||||
@error 'got duplicate unique id: #{$init}';
|
||||
}
|
||||
}",
|
||||
""
|
||||
);
|
||||
test!(
|
||||
unique_id_is_valid_identifier,
|
||||
"@for $_ from 0 to 100 {
|
||||
#{unique-id()} {}
|
||||
}",
|
||||
""
|
||||
);
|
||||
|
@ -138,7 +138,7 @@ test!(
|
||||
);
|
||||
test!(supports_empty_body, "@supports (a: b) {}", "");
|
||||
test!(
|
||||
does_not_simplify_calculation_in_args,
|
||||
calculation_not_in_declaration,
|
||||
"@supports (calc(1 + 1)) {
|
||||
a {
|
||||
color: red;
|
||||
@ -146,6 +146,24 @@ test!(
|
||||
}",
|
||||
"@supports (calc(1 + 1)) {\n a {\n color: red;\n }\n}\n"
|
||||
);
|
||||
test!(
|
||||
ident_addition_on_rhs_of_declaration,
|
||||
"@supports (a: a + b) {
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
}",
|
||||
"@supports (a: ab) {\n a {\n color: red;\n }\n}\n"
|
||||
);
|
||||
test!(
|
||||
calculation_on_rhs_of_declaration,
|
||||
"@supports (a: calc(1px + 1px)) {
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
}",
|
||||
"@supports (a: calc(1px + 1px)) {\n a {\n color: red;\n }\n}\n"
|
||||
);
|
||||
error!(
|
||||
supports_inside_declaration_body,
|
||||
"@mixin foo() {
|
||||
|
@ -640,4 +640,66 @@ fn module_functions_through_forward() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn use_variable_declared_in_this_and_other_module() {
|
||||
let mut fs = TestFs::new();
|
||||
|
||||
fs.add_file(
|
||||
"_a.scss",
|
||||
r#"
|
||||
$a: blue;
|
||||
"#,
|
||||
);
|
||||
|
||||
let input = r#"
|
||||
$a: red;
|
||||
@use "a" as *;
|
||||
|
||||
a {
|
||||
color: $a;
|
||||
}
|
||||
"#;
|
||||
|
||||
assert_err!(
|
||||
input,
|
||||
"Error: This module and the new module both define a variable named \"$a\".",
|
||||
grass::Options::default().fs(&fs)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "we don't check for this"]
|
||||
fn use_variable_declared_in_two_modules() {
|
||||
let mut fs = TestFs::new();
|
||||
|
||||
fs.add_file(
|
||||
"_a.scss",
|
||||
r#"
|
||||
$a: blue;
|
||||
"#,
|
||||
);
|
||||
|
||||
fs.add_file(
|
||||
"_b.scss",
|
||||
r#"
|
||||
$a: red;
|
||||
"#,
|
||||
);
|
||||
|
||||
let input = r#"
|
||||
@use "a" as *;
|
||||
@use "b" as *;
|
||||
|
||||
a {
|
||||
color: $a;
|
||||
}
|
||||
"#;
|
||||
|
||||
assert_err!(
|
||||
input,
|
||||
"Error: This variable is available from multiple global modules.",
|
||||
grass::Options::default().fs(&fs)
|
||||
);
|
||||
}
|
||||
|
||||
// todo: refactor these tests to use testfs where possible
|
||||
|
@ -2,3 +2,10 @@
|
||||
mod macros;
|
||||
|
||||
test!(simple_warn, "@warn 2", "");
|
||||
test!(
|
||||
// todo: test stdout
|
||||
warn_while_quiet,
|
||||
"@warn 2;",
|
||||
"",
|
||||
grass::Options::default().quiet(true)
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user