# frozen_string_literal: true

RSpec.describe MiniCSS::AST do
  it "transforms a parsed CSS into AST" do
    style = <<~CSS
      body { background-color: #AABBCC; }
    CSS
    tok = MiniCSS::CSS::Tokenizer.new(style)
    tok.tokenize
    par = MiniCSS::CSS::Parser.new(tok.tokens)
    sheet = par.parse_stylesheet
    MiniCSS::AST.convert(sheet)
  end

  it "transforms real CSS into AST" do
    tok = MiniCSS::CSS::Tokenizer.new(File.read(fixture_path("vito_io.css")))
    tok.tokenize
    par = MiniCSS::CSS::Parser.new(tok.tokens)
    sheet = par.parse_stylesheet
    MiniCSS::AST.convert(sheet)
  end

  it "parses an at-rule" do
    style = <<~CSS
      @media only screen and (min-width: 650px) and (max-height: 1000px) {
        main.home {
          margin-top: 200px;
        }
      }
    CSS

    tok = MiniCSS::CSS::Tokenizer.new(style)
    tok.tokenize
    par = MiniCSS::CSS::Parser.new(tok.tokens)
    rule = par.consume_at_rule
    MiniCSS::AST.convert(rule)
  end

  it "parses selectors containing double-quotes" do
    style = <<~CSS
      [data-role="primary"] .label {
        font-weight: bold;
      }
    CSS
    tok = MiniCSS::CSS::Tokenizer.new(style)
    tok.tokenize
    par = MiniCSS::CSS::Parser.new(tok.tokens)
    rule = par.parse_rule
    conv = MiniCSS::AST.convert(rule)
    expect(conv.selector).to eq({
      type: :complex,
      combinator: " ",
      left: {
        name: "data-role",
        operator: "=",
        value: "\"primary\"",
        type: :attribute,
        content: "[data-role=\"primary\"]",
        pos: [0, 21]
      },
      right: {
        name: "label",
        type: :class,
        content: ".label",
        pos: [22, 28]
      }
    })
  end

  it "parses nested rule with :is()" do
    style = <<~CSS
      .card {
        :is(.title, .header) {
          font-weight: bold;
        }
      }
    CSS
    tok = MiniCSS::CSS::Tokenizer.new(style)
    tok.tokenize
    par = MiniCSS::CSS::Parser.new(tok.tokens)
    rule = par.parse_rule
    conv = MiniCSS::AST.convert(rule)
    expect(conv.child_rules.first.raw_selector).to eq ":is(.title, .header) "
  end
end
