Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_js.py   Sprache: Python

 
""" Tests for the JS parser. """

import unittest
import jsparagus.lexer
from js_parser.parser import parse_Script, JSParser
from js_parser.lexer import JSLexer


class ESTestCase(unittest.TestCase):
    def parse(self, s):
        if isinstance(s, list):
            f = JSLexer(JSParser())
            for chunk in s:
                f.write(chunk)
            return f.close()
        else:
            return parse_Script(s)

    def assert_parses(self, s):
        self.parse(s)

    def assert_incomplete(self, s):
        """Assert that s fails to parse with UnexpectedEndError.

        (This should be the case if `s` is a prefix of a valid Script.)
        """
        self.assertRaises(jsparagus.lexer.UnexpectedEndError,
                          lambda: parse_Script(s))

    def assert_syntax_error(self, s):
        """Assert that s fails to parse."""
        with self.assertRaises(jsparagus.lexer.SyntaxError):
            parse_Script(s)

    def assert_can_close_after(self, s):
        parser = JSParser()
        lexer = JSLexer(parser)
        if isinstance(s, list):
            for chunk in s:
                lexer.write(chunk)
        else:
            lexer.write(s)
        self.assertTrue(lexer.can_close())

    # === Tests!

    def test_asi_at_end(self):
        self.assert_parses("3 + 4")
        self.assert_syntax_error("3 4")
        self.assert_incomplete("3 +")
        self.assert_incomplete("{")
        self.assert_incomplete("{;")

    def test_asi_at_block_end(self):
        self.assert_parses("{ doCrimes() }")
        self.assert_parses("function f() { ok }")

    def test_asi_after_line_terminator(self):
        self.assert_parses('''\
           switch (value) {
             case 1: break
             case 2: console.log('2');
           }
        ''')
        self.assert_syntax_error(
            "switch (value) { case 1: break case 2: console.log('2'); }")

    def test_asi_after_no_line_terminator_here(self):
        self.assert_parses('''\
           function f() {
             return
               x;
           }
        ''')

    def test_asi_suppressed(self):
        # The specification says ASI does not happen in the production
        # EmptyStatement : `;`.
        self.assert_syntax_error("if (true)")
        self.assert_syntax_error("{ for (;;) }")

        # ASI does not happen in for(;;) loops.
        self.assert_syntax_error("for ( \n ; ) {}")
        self.assert_syntax_error("for ( ; \n ) {}")
        self.assert_syntax_error("for ( \n \n ) {}")
        self.assert_syntax_error("for (var i = 0 \n i < 9; i++) {}")
        self.assert_syntax_error("for (var i = 0; i < 9 \n i++) {}")
        self.assert_syntax_error("for (i = 0 \n i < 9; i++) {}")
        self.assert_syntax_error("for (i = 0; i < 9 \n i++) {}")
        self.assert_syntax_error("for (let i = 0 \n i < 9; i++) {}")

        # ASI is suppressed in the production ClassElement[Yield, Await] : `;`
        # to prevent an infinite loop of ASI. lol
        self.assert_syntax_error("class Fail { \n +1; }")

    def test_if_else(self):
        self.assert_parses("if (x) f();")
        self.assert_incomplete("if (x)")
        self.assert_parses("if (x) f(); else g();")
        self.assert_incomplete("if (x) f(); else")
        self.assert_parses("if (x) if (y) g(); else h();")
        self.assert_parses("if (x) if (y) g(); else h(); else j();")

    def test_lexer_decimal(self):
        self.assert_parses("0.")
        self.assert_parses(".5")
        self.assert_syntax_error(".")

    def test_arrow(self):
        self.assert_parses("x => x")
        self.assert_parses("f = x => x;")
        self.assert_parses("(x, y) => [y, x]")
        self.assert_parses("f = (x, y) => {}")
        self.assert_syntax_error("(x, y) => {x: x, y: y}")

    def test_invalid_character(self):
        self.assert_syntax_error("\0")
        self.assert_syntax_error("—x;")
        self.assert_syntax_error("const ONE_THIRD = 1 ÷ 3;")

    def test_regexp(self):
        self.assert_parses(r"/\w/")
        self.assert_parses("/[A-Z]/")
        self.assert_parses("/[//]/")
        self.assert_parses("/a*a/")
        self.assert_parses("/**//x*/")
        self.assert_parses("{} /x/")
        self.assert_parses("of / 2")

    def test_incomplete_comments(self):
        self.assert_syntax_error("/*")
        self.assert_syntax_error("/* hello world")
        self.assert_syntax_error("/* hello world *")
        self.assert_parses(["/* hello\n"" world */"])
        self.assert_parses(["// oawfeoiawj""ioawefoawjie"])
        self.assert_parses(["// oawfeoiawj""ioawefoawjie\n ok();"])
        self.assert_parses(["// oawfeoiawj""ioawefoawjie""jiowaeawojefiw"])
        self.assert_parses(["// oawfeoiawj""ioawefoawjie""jiowaeawojefiw\n ok();"])

    def test_awkward_chunks(self):
        self.assert_parses(["let""ter.head = 1;"])
        self.assert_parses(["let"" x = 1;"])

        # `list()` here explodes the string into a list of one-character strings.
        self.assert_parses(list("function f() { ok(); }"))

        self.assertEqual(
            self.parse(["/xyzzy/""g;"]),
            ('script',
             ('script_body',
              ('statement_list_single',
               ('expression_statement',
                ('regexp_literal''/xyzzy/g'))))))

        self.assertEqual(
            self.parse(['x/''=2;']),
            ('script',
             ('script_body',
              ('statement_list_single',
               ('expression_statement',
                ('compound_assignment_expr',
                 ('identifier_expr', ('identifier_reference''x')),
                 ('box_assign_op', ('div_assign_op''/=')),
                 ('numeric_literal''2')))))))

    def test_can_close(self):
        self.assert_can_close_after([])
        self.assert_can_close_after("")
        self.assert_can_close_after("2 + 2;\n")
        self.assert_can_close_after("// seems ok\n")

    def test_can_close_with_asi(self):
        self.assert_can_close_after("2 + 2\n")

    def test_conditional_keywords(self):
        # property names
        self.assert_parses("let obj = {if: 3, function: 4};")
        self.assert_parses("assert(obj.if == 3);")

        # method names
        self.assert_parses("""
            class C {
                if() {}
                function() {}
            }
        """)

        self.assert_parses("var let = [new Date];")    # let as identifier
        self.assert_parses("let v = let;")             # let as keyword, then identifier
        # Next line would fail because the multitoken `let [` lookahead isn't implemented yet.
        # self.assert_parses("let.length;")            # `let .` -> ExpressionStatement
        self.assert_syntax_error("let[0].getYear();")  # `let [` -> LexicalDeclaration

        self.assert_parses("""
            var of = [1, 2, 3];
            for (of of of) console.log(of);  // logs 1, 2, 3
        """)
        self.assert_parses("var of, let, private, target;")
        self.assert_parses("class X { get y() {} }")
        self.assert_parses("async: { break async; }")
        self.assert_parses("var get = { get get() {}, set get(v) {}, set: 3 };")
        self.assert_parses("for (async of => {};;) {}")
        # self.assert_parses("for (async of []) {}")  # would fail


if __name__ == '__main__':
    unittest.main()

Messung V0.5
C=93 H=88 G=90

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge