@@ -30,25 +30,17 @@ TEST(TrueFalseTest, Basic) {
3030 auto false_instance = False::Instance ();
3131 auto negated = false_instance->Negate ();
3232
33- EXPECT_TRUE (negated.has_value ());
34-
3533 // Check that negated expression is True
36- auto true_expr = negated.value ();
37- EXPECT_EQ (true_expr->op (), Expression::Operation::kTrue );
38-
39- EXPECT_EQ (true_expr->ToString (), " true" );
34+ EXPECT_EQ (negated->op (), Expression::Operation::kTrue );
35+ EXPECT_EQ (negated->ToString (), " true" );
4036
4137 // Test negation of True returns false
4238 auto true_instance = True::Instance ();
4339 negated = true_instance->Negate ();
4440
45- EXPECT_TRUE (negated.has_value ());
46-
4741 // Check that negated expression is False
48- auto false_expr = negated.value ();
49- EXPECT_EQ (false_expr->op (), Expression::Operation::kFalse );
50-
51- EXPECT_EQ (false_expr->ToString (), " false" );
42+ EXPECT_EQ (negated->op (), Expression::Operation::kFalse );
43+ EXPECT_EQ (negated->ToString (), " false" );
5244}
5345
5446TEST (ANDTest, Basic) {
@@ -64,4 +56,102 @@ TEST(ANDTest, Basic) {
6456 EXPECT_EQ (and_expr->left ()->op (), Expression::Operation::kTrue );
6557 EXPECT_EQ (and_expr->right ()->op (), Expression::Operation::kTrue );
6658}
59+
60+ TEST (ORTest, Basic) {
61+ // Create True and False expressions
62+ auto true_expr = True::Instance ();
63+ auto false_expr = False::Instance ();
64+
65+ // Create an OR expression
66+ auto or_expr = std::make_shared<Or>(true_expr, false_expr);
67+
68+ EXPECT_EQ (or_expr->op (), Expression::Operation::kOr );
69+ EXPECT_EQ (or_expr->ToString (), " (true or false)" );
70+ EXPECT_EQ (or_expr->left ()->op (), Expression::Operation::kTrue );
71+ EXPECT_EQ (or_expr->right ()->op (), Expression::Operation::kFalse );
72+ }
73+
74+ TEST (ORTest, Negation) {
75+ // Test De Morgan's law: not(A or B) = (not A) and (not B)
76+ auto true_expr = True::Instance ();
77+ auto false_expr = False::Instance ();
78+
79+ auto or_expr = std::make_shared<Or>(true_expr, false_expr);
80+ auto negated_or = or_expr->Negate ();
81+
82+ // Should become AND expression
83+ EXPECT_EQ (negated_or->op (), Expression::Operation::kAnd );
84+ EXPECT_EQ (negated_or->ToString (), " (false and true)" );
85+ }
86+
87+ TEST (ORTest, Equals) {
88+ auto true_expr = True::Instance ();
89+ auto false_expr = False::Instance ();
90+
91+ // Test basic equality
92+ auto or_expr1 = std::make_shared<Or>(true_expr, false_expr);
93+ auto or_expr2 = std::make_shared<Or>(true_expr, false_expr);
94+ EXPECT_TRUE (or_expr1->Equals (*or_expr2));
95+
96+ // Test commutativity: (A or B) equals (B or A)
97+ auto or_expr3 = std::make_shared<Or>(false_expr, true_expr);
98+ EXPECT_TRUE (or_expr1->Equals (*or_expr3));
99+
100+ // Test inequality with different expressions
101+ auto or_expr4 = std::make_shared<Or>(true_expr, true_expr);
102+ EXPECT_FALSE (or_expr1->Equals (*or_expr4));
103+
104+ // Test inequality with different operation types
105+ auto and_expr = std::make_shared<And>(true_expr, false_expr);
106+ EXPECT_FALSE (or_expr1->Equals (*and_expr));
107+ }
108+
109+ TEST (ANDTest, Negation) {
110+ // Test De Morgan's law: not(A and B) = (not A) or (not B)
111+ auto true_expr = True::Instance ();
112+ auto false_expr = False::Instance ();
113+
114+ auto and_expr = std::make_shared<And>(true_expr, false_expr);
115+ auto negated_and = and_expr->Negate ();
116+
117+ // Should become OR expression
118+ EXPECT_EQ (negated_and->op (), Expression::Operation::kOr );
119+ EXPECT_EQ (negated_and->ToString (), " (false or true)" );
120+ }
121+
122+ TEST (ANDTest, Equals) {
123+ auto true_expr = True::Instance ();
124+ auto false_expr = False::Instance ();
125+
126+ // Test basic equality
127+ auto and_expr1 = std::make_shared<And>(true_expr, false_expr);
128+ auto and_expr2 = std::make_shared<And>(true_expr, false_expr);
129+ EXPECT_TRUE (and_expr1->Equals (*and_expr2));
130+
131+ // Test commutativity: (A and B) equals (B and A)
132+ auto and_expr3 = std::make_shared<And>(false_expr, true_expr);
133+ EXPECT_TRUE (and_expr1->Equals (*and_expr3));
134+
135+ // Test inequality with different expressions
136+ auto and_expr4 = std::make_shared<And>(true_expr, true_expr);
137+ EXPECT_FALSE (and_expr1->Equals (*and_expr4));
138+
139+ // Test inequality with different operation types
140+ auto or_expr = std::make_shared<Or>(true_expr, false_expr);
141+ EXPECT_FALSE (and_expr1->Equals (*or_expr));
142+ }
143+
144+ TEST (ExpressionTest, BaseClassNegateThrowsException) {
145+ // Create a mock expression that doesn't override Negate()
146+ class MockExpression : public Expression {
147+ public:
148+ Operation op () const override { return Operation::kTrue ; }
149+ // Deliberately not overriding Negate() to test base class behavior
150+ };
151+
152+ auto mock_expr = std::make_shared<MockExpression>();
153+
154+ // Should throw IcebergError when calling Negate() on base class
155+ EXPECT_THROW (mock_expr->Negate (), IcebergError);
156+ }
67157} // namespace iceberg
0 commit comments