/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/spec/HTMLTokenizer-test.js
428 строк
16 KB
ficristo
Move most inline jslint directives to config files
12 авг 2016, 10:22
12 авг 2016, 10:22
074382a
Код
Авторство
О чём код?
/* * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ /*global describe, it, expect */ /*unittests: HTML Tokenizer*/ define(function (require, exports, module) { "use strict"; var Tokenizer = require("language/HTMLTokenizer").Tokenizer; describe("HTML Tokenizer", function () { it("should handle tags and text", function () { var t = new Tokenizer("<html>\n<body>Hello</body>\n</html>"); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "html", start: 1, end: 5, startPos: {line: 0, ch: 1}, endPos: {line: 0, ch: 5} }); expect(t.nextToken()).toEqual({ type: "opentagend", contents: "", start: -1, end: 6, startPos: null, endPos: {line: 0, ch: 6} }); expect(t.nextToken()).toEqual({ type: "text", contents: "\n", start: 6, end: 7, startPos: {line: 0, ch: 6}, endPos: {line: 1, ch: 0} }); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "body", start: 8, end: 12, startPos: {line: 1, ch: 1}, endPos: {line: 1, ch: 5} }); expect(t.nextToken()).toEqual({ type: "opentagend", contents: "", start: -1, end: 13, startPos: null, endPos: {line: 1, ch: 6} }); expect(t.nextToken()).toEqual({ type: "text", contents: "Hello", start: 13, end: 18, startPos: {line: 1, ch: 6}, endPos: {line: 1, ch: 11} }); expect(t.nextToken()).toEqual({ type: "closetag", contents: "body", start: 20, end: 24, startPos: {line: 1, ch: 13}, endPos: {line: 1, ch: 17} }); expect(t.nextToken()).toEqual({ type: "text", contents: "\n", start: 25, end: 26, startPos: {line: 1, ch: 18}, endPos: {line: 2, ch: 0} }); expect(t.nextToken()).toEqual({ type: "closetag", contents: "html", start: 28, end: 32, startPos: {line: 2, ch: 2}, endPos: {line: 2, ch: 6} }); }); it("should handle attributes", function () { var t = new Tokenizer("<div class='foo bar' style=\"baz: quux\" checked></div>"); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "div", start: 1, end: 4, startPos: {line: 0, ch: 1}, endPos: {line: 0, ch: 4} }); expect(t.nextToken()).toEqual({ type: "attribname", contents: "class", start: 5, end: 10, startPos: {line: 0, ch: 5}, endPos: {line: 0, ch: 10} }); expect(t.nextToken()).toEqual({ type: "attribvalue", contents: "foo bar", start: 12, end: 19, startPos: {line: 0, ch: 12}, endPos: {line: 0, ch: 19} }); expect(t.nextToken()).toEqual({ type: "attribname", contents: "style", start: 21, end: 26, startPos: {line: 0, ch: 21}, endPos: {line: 0, ch: 26} }); expect(t.nextToken()).toEqual({ type: "attribvalue", contents: "baz: quux", start: 28, end: 37, startPos: {line: 0, ch: 28}, endPos: {line: 0, ch: 37} }); expect(t.nextToken()).toEqual({ type: "attribname", contents: "checked", start: 39, end: 46, startPos: {line: 0, ch: 39}, endPos: {line: 0, ch: 46} }); expect(t.nextToken()).toEqual({ type: "opentagend", contents: "", start: -1, end: 47, startPos: null, endPos: {line: 0, ch: 47} }); expect(t.nextToken()).toEqual({ type: "closetag", contents: "div", start: 49, end: 52, startPos: {line: 0, ch: 49}, endPos: {line: 0, ch: 52} }); expect(t.nextToken()).toEqual(null); }); it("should handle various newline cases", function () { var t = new Tokenizer("<div \n class='foo'\n checked>\n some text\n with a newline\n <br/>\n<!--multiline\ncomment-->\n</div>"); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "div", start: 1, end: 4, startPos: {line: 0, ch: 1}, endPos: {line: 0, ch: 4} }); expect(t.nextToken()).toEqual({ type: "attribname", contents: "class", start: 10, end: 15, startPos: {line: 1, ch: 4}, endPos: {line: 1, ch: 9} }); expect(t.nextToken()).toEqual({ type: "attribvalue", contents: "foo", start: 17, end: 20, startPos: {line: 1, ch: 11}, endPos: {line: 1, ch: 14} }); expect(t.nextToken()).toEqual({ type: "attribname", contents: "checked", start: 26, end: 33, startPos: {line: 2, ch: 4}, endPos: {line: 2, ch: 11} }); expect(t.nextToken()).toEqual({ type: "opentagend", contents: "", start: -1, end: 34, startPos: null, endPos: {line: 2, ch: 12} }); expect(t.nextToken()).toEqual({ type: "text", contents: "\n some text\n with a newline\n ", start: 34, end: 72, startPos: {line: 2, ch: 12}, endPos: {line: 5, ch: 4} }); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "br", start: 73, end: 75, startPos: {line: 5, ch: 5}, endPos: {line: 5, ch: 7} }); expect(t.nextToken()).toEqual({ type: "selfclosingtag", contents: "", start: -1, end: 77, startPos: null, endPos: {line: 5, ch: 9} }); expect(t.nextToken()).toEqual({ type: "text", contents: "\n", start: 77, end: 78, startPos: {line: 5, ch: 9}, endPos: {line: 6, ch: 0} }); expect(t.nextToken()).toEqual({ type: "comment", contents: "multiline\ncomment", start: 82, end: 99, startPos: {line: 6, ch: 4}, endPos: {line: 7, ch: 7} }); expect(t.nextToken()).toEqual({ type: "text", contents: "\n", start: 102, end: 103, startPos: {line: 7, ch: 10}, endPos: {line: 8, ch: 0} }); expect(t.nextToken()).toEqual({ type: "closetag", contents: "div", start: 105, end: 108, startPos: {line: 8, ch: 2}, endPos: {line: 8, ch: 5} }); }); it("should notify of explicit shorttags like <br/>", function () { var t = new Tokenizer("<p>hello<br/></p>"); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "p", start: 1, end: 2, startPos: {line: 0, ch: 1}, endPos: {line: 0, ch: 2} }); expect(t.nextToken()).toEqual({ type: "opentagend", contents: "", start: -1, end: 3, startPos: null, endPos: {line: 0, ch: 3} }); expect(t.nextToken()).toEqual({ type: "text", contents: "hello", start: 3, end: 8, startPos: {line: 0, ch: 3}, endPos: {line: 0, ch: 8} }); expect(t.nextToken()).toEqual({ type: "opentagname", contents: "br", start: 9, end: 11, startPos: {line: 0, ch: 9}, endPos: {line: 0, ch: 11} }); expect(t.nextToken()).toEqual({ type: "selfclosingtag", contents: "", start: -1, end: 13, startPos: null, endPos: {line: 0, ch: 13} }); expect(t.nextToken()).toEqual({ type: "closetag", contents: "p", start: 15, end: 16, startPos: {line: 0, ch: 15}, endPos: {line: 0, ch: 16} }); }); it("should parse a comment", function () { var t = new Tokenizer("<!--very important-->"); expect(t.nextToken()).toEqual({ type: "comment", contents: "very important", start: 4, end: 18, startPos: {line: 0, ch: 4}, endPos: {line: 0, ch: 18} }); }); describe("error cases", function () { function expectError(text, isError) { if (isError === undefined) { isError = true; } var t = new Tokenizer(text), token = t.nextToken(); while (token) { if (token.type === "error") { if (!isError) { expect("found an error token").toBe(false); } return; } token = t.nextToken(); } if (isError) { expect("found an error token").toBe(true); } } it("should not fail for a comment", function () { expectError("<!--a comment-->", false); }); it("should not fail for a tag with a mix of attribute styles", function () { expectError("<goodtag goodname=goodvalue goodname='goodvalue' goodname=\"goodvalue\" goodemptyname attrwithspace = attrval></goodtag>", false); }); it("should not fail for a tag with a quoted attribute at the end of the tag", function () { expectError("<goodtag goodname=\"goodvalue\"></goodtag>", false); }); it("should not fail for a tag with a quoted attribute followed by whitespace at the end of the tag", function () { expectError("<goodtag goodname=\"goodvalue\" ></goodtag>", false); }); it("should not fail for a tag with an unquoted attribute followed by whitespace at the end of the tag", function () { expectError("<goodtag goodname=goodvalue ></goodtag>", false); }); it("should fail for an angle bracket before a tag", function () { expectError("<<notatag>"); }); it("should fail for an angle bracket in a tag", function () { expectError("<not<atag>"); }); it("should fail for an angle bracket before an attribute name", function () { expectError("<tag <notattr>"); }); it("should fail for an angle bracket in an attribute name", function () { expectError("<tag not<attr>"); }); it("should fail for an angle bracket before a value", function () { expectError("<tag attr=<notvalue>"); }); it("should fail for an angle bracket inside a value", function () { expectError("<tag attr=not<value>"); }); it("should fail for an angle bracket before a close tag", function () { expectError("</<notatag>"); }); it("should fail for an angle bracket in a close tag", function () { expectError("</not<atag>"); }); it("should fail for unclosed open tag at EOF", function () { expectError("<unclosedopentag"); }); it("should fail for unfinished attr at EOF", function () { expectError("<tag unfinishedattr="); }); it("should fail for unfinished single-quoted value at EOF", function () { expectError("<tag attr='unfinishedval"); }); it("should fail for unfinished double-quoted value at EOF", function () { expectError("<tag attr=\"unfinishedval"); }); it("should fail for extra text between / and > in a self-close tag", function () { expectError("<img / >"); }); it("should fail for unmatched double-quotes when there is a slash after the next double-quote", function () { expectError("<p style=\"something></p><img src=\"foo/bar\">"); }); it("should fail if there is no whitespace between the end of an attribute and the next attribute name", function () { expectError("<p attr=\"val\"attr2=\"val\"></p>"); }); it("should allow a hyphen in a custom tag name", function () { expectError("<custom-tag></custom-tag>", false); }); }); }); });