From da994cf9fda179a733d42db04eaf28da3e8b5106 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 17 Oct 2010 05:08:47 +0200 Subject: [PATCH] draft a test to cover ElementQuery (Session API) trying to get #639 closed... discovered, that I had already implemented this filtering query in 6/2010 --- src/proc/asset/struct-factory-impl.hpp | 1 + src/proc/mobject/session/element-query.hpp | 6 + tests/components/Makefile.am | 1 + .../session/session-element-query-test.cpp | 149 ++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 tests/components/proc/mobject/session/session-element-query-test.cpp diff --git a/src/proc/asset/struct-factory-impl.hpp b/src/proc/asset/struct-factory-impl.hpp index 304432144..f27b32347 100644 --- a/src/proc/asset/struct-factory-impl.hpp +++ b/src/proc/asset/struct-factory-impl.hpp @@ -139,6 +139,7 @@ namespace asset { if (!track) track = Session::current->getRoot().attach (MObject::create (TrackID (desiredID))); + return track; } diff --git a/src/proc/mobject/session/element-query.hpp b/src/proc/mobject/session/element-query.hpp index ec23eae9b..796da799c 100644 --- a/src/proc/mobject/session/element-query.hpp +++ b/src/proc/mobject/session/element-query.hpp @@ -98,6 +98,12 @@ namespace session { public: + /** pick the first element from session satisfying a predicate. + * @param searchPredicate applied to \c Placement for filtering + * @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. + */ template typename _PickRes::Result pick (PRED const& searchPredicate) diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index f031fd139..ae2942c11 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -92,6 +92,7 @@ test_components_SOURCES = \ $(testcomponents_srcdir)/proc/mobject/session/rebuildfixturetest.cpp \ $(testcomponents_srcdir)/proc/mobject/session/scope-path-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/scope-query-test.cpp \ + $(testcomponents_srcdir)/proc/mobject/session/session-element-query-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/session-service-access-test.cpp \ $(testcomponents_srcdir)/proc/mobject/session/sessionmanagertest.cpp \ $(testcomponents_srcdir)/proc/mobject/session/test-scopes.cpp \ diff --git a/tests/components/proc/mobject/session/session-element-query-test.cpp b/tests/components/proc/mobject/session/session-element-query-test.cpp new file mode 100644 index 000000000..994adb8dd --- /dev/null +++ b/tests/components/proc/mobject/session/session-element-query-test.cpp @@ -0,0 +1,149 @@ +/* + ScopeQuery(Test) - running queries to discover container contents, filtering (sub)types + + Copyright (C) Lumiera.org + 2009, 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 + 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#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 "lib/util.hpp" + +#include +#include + + + +namespace mobject { +namespace session { +namespace test { + + using lib::Literal; + using std::string; + using std::cout; + using std::endl; + + using util::contains; + + + namespace { // helpers and shortcuts.... + + /** a filter predicate to pick some objects from a resultset. + * @note using the specific API of DummyMO, without cast! */ + bool + filter (Placement const& candidate) + { + string desc = candidate->operator string(); + return contains(desc, "MO2"); + } + + template + void + pullOut (IT const& iter) + { + for (IT elm(iter); + elm; ++elm) + cout << string(*elm) << endl; + } + + void + announce (Literal description) + { + static uint nr(0); + cout << "--------------------------------Test-"<< ++nr << ": " << description << endl; + } + + } + + + + /********************************************************************************************** + * @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. + * + * @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::ContentsQuery + */ + class ScopeQuery_test : public Test + { + virtual void + run (Arg) + { + // Prepare an (test)Index (dummy "session") + PPIdx testSession (build_testScopes()); + + PlacementMO const& scope = SessionServiceExploreScope::getScopeRoot(); + + 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"); + + 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); + + 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); + } + + + + 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"); + + +}}} // namespace mobject::session::test