func testScanMap(t *testing.T, v interface{}, tokens []elt) { var src []byte switch vv := v.(type) { case []byte: src = vv case string: src = []byte(vv) default: log.Fatal("unsupported") } whitespaceLinecount := newlineCount(whitespace) // error handler eh := func(_ token.Position, msg string) { t.Errorf("error handler called (msg = %s)", msg) } var s Scanner s.Init(fset.AddFile("", fset.Base(), len(src)), src, eh, ScanComments) epos := token.Position{ Filename: "", Offset: 0, Line: 1, Column: 1, } index := 0 for { pos, tok, lit := s.Scan() if tok == token.EOF { if len(whitespace) > 0 { epos.Line = newlineCount(string(src)) epos.Column = 2 } } // Selectors are magical and they appear when you least expect them switch tok { case token.SELECTOR: continue } // Some tokens don't respond with literals plit := lit if len(plit) == 0 { plit = tok.String() } checkPos(t, plit, pos, epos) // check token e := elt{token.EOF, ""} if index < len(tokens) { e = tokens[index] index++ } if tok != e.tok { t.Errorf("bad token for %q: got %s, expected %s", lit, tok, e.tok) } // check literal elit := "" switch e.tok { case token.COMMENT: // no CRs in comments elit = string(stripCR([]byte(e.lit))) //-style comment literal doesn't contain newline if elit[1] == '/' { elit = elit[0 : len(elit)-1] } case token.ATTRIBUTE: // FIXME: the parser should eliminate whitespace // from selector attributes elit = strings.Replace(e.lit, " ", "", -1) case token.IDENT: elit = e.lit case token.SEMICOLON: elit = ";" default: if e.tok.IsLiteral() { // no CRs in raw string literals elit = e.lit if elit[0] == '`' { elit = string(stripCR([]byte(elit))) } } else if e.tok.IsKeyword() || e.tok.IsCSSNum() { elit = e.lit } } if lit != elit { t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, elit) } if tok == token.EOF { break } // update position epos.Offset += len(e.lit) + len(whitespace) epos.Line += newlineCount(e.lit) + whitespaceLinecount if len(whitespace) == 0 { epos.Column += len(e.lit) } } }