<!doctype html>
<title>CSS Selectors parsing</title>
<link rel="author" title="Adam Argyle" href="mailto:argyle@google.com">
<link rel="help" href="https://drafts.csswg.org/css-nesting-1/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<style id="test-sheet"></style>
<script>
  let [ss] = document.styleSheets

  const beforeEach = () => {
    while (ss.rules.length)
      ss.removeRule(0)
  }

  const tests = [
    {
      rule: `.foo {\n  & { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssRules[0].selectorText, "&");
        assert_equals(rule.cssText, this.rule);
      },
    },
    {
      rule: `.foo {\n  &.bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, "&.bar");
      },
    },
    {
      rule: `.foo {\n  & .bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, "& .bar");
      },
    },
    {
      rule: `.foo {\n  & > .bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, "& > .bar");
      },
    },
    {
      rule: `.foo {\n  > & .bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssRules[0].selectorText, "& > & .bar");
      },
    },
    {
      rule: `.foo {\n  > .bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssRules[0].selectorText, "& > .bar");
      },
    },
    {
      rule: `.foo {\n  + .bar & { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssRules[0].selectorText, "& + .bar &");
      },
    },
    {
      rule: `.foo {\n  .test > & .bar { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, ".test > & .bar");
      },
    },
    {
      rule: `.foo {\n  + .bar, .foo, > .lol { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssRules[0].selectorText, "& + .bar, .foo, & > .lol");
      },
    },
    {
      rule: `.foo {\n  &:is(.bar, &.baz) { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, "&:is(.bar, &.baz)");
      },
    },
    {
      rule: `.foo {\n  .bar& { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, ".bar&");
      },
    },
    {
      rule: `.foo {\n  .bar > & { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, ".bar > &");
      },
    },
    {
      rule: `.foo, .bar {\n  & + .baz, &.qux { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
        assert_equals(rule.cssRules[0].selectorText, "& + .baz, &.qux");
      },
    },
    {
      rule: `.foo {\n  & .bar & .baz & .qux { color: green; }\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
      },
    },
    {
      rule: `.foo {\n  @media (min-width: 50px) { color: green; }\n}`,
      check(rule) {
        assert_in_array(rule.cssText, [
          this.rule,
          `.foo {\n  @media (min-width: 50px) {\n  & { color: green; }\n}\n}`,
        ]);
      },
    },
    {
      rule: `main {\n  & > section, & > article {\n  & > header { color: green; }\n}\n}`,
      check(rule) {
        assert_equals(rule.cssText, this.rule);
      },
    },
  ]

  tests.forEach(t => {
    test(function() {
      beforeEach()
      assert_equals(ss.cssRules.length, 0, "Should be empty");
      ss.insertRule(t.rule)
      assert_equals(ss.cssRules.length, 1, "Should have one rule");
      t.check(ss.rules[0]);
    }, t.rule)
  })
</script>
