コード例 #1
0
ファイル: ua_test.go プロジェクト: h12w/gombi
			{
				Name: "Firefox",
				Version: Version{
					Text: "31.0",
				},
			},
		},
	},
}

var _ = gspec.Add(func(s gspec.S) {
	testcase := s.Alias("testcase:")
	expect := gspec.Expect(s.FailNow)
	for i, tc := range testcases {
		testcase(strconv.Itoa(i), func() {
			r, err := ParseUserAgent(tc.str)
			expect(err).Equal(nil)
			expect(r).Equal(tc.ua)
		})
	}
})

func TestAll(t *testing.T) {
	gspec.Test(t)
}

func init() {
	gspec.SetSprint(flowPrint)
}

func flowPrint(v interface{}) string {
コード例 #2
0
ファイル: scan_test.go プロジェクト: h12w/gombi
var _ = gspec.Add(func(s gspec.S) {
	describe, given, it, they, and := gspec.Alias5("describe", "given", "it", "they", "and", s)
	expect := gspec.Expect(s.FailNow)
	describe("patterns", func() {
		given("a pattern", func() {
			a := Pat("ab")
			it("can be repeated zero or one time", func() {
				expect(a.ZeroOrOne().String()).Equal("(?:ab)?")
			})
			it("can be repeated zero or more times", func() {
				expect(a.ZeroOrMore().String()).Equal("(?:ab)*")
			})
			it("can be repeated one or more times", func() {
				expect(a.OneOrMore().String()).Equal("(?:ab)+")
			})
		})
		given("multiple patterns", func() {
			a, b, c := Pat("aa"), Pat("bb"), Pat("cc")
			they("can be concatenated into one pattern", func() {
				one := Con(a, b, c)
				expect(one.String()).Equal("aabbcc")
			})
			they("can be alternative choices", func() {
				alt := Or(a, b, c)
				expect(alt.String()).Equal("aa|bb|cc")
			})
		})
	})
	describe("character sets", func() {
		given("a character set", func() {
			c := Char(`abcde`)
			it("can be converted to a canonical pattern", func() {
				expect(c.String()).Equal(`[a-e]`)
			})
			it("can be negated", func() {
				nc := c.Negate()
				expect(nc.String()).Equal(`[^a-e]`)
				and("the original pattern is not changed by the negation", func() {
					expect(c.String()).Equal(`[a-e]`)
				})
				and("the negated pattern can be negated back", func() {
					expect(nc.Negate().String()).Equal(`[a-e]`)
				})
			})
			it("can exclude a subset", func() {
				expect(c.Exclude(Char(`bd`)).String()).Equal(`[ace]`)
			})
		})
		given("a character set with a single element (OpLiteral)", func() {
			a := Char(`a`)
			it("can be negated", func() {
				na := a.Negate()
				expect(na.String()).Equal(`[^a]`)
				expect(na.Negate().String()).Equal(`[a]`)
			})
		})
		given("a character set with an letter of upper and lower case (OpLiteral)", func() {
			x := Char(`xX`)
			it("has a canonical form of character set", func() {
				expect(x.String()).Equal(`[Xx]`)
			})
			it("can be negated", func() {
				nx := x.Negate()
				expect(nx.String()).Equal(`[^Xx]`)
				expect(nx.Negate().String()).Equal(`[Xx]`)
			})
		})
		given("multiple character sets", func() {
			a := Char(`a`)
			mn := Char(`mn`)
			z := Char(`z`)
			they("can be merged into one character set", func() {
				one := Merge(a, mn, z)
				expect(one.String()).Equal(`[am-nz]`)
			})
		})
	})
	describe("the scanner", func() {
		a := Char(`a`)
		s := Char(` `)
		b := Char(`b`)
		m := NewMatcher(a, s, b)
		scanner, _ := NewStringScanner(m, "b a")
		expect(scanner.Scan()).Equal(true)
		expect(scanner.Error()).Equal(nil)
		expect(scanner.Token()).Equal(
			&Token{
				ID:    3,
				Value: []byte("b"),
				Pos:   0,
			})
		expect(scanner.Scan()).Equal(true)
		expect(scanner.Error()).Equal(nil)
		expect(scanner.Token()).Equal(
			&Token{
				ID:    2,
				Value: []byte(" "),
				Pos:   1,
			})
		expect(scanner.Scan()).Equal(true)
		expect(scanner.Error()).Equal(nil)
		expect(scanner.Token()).Equal(
			&Token{
				ID:    1,
				Value: []byte("a"),
				Pos:   2,
			})
		expect(scanner.Scan()).Equal(true)
		expect(scanner.Error()).Equal(nil)
		expect(scanner.Token()).Equal(
			&Token{
				ID:    EOF,
				Value: nil,
				Pos:   3,
			})
		expect(scanner.Scan()).Equal(false)
		expect(scanner.Error()).Equal(nil)
	})
})
コード例 #3
0
ファイル: parse_test.go プロジェクト: h12w/gombi
var _ = gspec.Add(func(s gspec.S) {
	describe, testcase, given := gspec.Alias3("describe", "testcase:", "given", s)

	describe("the parser", func() {

		given("simple arithmetic grammar", func() {
			b := NewBuilder()
			Term, Or, Con := b.Term, b.Or, b.Con
			var (
				T    = Term("T")
				Plus = Term(`+`)
				Mult = Term(`*`)
				M    = NewRule().As("M")
				_    = M.Define(Or(
					T,
					Con(M, Mult, T),
				))
				S = NewRule().As("S")
				_ = S.Define(Or(
					Con(S, Plus, M),
					M,
				))
				P = Con(S, EOF).As("P")
			)
			P.InitTermSet()
			testcase("assotitivity", func() {
				testParse(s, P, TT{
					tok("1", T),
					tok("+", Plus),
					tok("2", T),
					tok("+", Plus),
					tok("3", T),
				}, `
			P ::= S EOF
				S ::= S + M
					S ::= S + M
						S ::= M
							M ::= T
								T ::= 1
						+ ::= +
						M ::= T
							T ::= 2
					+ ::= +
					M ::= T
						T ::= 3
				EOF ::= `)
			})
			testcase("precedence", func() {
				testParse(s, P, TT{
					tok("2", T),
					tok("+", Plus),
					tok("3", T),
					tok("*", Mult),
					tok("4", T),
				}, `
			P ::= S EOF
				S ::= S + M
					S ::= M
						M ::= T
							T ::= 2
					+ ::= +
					M ::= M * T
						M ::= T
							T ::= 3
						* ::= *
						T ::= 4
				EOF ::= `)
			})
		})

		given("a grammar with nullable rule", func() {
			b := NewBuilder()
			Term, Con, Or := b.Term, b.Con, b.Or
			var (
				A = Term("A")
				B = Term("B")
				C = Term("C")
				P = Con(Or(Con(A, B), A).As("AX"), C, EOF).As("P")
			)
			P.InitTermSet()

			testcase("a sequence without the optional token", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("C", C),
				}, `
				P ::= AX C EOF
					AX ::= A
						A ::= A
					C ::= C
					EOF ::= `,
				)
			})

			testcase("a sequence with the optional token", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("B", B),
					tok("C", C),
				}, `
				P ::= AX C EOF
					AX ::= A B
						A ::= A
						B ::= B
					C ::= C
					EOF ::= `)
			})
		})

		given("a grammar with zero or more repetition", func() {
			b := NewBuilder()
			Term, Con, Or := b.Term, b.Con, b.Or
			var (
				A = Term("A")
				B = Term("B")
				X = B.AtLeast(1).As("X")
				C = Term("C")
				P = Con(A, Or(C, Con(X, C)).As("XC"), EOF).As("P")
			)
			P.InitTermSet()
			testcase("zero", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("C", C),
				}, `
			P ::= A XC EOF
				A ::= A
				XC ::= C
					C ::= C
				EOF ::= `)
			})

			testcase("one", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("B", B),
					tok("C", C),
				}, `
			P ::= A XC EOF
				A ::= A
				XC ::= X C
					X ::= B
						B ::= B
					C ::= C
				EOF ::= `)
			})

			testcase("two", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("B", B),
					tok("B", B),
					tok("C", C),
				}, `
			P ::= A XC EOF
				A ::= A
				XC ::= X C
					X ::= B X
						B ::= B
						X ::= B
							B ::= B
					C ::= C
				EOF ::= `)
			})
		})

		given("a grammar with common prefix", func() {
			b := NewBuilder()
			Term, Or, Con := b.Term, b.Or, b.Con
			var (
				A = Term("A")
				B = Term("B")
				X = Con(A).As("X")
				Y = Con(A, B).As("Y")
				S = Or(X, Y).As("S")
				P = Con(S, EOF).As("P")
			)
			P.InitTermSet()
			testcase("short", func() {
				testParse(s, P, TT{
					tok("A", A),
				}, `
			P ::= S EOF
				S ::= X
					X ::= A
				EOF ::= `)
			})
			testcase("short", func() {
				testParse(s, P, TT{
					tok("A", A),
					tok("B", B),
				}, `
			P ::= S EOF
				S ::= Y
					Y ::= X B
						X ::= A
						B ::= B
				EOF ::= `)
			})

		})
	})
})