// // dice_test.cxx // dice-td // // Created by Sam Jaffe on 12/17/18. // Copyright © 2018 Sam Jaffe. All rights reserved. // #include #include "xcode_gtest_helper.h" #include "dice-roll/die.h" #include "dice-roll/exception.h" using unsigned_die = std::pair; namespace dice { bool operator==(die const & lhs, die const & rhs) { return lhs.sgn == rhs.sgn && lhs.num == rhs.num && lhs.sides == rhs.sides; } bool operator==(die const & lhs, unsigned_die const & rhs) { return lhs.num == rhs.first && lhs.sides == rhs.second; } } using namespace ::testing; TEST(ParserTest, ThrowsOnEmptyString) { EXPECT_THROW(dice::from_string(""), dice::unexpected_token); } TEST(ParserTest, ThrowsOnOpeningArithmetic) { EXPECT_THROW(dice::from_string("+5"), dice::unexpected_token); EXPECT_THROW(dice::from_string("-5"), dice::unexpected_token); EXPECT_THROW(dice::from_string("+1d4"), dice::unexpected_token); EXPECT_THROW(dice::from_string("-1d4"), dice::unexpected_token); } TEST(ParserTest, Implicit1dN) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("d4")); EXPECT_THAT(capture.num, Eq(1)); EXPECT_THAT(capture.of, SizeIs(1)); EXPECT_THAT(capture.of[0], Eq(unsigned_die(1, 4))); } TEST(ParserTest, Explicit1dN) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("1d4")); EXPECT_THAT(capture.num, Eq(1)); EXPECT_THAT(capture.of, SizeIs(1)); EXPECT_THAT(capture.of[0], Eq(unsigned_die(1, 4))); } TEST(ParserTest, CannotImplicitNumberOfSides) { EXPECT_THROW(dice::from_string("1d"), dice::unexpected_token); } TEST(ParserTest, AllowsMultipleDice) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("1d4+1d6")); EXPECT_THAT(capture.of, SizeIs(2)); EXPECT_THAT(capture.of, ElementsAre(Eq(unsigned_die(1, 4)), Eq(unsigned_die(1, 6)))); } TEST(ParserTest, CanIncludeConstant) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("1d4+1")); EXPECT_THAT(capture.of, SizeIs(1)); EXPECT_THAT(capture.modifier, SizeIs(1)); EXPECT_THAT(capture.modifier[0].value, 1); } TEST(ParserTest, ConstantSignIsInSgnMember) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("1d4-1")); EXPECT_THAT(capture.of, SizeIs(1)); EXPECT_THAT(capture.modifier, SizeIs(1)); EXPECT_THAT(capture.modifier[0].value, 1); } TEST(ParserTest, ThrowsIfUnterminatedArithmatic) { EXPECT_THROW(dice::from_string("1d4+"), dice::unexpected_token); } TEST(ParserTest, CanProduceMultiRollExpression) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("2{d4}")); EXPECT_THAT(capture.num, Eq(2)); EXPECT_THAT(capture.of, SizeIs(1)); } TEST(ParserTest, MultiRollWillThrowIfNoEndBrace) { EXPECT_THROW(dice::from_string("2{d4"), dice::unexpected_token); } TEST(ParserTest, IgnoresWhitespace) { dice::dice capture; EXPECT_NO_THROW(capture = dice::from_string("2 { d 4 + 5 }")); EXPECT_THAT(capture.num, Eq(2)); EXPECT_THAT(capture.of, SizeIs(1)); EXPECT_THAT(capture.modifier, SizeIs(1)); } TEST(ParserTest, CanParseDC) { EXPECT_NO_THROW(dice::from_string("1d20<10")); EXPECT_NO_THROW(dice::from_string("1d20<=10")); EXPECT_NO_THROW(dice::from_string("1d20>10")); EXPECT_NO_THROW(dice::from_string("1d20>=10")); } TEST(ParserTest, DCCannotBeNegative) { EXPECT_THROW(dice::from_string("1d20>-1"), dice::unexpected_token); } TEST(ParserTest, DCCanBeWhitespacePadded) { EXPECT_NO_THROW(dice::from_string("1d20 < 10")); } TEST(ParserTest, CanParseDCForMultiroll) { EXPECT_NO_THROW(dice::from_string("2{1d20<10}")); EXPECT_NO_THROW(dice::from_string("2{1d20<=10}")); EXPECT_NO_THROW(dice::from_string("2{1d20>10}")); EXPECT_NO_THROW(dice::from_string("2{1d20>=10}")); } TEST(ParserTest, MultirollDCMustAppearInsideBrackets) { EXPECT_NO_THROW(dice::from_string("2{1d20}<10")); EXPECT_NO_THROW(dice::from_string("2{1d20}<=10")); EXPECT_NO_THROW(dice::from_string("2{1d20}>10")); EXPECT_NO_THROW(dice::from_string("2{1d20}>=10")); } TEST(ParserTest, DCIsCaptured) { using test = dice::difficulty_class::test; EXPECT_THAT(dice::from_string("1d20<10").dc.against, 10); EXPECT_THAT(dice::from_string("1d20<10").dc.comp, test::Less); EXPECT_THAT(dice::from_string("1d20<=10").dc.comp, test::LessOrEqual); EXPECT_THAT(dice::from_string("1d20>10").dc.comp, test::Greater); EXPECT_THAT(dice::from_string("1d20>=10").dc.comp, test::GreaterOrEqual); }