#![cfg(test)]

#[macro_use]
mod macros;

test!(
    basic_mixin,
    "@mixin a {\n  color: red;\n}\n\nb {\n  @include a;\n}\n",
    "b {\n  color: red;\n}\n"
);
test!(empty_mixin, "@mixin a {}\n\nb {\n  @include a;\n}\n", "");
test!(
    just_a_comment,
    "@mixin foo() {\n  /* begin foo */\n}\n\na {\n    @include foo();\n}\n",
    "a {\n  /* begin foo */\n}\n"
);
test!(
    mixin_two_styles,
    "@mixin a {\n  color: red;\n  color: blue;\n}\n\nb {\n  @include a;\n}\n",
    "b {\n  color: red;\n  color: blue;\n}\n"
);
test!(
    mixin_ruleset,
    "@mixin a {\n  b {\n    color: red;\n  }\n}\nb {\n  @include a;\n}\n",
    "b b {\n  color: red;\n}\n"
);
test!(
    mixin_two_rulesets,
    "@mixin a {\n  b {\n    color: red;\n  }\n  c {\n    color: blue;\n  }\n}\nd {\n  @include a;\n}\n",
    "d b {\n  color: red;\n}\nd c {\n  color: blue;\n}\n"
);
test!(
    mixin_ruleset_and_style,
    "@mixin a {\n  b {\n    color: red;\n  }\n  color: blue;\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: blue;\n}\nd b {\n  color: red;\n}\n"
);
test!(
    mixin_style_and_ruleset,
    "@mixin a {\n  color: blue;\n  b {\n    color: red;\n}\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: blue;\n}\nd b {\n  color: red;\n}\n"
);
test!(
    mixin_nested_rulesets,
    "@mixin a {\n  b {\n    c {\n      color: red;\n}\n}\n}\nd {\n  @include a;\n}\n",
    "d b c {\n  color: red;\n}\n"
);
test!(
    mixin_removes_empty_ruleset,
    "@mixin a {\n  color: red; b {\n}\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_variable_scope_one_ruleset,
    "@mixin a {\n  $a: blue;\nb {\n  $a: red;\n}  color: $a\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_no_args,
    "@mixin a {\n  color: red;\n}\nd {\n  @include a();\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_single_arg,
    "@mixin a($b) {\n  color: $b;\n}\nd {\n  @include a(red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_two_args,
    "@mixin a($b, $c) {\n  color: $b;\n  color: $c\n}\nd {\n  @include a(red, blue);\n}\n",
    "d {\n  color: red;\n  color: blue;\n}\n"
);
test!(
    mixin_arg_trailing_comma,
    "@mixin a($b, $c,) {\n  color: $b;\n  color: $c\n}\nd {\n  @include a(red, blue);\n}\n",
    "d {\n  color: red;\n  color: blue;\n}\n"
);
test!(
    mixin_property_interpolation,
    "@mixin a($b) {\n  #{$b}: red;\n}\nd {\n  @include a(color);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_style_interpolation,
    "@mixin a($b) {\n  color: #{$b};\n}\nd {\n  @include a(red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_simple_default_value,
    "@mixin a($b: red) {\n  color: $b;\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    mixin_second_value_default,
    "@mixin a($a, $b: blue) {\n  color: $a $b;\n}\nd {\n  @include a(red);\n}\n",
    "d {\n  color: red blue;\n}\n"
);
test!(
    mixin_two_default_values,
    "@mixin a($a: red, $b: blue) {\n  color: $a $b;\n}\nd {\n  @include a;\n}\n",
    "d {\n  color: red blue;\n}\n"
);
test!(
    mixin_override_default_value_positionally,
    "@mixin a($a: red) {\n  color: $a;\n}\nd {\n  @include a(blue);\n}\n",
    "d {\n  color: blue;\n}\n"
);
test!(
    mixin_keyword_arg,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a($a: blue);\n}\n",
    "d {\n  color: blue;\n}\n"
);
test!(
    mixin_keyword_arg_override_default,
    "@mixin a($a: red) {\n  color: $a;\n}\nd {\n  @include a($a: blue);\n}\n",
    "d {\n  color: blue;\n}\n"
);
test!(
    mixin_keyword_applies_to_second_arg,
    "@mixin a($a: red, $b) {\n  color: $a $b;\n}\nd {\n  @include a($b: blue);\n}\n",
    "d {\n  color: red blue;\n}\n"
);
test!(
    mixin_two_keywords,
    "@mixin a($a, $b) {\n  color: $a $b;\n}\nd {\n  @include a($a: red, $b: blue);\n}\n",
    "d {\n  color: red blue;\n}\n"
);
test!(
    mixin_two_keywords_wrong_direction,
    "@mixin a($a, $b) {\n  color: $a $b;\n}\nd {\n  @include a($b: blue, $a: red);\n}\n",
    "d {\n  color: red blue;\n}\n"
);
test!(
    variable_in_call_args,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  $c: red;\n  @include a($c);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_before_positional_call_arg,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a(/*foo*/red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_after_positional_call_arg,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a(red/*foo*/);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_before_keyword_call_arg_val,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a($a: /*foo*/red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_after_keyword_call_arg_val,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a($a: red/*foo*/);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_before_keyword_call_arg_name,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a(/*foo*/$a: red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    comment_after_keyword_call_arg_name,
    "@mixin a($a) {\n  color: $a;\n}\nd {\n  @include a($a/*foo*/: red);\n}\n",
    "d {\n  color: red;\n}\n"
);
test!(
    toplevel_include,
    "@mixin a {\n  a {\n    color: red;\n  }\n}\n\n@include a;\n",
    "a {\n  color: red;\n}\n"
);
test!(
    include_list,
    "@mixin foo($x) {\n  color: $x;\n}\na {\n  @include foo(0px 0px 0px 0px #ef8086 inset !important);\n}\n",
    "a {\n  color: 0px 0px 0px 0px #ef8086 inset !important;\n}\n"
);
test!(
    content_without_variable,
    "@mixin foo {\n  @content;\n}\n\na {\n  @include foo {\n    color: red;\n  }\n}\n",
    "a {\n  color: red;\n}\n"
);
test!(
    content_with_variable,
    "@mixin foo($a) {\n  @content;\n}\n\na {\n  @include foo(red) {\n    color: red;\n  }\n}\n",
    "a {\n  color: red;\n}\n"
);
test!(
    mixin_style_does_not_end_with_semicolon,
    "@mixin foo {\n  color: red\n}\n\na {\n  @include foo;\n}\n",
    "a {\n  color: red;\n}\n"
);
test!(
    args_hyphen_arg_allows_underscore,
    "@mixin foo($a-b) {\n  color: $a-b;\n  color: $a_b;\n}\na {\n  @include foo($a_b: a);\n  @include foo($a-b: a);\n}\n",
    "a {\n  color: a;\n  color: a;\n  color: a;\n  color: a;\n}\n"
);
test!(
    args_underscore_arg_allows_hyphen,
    "@mixin foo($a_b) {\n  color: $a-b;\n  color: $a_b;\n}\na {\n  @include foo($a_b: a);\n  @include foo($a-b: a);\n}\n",
    "a {\n  color: a;\n  color: a;\n  color: a;\n  color: a;\n}\n"
);
test!(
    control_flow_in_content,
    "@mixin foo {\n    @content;\n}\n\na {\n    @include foo {@if true {color: red;}}\n}\n",
    "a {\n  color: red;\n}\n"
);
test!(
    content_in_control_flow,
    "@mixin foo() {\n    @if true {\n        @content;\n    }\n}\n\na {\n    @include foo {\n        color: red;\n    }\n}\n",
    "a {\n  color: red;\n}\n"
);
test!(
    content_inside_unknown_at_rule,
    "@mixin foo() {\n    @foo (max-width: max) {\n        @content;\n    }\n}\n\na {\n    @include foo {\n        color: red;\n    }\n}\n",
    "@foo (max-width: max) {\n  a {\n    color: red;\n  }\n}\n"
);
test!(
    content_inside_media,
    "@mixin foo() {\n    @media (max-width: max) {\n        @content;\n    }\n}\n\na {\n    @include foo {\n        color: red;\n    }\n}\n",
    "@media (max-width: max) {\n  a {\n    color: red;\n  }\n}\n"
);
error!(
    function_inside_mixin,
    "@mixin foo() {\n    @function bar() {\n        @return foo;\n    }\n}\n\na {\n    @include foo {\n        color: red;\n    }\n}\n",
    "Error: Mixins may not contain function declarations."
);
error!(
    content_inside_control_flow_outside_mixin,
    "a {\n    @if true {\n        @content;\n    }\n}\n",
    "Error: @content is only allowed within mixin declarations."
);
error!(
    undefined_mixin,
    "a {@include foo;}", "Error: Undefined mixin."
);
test!(
    include_empty_args_no_semicolon,
    "@mixin c {}\n\na {\n    @include c()\n}\n",
    ""
);