# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # from qpid.tests import Test from qpid.address import lex, parse, ParseError, EOF, ID, NUMBER, SYM, WSPACE class AddressTests(Test): def lex(self, addr, *types): toks = [t.type for t in lex(addr) if t.type not in (WSPACE, EOF)] assert list(types) == toks, "expected %s, got %s" % (types, toks) def testDashInId1(self): self.lex("foo-bar", ID) def testDashInId2(self): self.lex("foo-3", ID) def testDashAlone1(self): self.lex("foo - bar", ID, SYM, ID) def testDashAlone2(self): self.lex("foo - 3", ID, SYM, NUMBER) def testLeadingDash(self): self.lex("-foo", SYM, ID) def testTrailingDash(self): self.lex("foo-", ID, SYM) def testNegativeNum(self): self.lex("-3", NUMBER) def valid(self, addr, name=None, subject=None, options=None): expected = (name, subject, options) got = parse(addr) assert expected == got, "expected %s, got %s" % (expected, got) def invalid(self, addr, error=None): try: p = parse(addr) assert False, "invalid address parsed: %s" % p except ParseError, e: assert error == str(e), "expected %r, got %r" % (error, str(e)) def testHash(self): self.valid("foo/bar.#", "foo", "bar.#") def testStar(self): self.valid("foo/bar.*", "foo", "bar.*") def testColon(self): self.valid("foo.bar/baz.qux:moo:arf", "foo.bar", "baz.qux:moo:arf") def testOptions(self): self.valid("foo.bar/baz.qux:moo:arf; {key: value}", "foo.bar", "baz.qux:moo:arf", {"key": "value"}) def testOptionsTrailingComma(self): self.valid("name/subject; {key: value,}", "name", "subject", {"key": "value"}) def testSemiSubject(self): self.valid("foo.bar/'baz.qux;moo:arf'; {key: value}", "foo.bar", "baz.qux;moo:arf", {"key": "value"}) def testCommaSubject(self): self.valid("foo.bar/baz.qux.{moo,arf}", "foo.bar", "baz.qux.{moo,arf}") def testCommaSubjectOptions(self): self.valid("foo.bar/baz.qux.{moo,arf}; {key: value}", "foo.bar", "baz.qux.{moo,arf}", {"key": "value"}) def testUnbalanced(self): self.valid("foo.bar/baz.qux.{moo,arf; {key: value}", "foo.bar", "baz.qux.{moo,arf", {"key": "value"}) def testSlashQuote(self): self.valid("foo.bar\\/baz.qux.{moo,arf; {key: value}", "foo.bar/baz.qux.{moo,arf", None, {"key": "value"}) def testSlashHexEsc1(self): self.valid("foo.bar\\x00baz.qux.{moo,arf; {key: value}", "foo.bar\x00baz.qux.{moo,arf", None, {"key": "value"}) def testSlashHexEsc2(self): self.valid("foo.bar\\xffbaz.qux.{moo,arf; {key: value}", "foo.bar\xffbaz.qux.{moo,arf", None, {"key": "value"}) def testSlashHexEsc3(self): self.valid("foo.bar\\xFFbaz.qux.{moo,arf; {key: value}", "foo.bar\xFFbaz.qux.{moo,arf", None, {"key": "value"}) def testSlashUnicode1(self): self.valid("foo.bar\\u1234baz.qux.{moo,arf; {key: value}", u"foo.bar\u1234baz.qux.{moo,arf", None, {"key": "value"}) def testSlashUnicode2(self): self.valid("foo.bar\\u0000baz.qux.{moo,arf; {key: value}", u"foo.bar\u0000baz.qux.{moo,arf", None, {"key": "value"}) def testSlashUnicode3(self): self.valid("foo.bar\\uffffbaz.qux.{moo,arf; {key: value}", u"foo.bar\uffffbaz.qux.{moo,arf", None, {"key": "value"}) def testSlashUnicode4(self): self.valid("foo.bar\\uFFFFbaz.qux.{moo,arf; {key: value}", u"foo.bar\uFFFFbaz.qux.{moo,arf", None, {"key": "value"}) def testNoName(self): self.invalid("; {key: value}", "unexpected token SEMI(';') line:1,0:; {key: value}") def testEmpty(self): self.invalid("", "unexpected token EOF line:1,0:") def testNoNameSlash(self): self.invalid("/asdf; {key: value}", "unexpected token SLASH('/') line:1,0:/asdf; {key: value}") def testBadOptions1(self): self.invalid("name/subject; {", "expecting (ID, RBRACE), got EOF line:1,15:name/subject; {") def testBadOptions2(self): self.invalid("name/subject; { 3", "expecting (ID, RBRACE), got NUMBER('3') " "line:1,16:name/subject; { 3") def testBadOptions3(self): self.invalid("name/subject; { key:", "expecting (NUMBER, STRING, ID, LBRACE), got EOF " "line:1,20:name/subject; { key:") def testBadOptions4(self): self.invalid("name/subject; { key: value", "expecting (COMMA, RBRACE), got EOF " "line:1,26:name/subject; { key: value") def testBadOptions5(self): self.invalid("name/subject; { key: value asdf", "expecting (COMMA, RBRACE), got ID('asdf') " "line:1,27:name/subject; { key: value asdf") def testBadOptions6(self): self.invalid("name/subject; { key: value,", "expecting (ID, RBRACE), got EOF " "line:1,27:name/subject; { key: value,") def testBadOptions7(self): self.invalid("name/subject; { key: value } asdf", "expecting EOF, got ID('asdf') " "line:1,29:name/subject; { key: value } asdf")