From 4bc5444c7e319df34a79c43fe99b429752c17a58 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 09:38:19 -0700 Subject: Start a suite of unit tests for the incremental expression module of the resolver. --- tests/Makefile.am | 1 + tests/test_incremental_expression.cc | 272 +++++++++++++++++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 tests/test_incremental_expression.cc diff --git a/tests/Makefile.am b/tests/Makefile.am index acfd45ad..4d45c314 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -31,6 +31,7 @@ cppunit_test_SOURCES = \ test_choice_set.cc \ test_config_pusher.cc \ test_dense_setset.cc \ + test_incremental_expression.cc \ test_matching.cc \ test_misc.cc \ test_parsers.cc \ diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc new file mode 100644 index 00000000..23983263 --- /dev/null +++ b/tests/test_incremental_expression.cc @@ -0,0 +1,272 @@ +// test_incremental_expression.cc +// +// Copyright (C) 2010 Daniel Burrows +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include + +#include + +#include + +namespace cw = cwidget; + +namespace +{ + // Make it possible to "show" vectors. + template + std::ostream &operator<<(std::ostream &out, const std::vector &v) + { + out << "["; + + for(typename std::vector::const_iterator it = + v.begin(); it != v.end(); ++it) + { + if(it != v.begin()) + out << ", "; + + out << *it; + } + + out << "]"; + + return out; + } + + // Helper class for the code below that records a single call to + // child_modified(). + template + class child_modified_call + { + cw::util::ref_ptr > child; + T old_value, new_value; + + public: + child_modified_call(const cw::util::ref_ptr > &_child, + const T &_old_value, const T &_new_value) + : child(_child), old_value(_old_value), new_value(_new_value) + { + } + + const cw::util::ref_ptr > &get_child() const { return child; } + const T &get_old_value() const { return old_value; } + const T &get_new_value() const { return new_value; } + + bool operator==(const child_modified_call &other) const + { + return + child == other.child && + old_value == other.old_value && + new_value == other.new_value; + } + }; + + template + std::ostream &operator<<(std::ostream &out, const child_modified_call &t) + { + return out << "child_modified(old_value = " << t.get_old_value() + << ", new_value = " << t.get_new_value() << ")"; + } + + template + class get_value_call + { + T return_value; + + public: + get_value_call(const T &_return_value) + : return_value(_return_value) + { + } + + const T &get_return_value() const { return return_value; } + + bool operator==(const get_value_call &other) const + { + return return_value == other.return_value; + } + }; + + template + std::ostream &operator<<(std::ostream &out, const get_value_call &c) + { + return out << "get_value() => " << c.get_return_value(); + } + + // A class that implements the expression container interface, + // passing all interesting calls to a single sub-object and + // recording all the calls to child_modified. + template + class fake_container : public expression_container + { + cw::util::ref_ptr > real_object; + std::vector > calls; + + fake_container(const cw::util::ref_ptr > &_real_object) + : real_object(_real_object) + { + real_object->add_parent(this); + } + + public: + ~fake_container() + { + real_object->remove_parent(this); + } + + static cw::util::ref_ptr > + create(const cw::util::ref_ptr > &child) + { + return new fake_container(child); + } + + const std::vector > &get_calls() const { return calls; } + + void child_modified(const cw::util::ref_ptr > &child, + T old_value, + T new_value) + { + calls.push_back(child_modified_call(child, old_value, new_value)); + } + + T get_value() + { + return real_object->get_value(); + } + + void dump(std::ostream &out) + { + real_object->dump(out); + } + }; + + // Records calls to expression_box::changed. + template + class changed_call + { + T new_value; + + public: + changed_call(const T &_new_value) + : new_value(_new_value) + { + } + + const T &get_new_value() const { return new_value; } + }; + + template + std::ostream &operator<<(std::ostream &out, const changed_call &c) + { + return out << "changed(" << c.get_new_value() << ")"; + } + + // A helper class used to test that expression_wrapper behaves as + // advertised. + // + // Wraps its subexpression and records all the calls to + // child_modified() and changed(). + template + class fake_wrapper : public expression_wrapper + { + std::vector, changed_call > > calls; + + fake_wrapper() : expression_wrapper() { } + fake_wrapper(const cw::util::ref_ptr > &child) + : expression_wrapper(child) + { + } + + public: + static cw::util::ref_ptr create() + { + return new fake_wrapper; + } + + static cw::util::ref_ptr + create(const cw::util::ref_ptr > &child) + { + return new fake_wrapper(child); + } + + void child_modified(const cw::util::ref_ptr > &child, + T old_value, + T new_value) + { + calls.push_back(child_modified_call(child, old_value, new_value)); + + expression_wrapper::child_modified(child, old_value, new_value); + } + + void changed(T new_value) + { + calls.push_back(changed_call(new_value)); + + expression_wrapper::changed(this->get_child()); + } + }; +} + +class TestIncrementalExpression : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestIncrementalExpression); + + CPPUNIT_TEST(testIncrementalExpressionGetVarValue); + CPPUNIT_TEST(testIncrementalExpressionSetVarValue); + CPPUNIT_TEST(testIncrementalExpressionVarSignalChange); + + CPPUNIT_TEST_SUITE_END(); + +public: + void testIncrementalExpressionGetVarValue() + { + cw::util::ref_ptr > + v0 = var_e::create(0), + v5 = var_e::create(5), + v9 = var_e::create(9); + + CPPUNIT_ASSERT_EQUAL(0, v0->get_value()); + CPPUNIT_ASSERT_EQUAL(5, v5->get_value()); + CPPUNIT_ASSERT_EQUAL(9, v9->get_value()); + } + + void testIncrementalExpressionSetVarValue() + { + cw::util::ref_ptr > v = var_e::create(123456); + + v->set_value(987654); + CPPUNIT_ASSERT_EQUAL(987654, v->get_value()); + } + + void testIncrementalExpressionVarSignalChange() + { + cw::util::ref_ptr > v = var_e::create(55555); + + cw::util::ref_ptr > c = fake_container::create(v); + + std::vector > expected_calls; + expected_calls.push_back(child_modified_call(v, 55555, 42)); + expected_calls.push_back(child_modified_call(v, 42, 10)); + + v->set_value(42); + // Test that setting to the same value doesn't emit a signal. + v->set_value(42); + v->set_value(10); + + CPPUNIT_ASSERT_EQUAL(expected_calls, c->get_calls()); + } +}; -- cgit v1.2.3 From faaf9295f9afb0d29f589e84b3008c21d0c6baf8 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 09:45:36 -0700 Subject: Add tests of the expression weak reference subsystem. --- tests/test_incremental_expression.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 23983263..67d30a71 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -228,6 +228,12 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testIncrementalExpressionGetVarValue); CPPUNIT_TEST(testIncrementalExpressionSetVarValue); CPPUNIT_TEST(testIncrementalExpressionVarSignalChange); + // TODO: test comparisons? + // TODO: test conversions to string? + + CPPUNIT_TEST(testIncrementalExpressionWeakRefDeref); + CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidLive); + CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidDead); CPPUNIT_TEST_SUITE_END(); @@ -269,4 +275,31 @@ public: CPPUNIT_ASSERT_EQUAL(expected_calls, c->get_calls()); } + + + void testIncrementalExpressionWeakRefDeref() + { + cw::util::ref_ptr > e = var_e::create(5); + expression_weak_ref > e_ref = e; + + CPPUNIT_ASSERT_EQUAL(e.unsafe_get_ref(), e_ref.get_value()); + } + + void testIncrementalExpressionWeakRefGetValidLive() + { + cw::util::ref_ptr > e = var_e::create(5); + expression_weak_ref > e_ref = e; + + CPPUNIT_ASSERT(e_ref.get_valid()); + } + + void testIncrementalExpressionWeakRefGetValidDead() + { + cw::util::ref_ptr > e = var_e::create(5); + expression_weak_ref > e_ref = e; + + e = cw::util::ref_ptr >(); + + CPPUNIT_ASSERT(!e_ref.get_valid()); + } }; -- cgit v1.2.3 From 841975c3efde6e808466230a7291e39182373b89 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:46:52 -0700 Subject: Add some basic tests of "and" expressions. --- tests/test_incremental_expression.cc | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 67d30a71..2f60e8e8 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -302,4 +302,95 @@ public: CPPUNIT_ASSERT(!e_ref.get_valid()); } + + + void testAndEmpty() + { + cw::util::ref_ptr > empty[] = { }; + cw::util::ref_ptr > e = and_e::create(empty, empty); + + CPPUNIT_ASSERT(e->get_value()); + } + +private: + cw::util::ref_ptr getAndSingleton(cw::util::ref_ptr > v1) + { + cw::util::ref_ptr > subexprs_begin[] = { v1 }; + cw::util::ref_ptr > *subexprs_end = + subexprs_begin + sizeof(subexprs_begin) / sizeof(subexprs_begin[0]); + + return and_e::create(subexprs_begin, subexprs_end); + } + + void testAndSingletonRaise() + { + cw::util::ref_ptr > v1 = var_e::create(false); + cw::util::ref_ptr e = getAndSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(v1, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndSingletonLower() + { + cw::util::ref_ptr > v1 = var_e::create(true); + cw::util::ref_ptr e = getAndSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(v1, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndSingletonRaiseByRemoving() + { + cw::util::ref_ptr > v1 = var_e::create(false); + cw::util::ref_ptr e = getAndSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + e->remove_child(v1); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(v1, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndSingletonLowerByAppending() + { + cw::util::ref_ptr > v1 = var_e::create(true); + cw::util::ref_ptr e = getAndSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + e->add_child(var_e::create(false)); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(v1, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } }; -- cgit v1.2.3 From 1bcf3d798d41f858da55da660c1e700e6e02b860 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:50:24 -0700 Subject: Actually run the new tests. --- tests/test_incremental_expression.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 2f60e8e8..8a8176b8 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -235,6 +235,11 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidLive); CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidDead); + CPPUNIT_TEST(testAndSingletonRaise); + CPPUNIT_TEST(testAndSingletonLower); + CPPUNIT_TEST(testAndSingletonRaiseByRemoving); + CPPUNIT_TEST(testAndSingletonLowerByAppending); + CPPUNIT_TEST_SUITE_END(); public: @@ -322,6 +327,7 @@ private: return and_e::create(subexprs_begin, subexprs_end); } +public: void testAndSingletonRaise() { cw::util::ref_ptr > v1 = var_e::create(false); -- cgit v1.2.3 From 7ac3306f87b479f7ba64510e440562ef6509ae0c Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:51:02 -0700 Subject: Add a first test of "and" over two elements. --- tests/test_incremental_expression.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 8a8176b8..33dfafe2 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -240,6 +240,8 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testAndSingletonRaiseByRemoving); CPPUNIT_TEST(testAndSingletonLowerByAppending); + CPPUNIT_TEST(testAndDoubletonRaiseFirst); + CPPUNIT_TEST_SUITE_END(); public: @@ -397,6 +399,37 @@ public: std::vector > expected; expected.push_back(child_modified_call(v1, true, false)); + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + +private: + cw::util::ref_ptr getAndDoubleton(const cw::util::ref_ptr > &v1, + const cw::util::ref_ptr > &v2) + { + cw::util::ref_ptr > subexprs_begin[] = { v1, v2 }; + cw::util::ref_ptr > *subexprs_end = + subexprs_begin + sizeof(subexprs_begin) / sizeof(subexprs_begin[0]); + + return and_e::create(subexprs_begin, subexprs_end); + } + +public: + void testAndDoubletonRaiseFirst() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(false); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v2->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } }; -- cgit v1.2.3 From 76bdf7fc30d8f0b0891f270a1f9d8344dcda697c Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:56:12 -0700 Subject: Add the missing registration call for the new test suite. --- tests/test_incremental_expression.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 33dfafe2..c3378e5e 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -433,3 +433,5 @@ public: CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } }; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestIncrementalExpression); -- cgit v1.2.3 From 9453d9b00359ae41adaa9204e5fc95de4a57ed41 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:57:13 -0700 Subject: Print the child that was modified when printing a child_modified_call object. --- tests/test_incremental_expression.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index c3378e5e..d9a88419 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -78,7 +78,8 @@ namespace template std::ostream &operator<<(std::ostream &out, const child_modified_call &t) { - return out << "child_modified(old_value = " << t.get_old_value() + return out << "child_modified(child = " << t.get_child() + << ", old_value = " << t.get_old_value() << ", new_value = " << t.get_new_value() << ")"; } -- cgit v1.2.3 From dd0efd801db791035adde6b8fa296b6000ef9380 Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 18:58:06 -0700 Subject: Expect the child_modified call that comes from an "and" expression to refer to the expression itself, not to the child that triggered the call. --- tests/test_incremental_expression.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index d9a88419..d638b872 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -344,7 +344,7 @@ public: CPPUNIT_ASSERT(e->get_value()); std::vector > expected; - expected.push_back(child_modified_call(v1, false, true)); + expected.push_back(child_modified_call(e, false, true)); CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } @@ -362,7 +362,7 @@ public: CPPUNIT_ASSERT(!e->get_value()); std::vector > expected; - expected.push_back(child_modified_call(v1, true, false)); + expected.push_back(child_modified_call(e, true, false)); CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } @@ -380,7 +380,7 @@ public: CPPUNIT_ASSERT(e->get_value()); std::vector > expected; - expected.push_back(child_modified_call(v1, false, true)); + expected.push_back(child_modified_call(e, false, true)); CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } @@ -398,7 +398,7 @@ public: CPPUNIT_ASSERT(!e->get_value()); std::vector > expected; - expected.push_back(child_modified_call(v1, true, false)); + expected.push_back(child_modified_call(e, true, false)); CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } -- cgit v1.2.3 From a43a970cbc1c6f00e9028a538aa1591457d0728d Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 19:01:15 -0700 Subject: Un-swap the first and second case of the doubleton test, and add a test that raising just one input to an AND has no effect. --- tests/test_incremental_expression.cc | 60 +++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index d638b872..e8470d4d 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -242,6 +242,9 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testAndSingletonLowerByAppending); CPPUNIT_TEST(testAndDoubletonRaiseFirst); + CPPUNIT_TEST(testAndDoubletonRaiseSecond); + CPPUNIT_TEST(testAndDoubletonRaiseFirstNoEffect); + CPPUNIT_TEST(testAndDoubletonRaiseSecondNoEffect); CPPUNIT_TEST_SUITE_END(); @@ -415,7 +418,7 @@ private: } public: - void testAndDoubletonRaiseFirst() + void testAndDoubletonRaiseSecond() { cw::util::ref_ptr > v1 = var_e::create(true), @@ -433,6 +436,61 @@ public: CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } + + void testAndDoubletonRaiseFirst() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(true); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndDoubletonRaiseFirstNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(false); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndDoubletonRaiseSecondNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(false); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v2->set_value(true); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(TestIncrementalExpression); -- cgit v1.2.3 From 7f780d5086bad371b36c78a4759f78219e90c19f Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 19:03:36 -0700 Subject: Add tests checking what happens if one input to a doubleton is *lowered*. --- tests/test_incremental_expression.cc | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index e8470d4d..1ecf587b 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -246,6 +246,11 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testAndDoubletonRaiseFirstNoEffect); CPPUNIT_TEST(testAndDoubletonRaiseSecondNoEffect); + CPPUNIT_TEST(testAndDoubletonLowerFirst); + CPPUNIT_TEST(testAndDoubletonLowerSecond); + CPPUNIT_TEST(testAndDoubletonLowerFirstNoEffect); + CPPUNIT_TEST(testAndDoubletonLowerSecondNoEffect); + CPPUNIT_TEST_SUITE_END(); public: @@ -491,6 +496,82 @@ public: CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } + + + void testAndDoubletonLowerFirst() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(true); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndDoubletonLowerSecond() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(true); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v2->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + + void testAndDoubletonLowerFirstNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(false); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testAndDoubletonLowerSecondNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(true); + cw::util::ref_ptr e = getAndDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v2->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(TestIncrementalExpression); -- cgit v1.2.3 From 44c2785a84123bd1fe60350aaa94b7a814c4c1ee Mon Sep 17 00:00:00 2001 From: Daniel Burrows Date: Mon, 19 Apr 2010 19:08:38 -0700 Subject: Write out tests of "or" that are dual to the tests of "and". --- tests/test_incremental_expression.cc | 276 +++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) diff --git a/tests/test_incremental_expression.cc b/tests/test_incremental_expression.cc index 1ecf587b..2de1ca6d 100644 --- a/tests/test_incremental_expression.cc +++ b/tests/test_incremental_expression.cc @@ -236,6 +236,8 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidLive); CPPUNIT_TEST(testIncrementalExpressionWeakRefGetValidDead); + CPPUNIT_TEST(testAndEmpty); + CPPUNIT_TEST(testAndSingletonRaise); CPPUNIT_TEST(testAndSingletonLower); CPPUNIT_TEST(testAndSingletonRaiseByRemoving); @@ -251,6 +253,23 @@ class TestIncrementalExpression : public CppUnit::TestFixture CPPUNIT_TEST(testAndDoubletonLowerFirstNoEffect); CPPUNIT_TEST(testAndDoubletonLowerSecondNoEffect); + CPPUNIT_TEST(testOrEmpty); + + CPPUNIT_TEST(testOrSingletonRaise); + CPPUNIT_TEST(testOrSingletonLower); + CPPUNIT_TEST(testOrSingletonLowerByRemoving); + CPPUNIT_TEST(testOrSingletonRaiseByAppending); + + CPPUNIT_TEST(testOrDoubletonRaiseFirst); + CPPUNIT_TEST(testOrDoubletonRaiseSecond); + CPPUNIT_TEST(testOrDoubletonRaiseFirstNoEffect); + CPPUNIT_TEST(testOrDoubletonRaiseSecondNoEffect); + + CPPUNIT_TEST(testOrDoubletonLowerFirst); + CPPUNIT_TEST(testOrDoubletonLowerSecond); + CPPUNIT_TEST(testOrDoubletonLowerFirstNoEffect); + CPPUNIT_TEST(testOrDoubletonLowerSecondNoEffect); + CPPUNIT_TEST_SUITE_END(); public: @@ -572,6 +591,263 @@ public: CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); } + + + + + void testOrEmpty() + { + cw::util::ref_ptr > empty[] = { }; + cw::util::ref_ptr > e = or_e::create(empty, empty); + + CPPUNIT_ASSERT(!e->get_value()); + } + +private: + cw::util::ref_ptr getOrSingleton(cw::util::ref_ptr > v1) + { + cw::util::ref_ptr > subexprs_begin[] = { v1 }; + cw::util::ref_ptr > *subexprs_end = + subexprs_begin + sizeof(subexprs_begin) / sizeof(subexprs_begin[0]); + + return or_e::create(subexprs_begin, subexprs_end); + } + +public: + void testOrSingletonRaise() + { + cw::util::ref_ptr > v1 = var_e::create(false); + cw::util::ref_ptr e = getOrSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrSingletonLower() + { + cw::util::ref_ptr > v1 = var_e::create(true); + cw::util::ref_ptr e = getOrSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrSingletonLowerByRemoving() + { + cw::util::ref_ptr > v1 = var_e::create(true); + cw::util::ref_ptr e = getOrSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + e->remove_child(v1); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrSingletonRaiseByAppending() + { + cw::util::ref_ptr > v1 = var_e::create(false); + cw::util::ref_ptr e = getOrSingleton(v1); + + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + e->add_child(var_e::create(true)); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + +private: + cw::util::ref_ptr getOrDoubleton(const cw::util::ref_ptr > &v1, + const cw::util::ref_ptr > &v2) + { + cw::util::ref_ptr > subexprs_begin[] = { v1, v2 }; + cw::util::ref_ptr > *subexprs_end = + subexprs_begin + sizeof(subexprs_begin) / sizeof(subexprs_begin[0]); + + return or_e::create(subexprs_begin, subexprs_end); + } + +public: + + void testOrDoubletonRaiseFirst() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(false); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrDoubletonRaiseSecond() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(false); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(!e->get_value()); + v2->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, false, true)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrDoubletonRaiseFirstNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(true); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrDoubletonRaiseSecondNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(false); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v2->set_value(true); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + + void testOrDoubletonLowerFirst() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(false); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrDoubletonLowerSecond() + { + cw::util::ref_ptr > + v1 = var_e::create(false), + v2 = var_e::create(true); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v2->set_value(false); + CPPUNIT_ASSERT(!e->get_value()); + + std::vector > expected; + expected.push_back(child_modified_call(e, true, false)); + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + + void testOrDoubletonLowerFirstNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(true); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v1->set_value(false); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } + + void testOrDoubletonLowerSecondNoEffect() + { + cw::util::ref_ptr > + v1 = var_e::create(true), + v2 = var_e::create(true); + cw::util::ref_ptr e = getOrDoubleton(v1, v2); + cw::util::ref_ptr > e_wrap = + fake_container::create(e); + + CPPUNIT_ASSERT(e->get_value()); + v2->set_value(false); + CPPUNIT_ASSERT(e->get_value()); + + std::vector > expected; + + CPPUNIT_ASSERT_EQUAL(expected, e_wrap->get_calls()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(TestIncrementalExpression); -- cgit v1.2.3