From 120973311afa0e97acf46419c2a1ede9462d4d1e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 17 Oct 2010 05:54:21 +0200 Subject: [PATCH] Session ElementQuery unit test pass (closes #639) --- src/proc/mobject/session/element-query.hpp | 13 +- src/proc/mobject/test-dummy-mobject.hpp | 5 + tests/43session.tests | 5 + .../session/session-element-query-test.cpp | 147 +++++++++--------- .../proc/mobject/session/testsession1.hpp | 4 +- 5 files changed, 92 insertions(+), 82 deletions(-) diff --git a/src/proc/mobject/session/element-query.hpp b/src/proc/mobject/session/element-query.hpp index 796da799c..9baf6a5d6 100644 --- a/src/proc/mobject/session/element-query.hpp +++ b/src/proc/mobject/session/element-query.hpp @@ -25,14 +25,11 @@ #define MOBJECT_SESSION_ELEMENT_QUERY_H -//#include "lib/p.hpp" -//#include "lib/query.hpp" #include "proc/mobject/placement.hpp" #include "proc/mobject/mobject-ref.hpp" #include "proc/mobject/session/specific-contents-query.hpp" #include "proc/mobject/session/session-service-explore-scope.hpp" -//#include #include #include @@ -42,8 +39,6 @@ namespace mobject { namespace session { -// using lumiera::P; -// using boost::scoped_ptr; using std::tr1::function; @@ -91,6 +86,9 @@ namespace session { * For now the motivation to package this as a separate interface module * was just to reduce the includes on the top level session API and to allow * for templated search functions, based on function objects. + * + * @see session-element-query-test.cpp demo test + * @see struct-factory-impl.hpp usage example */ class ElementQuery : boost::noncopyable @@ -100,9 +98,12 @@ namespace session { /** pick the first element from session satisfying a predicate. * @param searchPredicate applied to \c Placement for filtering + * @return MObject ref to the fist suitable element. Might be an empty MObjectRef. * @note the embedded MObject subtype (MO) causes an additional filtering * on that specific kind of MObject (e.g. considering just Clips) - * @return MObject ref to the fist suitable element. Might be an empty MObjectRef. + * @warning be sure the passed predicate actually takes a \code Placement const& \endcode + * with XX being the correct type. Note the \c const& -- Failing to do so shows up as + * compiler error "no suitable function pick(.....)" */ template typename _PickRes::Result diff --git a/src/proc/mobject/test-dummy-mobject.hpp b/src/proc/mobject/test-dummy-mobject.hpp index adbeeb313..24c1df0f2 100644 --- a/src/proc/mobject/test-dummy-mobject.hpp +++ b/src/proc/mobject/test-dummy-mobject.hpp @@ -134,6 +134,11 @@ namespace test { TestPlacement(DummyMO& dummyObj) : Placement::Placement(dummyObj, &DummyMO::killDummy) { } + + // allowing all kinds of copy + TestPlacement(Placement const& refP) + : Placement::Placement(refP) + { } }; template diff --git a/tests/43session.tests b/tests/43session.tests index ebe930800..40a81d269 100644 --- a/tests/43session.tests +++ b/tests/43session.tests @@ -36,6 +36,11 @@ PLANNED "SessionElementTracker_test" SessionElementTracker_test < + 2010, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -22,15 +22,14 @@ #include "lib/test/run.hpp" -#include "proc/mobject/session/scope-query.hpp" -#include "proc/mobject/session/specific-contents-query.hpp" -#include "proc/mobject/session/session-service-explore-scope.hpp" #include "proc/mobject/session/test-scopes.hpp" -#include "proc/mobject/session/clip.hpp" -#include "lib/symbol.hpp" +#include "proc/mobject/session/element-query.hpp" +#include "proc/mobject/session/scope-path.hpp" +#include "proc/mobject/session/scope.hpp" +#include "proc/mobject/mobject-ref.hpp" #include "lib/util.hpp" -#include +#include #include @@ -39,39 +38,34 @@ namespace mobject { namespace session { namespace test { - using lib::Literal; + using std::tr1::placeholders::_1; + using std::tr1::function; + using std::tr1::bind; using std::string; - using std::cout; - using std::endl; + using util::cStr; using util::contains; namespace { // helpers and shortcuts.... - /** a filter predicate to pick some objects from a resultset. + typedef Placement const& PDummy; // note const& required by ElementQuery filter definition + + + /** a filter predicate to pick some objects from a resultset, + * based on string match with the element's self-display string. * @note using the specific API of DummyMO, without cast! */ bool - filter (Placement const& candidate) + filter_typeID (PDummy candidate, string expectedText) { string desc = candidate->operator string(); - return contains(desc, "MO2"); + return contains(desc, expectedText); } - template - void - pullOut (IT const& iter) + inline function + elementID_contains (string expectedText) { - for (IT elm(iter); - elm; ++elm) - cout << string(*elm) << endl; - } - - void - announce (Literal description) - { - static uint nr(0); - cout << "--------------------------------Test-"<< ++nr << ": " << description << endl; + return bind (filter_typeID, _1, expectedText); } } @@ -79,19 +73,21 @@ namespace test { /********************************************************************************************** - * @test how to discover contents or location of a container-like part of the high-level model. - * As this container-like object is just a concept and actually implemented by the - * PlacementIndex, this means querying the index for elements registered with - * a given scope or finding the enclosing scopes. The discovered - * elements will be filtered by a runtime type check. + * @test cover the part of the session API allowing to retrieve specific elements by query. + * - This test first picks an object from the test session, where the filter predicate + * utilises the specific MObject subclass (here DummyMO). + * - Then re-fetches the same object using a different filter + * (based on the specific random int-ID). + * - Next the element is removed from the test session to verify the "not found" result + * - finally we re-attach another placement of the same underlying MObject instance + * at a different location in the test session and verify we can again pick this + * element with the specific query. * - * @todo change that to use a more realistic test session, based on the actual model types //////////////// TICKET #532 - * - * @see mobject::session::PlacementIndex - * @see mobject::session::QueryResolver + * @see mobject::session::ElementQuery * @see mobject::session::ContentsQuery + * @see scope-query-test.cpp */ - class ScopeQuery_test : public Test + class SessionElementQuery_test : public Test { virtual void run (Arg) @@ -99,51 +95,54 @@ namespace test { // Prepare an (test)Index (dummy "session") PPIdx testSession (build_testScopes()); - PlacementMO const& scope = SessionServiceExploreScope::getScopeRoot(); + ElementQuery queryAPI; - discover (ScopeQuery (scope, CONTENTS) , "contents depth-first"); - discover (ScopeQuery (scope, CONTENTS) , "contents depth-first, filtered to Clip"); - discover (ScopeQuery (scope, CONTENTS) , "contents depth-first, filtered to DummyMO"); ////////////////////// TICKET #532 - discover (ScopeQuery (scope, CONTENTS) , "contents depth-first, filtered to TestSubMO1"); - discover (ScopeQuery (scope, CONTENTS) , "contents depth-first, filtered to TestSubMO2"); + MORef dummy1 = queryAPI.pick (elementID_contains("MO2")); + CHECK (dummy1); + CHECK (dummy1->isValid()); + INFO (test, "Location in Tree: %s", cStr(ScopePath(dummy1.getPlacement()))); + string elementID = dummy1->operator string(); + CHECK (contains (elementID, "MO2")); - discover (pickAllSuitable(scope, filter) , "contents depth-first, custom filtered DummyMO"); - // note filter is typed to accept DummyMO - ScopeQuery allM021(scope, CONTENTS); - ScopeQuery::iterator specialEl (issue(allM021)); - ++specialEl; // step in to second solution found... - ASSERT (specialEl); + string specificID = elementID.substr(10); // should contain the random int-ID + MORef dummy2; + CHECK (!dummy2); + dummy2 = queryAPI.pick (elementID_contains(specificID)); + CHECK (dummy2); // found the same object again + CHECK (dummy2->isValid()); + CHECK (dummy2 == dummy1); - discover (ScopeQuery (*specialEl, PARENTS) , "parents of the second TestSubMO2 element found"); - discover (ScopeQuery (*specialEl, CHILDREN), "children of the this TestSubMO2 element"); - discover (ScopeQuery (*specialEl, PATH) , "path from there to root"); - discover (ScopeQuery (*specialEl, PATH) , "same path, but filtered to TestSubMO2"); - announce ( "continue exploring partially used TestSubMO2 iterator"); - pullOut (specialEl); + + // put aside a new handle holding onto the MObject + PDum newPlacement(dummy1.getPlacement()); + CHECK (testSession->contains(dummy1.getRef())); + CHECK (!testSession->contains(newPlacement)); + + // and now remove the placement and all contained elements + testSession->clear (dummy1.getRef()); + CHECK (!testSession->contains(dummy1.getRef())); + + MORef findAgain = queryAPI.pick (elementID_contains(specificID)); + CHECK (!findAgain); // empty result because searched element was removed from session... + + MORef otherElm = queryAPI.pick (elementID_contains("MO1")); + CHECK (otherElm); // now pick just some other arbitrary element + + testSession->insert(newPlacement, otherElm.getRef()); + dummy2 = queryAPI.pick (elementID_contains(specificID)); + CHECK (dummy2); + CHECK (dummy2 != dummy1); + CHECK (dummy2 != newPlacement); + CHECK (isSharedPointee(newPlacement, dummy2.getPlacement())); + CHECK (Scope::containing(dummy2.getPlacement()) == Scope(otherElm.getPlacement())); + INFO (test, "New treelocation: %s", cStr(ScopePath(dummy2.getPlacement()))); } - - - - template - static void - discover (ScopeQuery const& query, Literal description) - { - announce (description); - pullOut (issue(query)); - } - - template - static typename ScopeQuery::iterator - issue (ScopeQuery const& query) - { - return query.resolveBy(SessionServiceExploreScope::getResolver()); - } - }; + /** Register this test class... */ - LAUNCHER (ScopeQuery_test, "unit session"); + LAUNCHER (SessionElementQuery_test, "function session"); }}} // namespace mobject::session::test diff --git a/tests/components/proc/mobject/session/testsession1.hpp b/tests/components/proc/mobject/session/testsession1.hpp index 641c875d8..198e796ff 100644 --- a/tests/components/proc/mobject/session/testsession1.hpp +++ b/tests/components/proc/mobject/session/testsession1.hpp @@ -21,8 +21,8 @@ */ -#ifndef MOBJECT_SESSION_TESTSESSION_H -#define MOBJECT_SESSION_TESTSESSION_H +#ifndef MOBJECT_SESSION_TESTSESSION1_H +#define MOBJECT_SESSION_TESTSESSION1_H #include "proc/mobject/session.hpp"