aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/parcom_spec.cr183
-rw-r--r--spec/spec_helper.cr2
2 files changed, 185 insertions, 0 deletions
diff --git a/spec/parcom_spec.cr b/spec/parcom_spec.cr
new file mode 100644
index 0000000..a496a3f
--- /dev/null
+++ b/spec/parcom_spec.cr
@@ -0,0 +1,183 @@
+require "./spec_helper"
+
+require "../src/parcom.cr"
+
+include Parcom
+
+describe Result do
+ describe "#initialize" do
+ it "sets values for #tokens and #value" do
+ tokens = "esting".chars
+ value = 't'
+ result = Result(Char, Char).new(tokens, value)
+
+ result.tokens.should eq(tokens)
+ result.value.should eq(value)
+ end
+ end
+end
+
+describe Parser do
+ describe "#|" do
+ it "creates an `Alt` instance from `self` and another `Parser(T, V)`" do
+ p = AnyToken(Char).new | AnyToken(Char).new
+
+ p.should be_a(Alt(Char, Char))
+ end
+ end
+
+ describe "#assert" do
+ it "creates an `Assert` instance from self and a `Proc(T, Bool)`" do
+ f = ->(x : Char) { x == '#' }
+ p = AnyToken(Char).new.assert(f)
+
+ p.should be_a(Assert(Char, Char))
+ end
+ end
+end
+
+describe Flunk do
+ describe "#parse" do
+ it "always fails" do
+ tokens = "testing".chars
+ expect_raises(ParserException) { Flunk(Char, Char).new.parse(tokens) }
+ end
+ end
+end
+
+describe AnyToken do
+ describe "#parse" do
+ it "succeeds when input is non-empty" do
+ tokens = "testing".chars
+ result = AnyToken(Char).new.parse(tokens)
+
+ result.tokens.should eq(tokens[1..])
+ result.value.should eq('t')
+ end
+
+ it "fails when input is empty" do
+ expect_raises(ParserException) { AnyToken(Char).new.parse([] of Char) }
+ end
+ end
+end
+
+describe Eof do
+ describe "#parse" do
+ it "succeeds when input is empty" do
+ result = Eof(Char).new.parse([] of Char)
+
+ result.tokens.empty?.should be_true
+ result.value.should be_nil
+ end
+
+ it "fails when input is non-empty" do
+ tokens = "testing".chars
+
+ expect_raises(ParserException) { Eof(Char).new.parse(tokens) }
+ end
+ end
+end
+
+describe Peek do
+ describe "#parse" do
+ it "does not modify the result of the wrapped parser" do
+ tokens = "testing".chars
+ parser = AnyToken(Char).new
+ result_normal = parser.parse(tokens)
+ result_peek = Peek.new(parser).parse(tokens)
+
+ result_peek.value.should eq(result_normal.value)
+ end
+
+ it "does not consume any input" do
+ tokens = "testing".chars
+ parser = AnyToken(Char).new
+ result = Peek.new(parser).parse(tokens)
+
+ result.tokens.should eq(tokens)
+ end
+ end
+end
+
+describe Assert do
+ describe "#parse" do
+ it "fails if the wrapped parser fails" do
+ test = ->(x : Char) { true } # doesn't matter for this test
+ p = Assert.new(AnyToken(Char).new, test)
+ expect_raises(ParserException) { p.parse([] of Char) }
+ end
+
+ it "fails if the result value fails the test" do
+ tokens = "testing".chars
+ test = ->(x : Char) { x == '$' }
+ p = Assert.new(AnyToken(Char).new, test)
+ expect_raises(ParserException) { p.parse(tokens) }
+ end
+
+ it "succeeds if the wrapped parser succeeds and the test passes" do
+ tokens = "testing".chars
+ expected_char = tokens[0]
+ test = ->(x : Char) { x == expected_char }
+ p = Assert.new(AnyToken(Char).new, test)
+ result = p.parse(tokens)
+
+ result.value.should eq(expected_char)
+ test.call(expected_char).should be_true
+ end
+ end
+end
+
+describe Satisfy do
+ describe "#parse" do
+ it "fails if there are input is empty" do
+ test = ->(x : Char) { x == '#' } # doesn't matter for this case
+ p = Satisfy(Char).new(test)
+
+ expect_raises(ParserException) { p.parse([] of Char) }
+ end
+
+ it "fails if the token fails the test" do
+ tokens = "testing".chars
+ test = ->(x : Char) { x == '#' }
+ p = Satisfy(Char).new(test)
+
+ expect_raises(ParserException) { p.parse(tokens) }
+ end
+
+ it "succeeds if the token passes the test" do
+ tokens = "testing".chars
+ expected_char = tokens[0]
+ test = ->(x : Char) { x == expected_char }
+ p = Satisfy(Char).new(test)
+ result = p.parse(tokens)
+
+ result.value.should eq(expected_char)
+ test.call(result.value).should be_true
+ end
+ end
+end
+
+describe Token do
+ describe "#parse" do
+ it "fails if the input is empty" do
+ expect_raises(ParserException) { Token(Char).new('t').parse([] of Char) }
+ end
+
+ it "fails if the token is not the expected token" do
+ tokens = "testing".chars
+ p = Token(Char).new('#')
+
+ expect_raises(ParserException) { p.parse(tokens) }
+ end
+
+ it "succeeds if the token is the expected token" do
+ tokens = "testing".chars
+ expected_char = tokens[0]
+ p = Token(Char).new(expected_char)
+ result = p.parse(tokens)
+
+ result.value.should eq(expected_char)
+ end
+ end
+end
+
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
new file mode 100644
index 0000000..3a4747e
--- /dev/null
+++ b/spec/spec_helper.cr
@@ -0,0 +1,2 @@
+require "spec"
+require "../src/parcom"