Commit graph

417 commits

Author SHA1 Message Date
dcad50ef1b test diff: codify and document the diff sequence
the plan is to use this specific diff sequence
both in the individual binding tests, and in a
more high level integration test. Hopefully this
helps to make these quite technical tests more readable
2016-05-26 01:56:13 +02:00
4571d3fb0f introduce new mutation primitive as pointed out by preceding analysis
to summarise, it turned out that it is impossible to
provide an airtight 'emptySrc' implementation when binding
to object fields -- so we distinguish into positive and
negative tests, allowing to loosen the sanity check
only for the latter ones when binding to object fields.
2016-05-24 23:43:55 +02:00
b47b4c3f94 flip logic of emptySrc -> hasSrc
..as concluded from the preceding analysis.
NOTE this entails a semantical change, since this
predicate is now only meant to be indicative, not conclusive

remarks: the actual implementation of the diff application process
as bound via the TreeMutator remains yet to be written...
2016-05-24 21:34:08 +02:00
d3869d2280 Design/Analysis: Attribute TreeMutator binding
how can ordinary object fields be treated as "Attributes"
and thus tied into the Diff framework defined thus far.
This turns out to be really tricky, even questionable
2016-04-30 00:26:19 +02:00
7467e6da2a extend test to cover nested mutation of another disjoint sub-scope
which also verifies the object ownership and lifecycle handling
of the opaque buffer used to place the nested mutator.
2016-04-18 01:41:41 +02:00
7bbfb4bc68 implement nested mutation of sub structures
...basically this worked right away and was easy to put together.
However, when considering how many components, indirections and
nested lambdas are working together here, I feel a bit dizzy...

:-/
2016-04-17 04:51:19 +02:00
8167fbff77 implement fast-forward and assignment to value
...all of this implementation boils down to slightly adjusting
the code written for the test-mutation-target. Insofar it pays off now
having implemented this diagnostic and demonstration first.

Moreover I'm implementing this basic scheme of "diff application"
roughly the fourth time, thus things kindof fall into place now.
What's really hard is all those layers of abstraction in between.

Lesson learned (after being off for three weeks, due to LAC and
other obligations): I really need to document the meaning of the
closures, and I need to document the "abstract operational semantics"
of diff application, otherwise no one will be able to provide
the correct closures.
2016-04-17 01:07:07 +02:00
7f42b9b7e7 draft third round of mutation operations to be implemented
...now about opening a sub mutator within a nested scope
2016-04-16 02:20:23 +02:00
54fb335a9c allow to "peek" into an embedded Record's type field
while I still keep my stance not to allow reflection and
switch-on-type, access to the internal / semantic type of
an embedded record seems a valid compromise to allow
to deal with collections of object-like children
of mixed kind.

Indirectly (and quite intentional) this also opens a loophole
to detect if a given GenNode might constitute a nested scope,
but with the for the actual nested element indeed to cary
a type symbol. Effectively this limits the use of this shortcut
to situations where the handling context does have some pre-established
knowledge about what types *might* be expected. This is precisely
the kind of constraint I intend to uphold: I do not want the
false notion of "total flexibility", as is conveyed by introspection.
2016-04-16 00:48:15 +02:00
f9f2a225c3 implement content reordering mutation primitives
and cover result in test.
This also demonstrates that it is possible to install
a specific lambda on each usage
2016-03-26 01:22:40 +01:00
c49dd04b44 address an insidious dangling reference
I still feel somewhat queasy with this whole situation!
We need to return the product of the DSL/Builder by value,
but we also want to swap away the current contents before
starting the mutation, and we do not want a stateful lifecycle
for the mutator implementation. Which means, we need to swap
right at construction, and then we copy -- TADAAA!

Thus I'm going for the solution to disallow copying of the
mutator, yet to allow moving, and to change the builder
to move its product into place. Probably should even push
this policy up into the base class (TreeMutator) to set
everyone straight.

Looks like this didn't show up with the test dummy implementation
just because in this case the src buffer also lived within th
TestMutationTarget, which is assumed to sit where it is, so
effectively we moved around only pointers.
2016-03-26 00:48:38 +01:00
adf01b0fbf WIP: define what will be the next steps to implement
basically we're duplicating the existing test case literally
2016-03-25 23:45:32 +01:00
d98fde5b0e better verification in test
...actually iterate the populated collection
and verify each element in order. Also verify
and document the mutator's storage requirements
2016-03-25 23:12:54 +01:00
e84844142f implement inserting of new elements 2016-03-25 22:43:11 +01:00
91bf75d54a spelling in comments 2016-03-25 21:40:30 +01:00
77bbe98275 draft first round of operation in test to be implemented.... 2016-03-25 03:12:02 +01:00
e698a3800b verify signatures of binding lambdas
the collection binding can be configured with various
lambdas to supply the basic building blocks of the generated binding.

Since we allow picking up basically anything (functors,
function pointers, function objects, lamdas), and since
we speculate on inlining optimisation of lambdas, we can not
enforce a specific signature in the builder functions.

But at least we can static_assert on the effective signature
at the point where we're generating the actual binding configuration
2016-03-25 02:51:56 +01:00
cb2a95627d WIP: specify first example binding...
...but does not compile, since all of the fallback functions
will be instantiated, even while in fact we're overriding them
right away with something that *can* be compiled.

this prompts me to reconsider and question the basic approach
with closures for binding, while in fact what I am doing here
is to implement an ABC.
2016-03-24 17:32:30 +01:00
df8ca071a8 first outline of test and aggregate initialisation problem
- the test will use some really private data types,
  valid only within the scope of the test function.

- invoking the builder for real got me into problems
  with the aggregate initialisation I'd used.
  Maybe it's the function pointers? Anyway, working
  around that by definint a telescope ctor
2016-03-19 16:47:40 +01:00
a106a0e090 spelling fixes 2016-03-19 01:42:27 +01:00
9ef32e0d62 complete dummy/proof-of-concept implementation of TreeMutator primitives
the first part of the unit test (now passing)
is able to demonstrate the full set of diff operations
just by binding to a TestMutationTarget.

Now, after verifying the design of those primmitive operations,
we can now proceed with bindings to "real" data structures
2016-03-11 21:30:25 +01:00
b0c6ba0777 switch implementation of TestMutationTarget to storing full GenNodes
when implementing the assignment and mutation primitives
it became clear that the original approach of just storing
a log or string rendered elements does not work: for
assignment, we need to locate an element by ID
2016-03-11 17:39:25 +01:00
75a6b4c05d specify and stub the test thus far to complete API design
now the full API for the "mutation primitives" is shaped.
Of course the actual implementation is missing, but that
should be low hanging fuit by now.

What still requires some thinking though is how to implement
the selector, so we'll actually get a onion shaped decorator
2016-03-06 03:55:31 +01:00
7b73aa6950 add some further checks and coverage to the test
...basically we've now the list mutation primitives working,
albeit in a test/dummy implementation only. Next steps will
be to integrate the assignment and sub scope primitives,
and then to re-do the same implementation respectively
for the case of mutating a standard collection of arbitrary type
2016-03-04 23:56:53 +01:00
75de98fe4d get the unit test to pass again
what's problematic is that we leave back waste in the
internal buffer holding the source. Thus it doesn't make
sense to check if this buffer is empty. Rather the
Mutator must offer an predicate emptySrc().

This will be relevant for other implementations as well
2016-03-04 23:18:25 +01:00
6cf97f2478 forward operations to test/dummy onion layer
...first round of implementation happens here
2016-03-04 21:26:25 +01:00
b0ee330737 stub and decide about further part of the API 2016-03-04 21:13:49 +01:00
7d63167276 WIP: define usage of the reordering part of the mutation primitives
...this kind of settles the problem with the "opaque" position
2016-03-04 20:55:52 +01:00
9875c93ca7 add iteration and some diagnostics to the test 2016-03-04 19:23:21 +01:00
af50e84737 first partial implementation unit test PASS
that is, the dummy/diagnostic-implementation
of the first "mutation primitive", namely injectNew(elm)
2016-03-04 00:25:36 +01:00
d8fe9bce94 baseline of test-dummy implementation or a mutation target binding
- we're using the source / target buffer paradigm to implement the mutation
 - we're using Record<string> to account for "the current content"
2016-03-03 23:11:36 +01:00
3f8946c157 better naming of Record::Mutator content moving operation
while the original name, 'replace', conveys the intention,
this more standard name 'swap' reveals what is done
and thus opens a wider array of possible usage
2016-03-03 22:58:33 +01:00
48f519e785 align naming of mutation primitives
...convinced myself to retain an uniform naming scheme,
even while the implementation spans several onion-like layers
2016-03-03 22:02:01 +01:00
8bcd37df0a stub first round of mutation primitives to pass compiler again
now this feels like making progress again,
even when just writing stubs ;-)

Moreover, it became clear that the "typing" of typed child collections
will always be ad hoc, and thus needs to be ensured on a case by case
base. As a consequence, all mutation primitives must carry the
necessary information for the internal selector to decide if this
primitive is applicable to a given decorator layer. Because
otherwise it is not possible to uphold the concept of a single,
abstracted "source position", where in fact each typed sub-collection
of children (and thus each "onion layer" in the decorator chain)
maintains its own private position
2016-02-27 01:47:33 +01:00
5d230aa7ac WIP: start defining the inner API systematically
...trying to get ahead step by step
2016-02-27 00:18:06 +01:00
bdf48e1b7b WIP: desperate attempt to get out of the design deadlock
Arrrrgh.
I go round in circles since hours now.
Whatever I attempt, it again relies on
yet further unsecured suppositions
2016-02-26 22:57:49 +01:00
dd1afef970 WIP: consider what kind of changes to support and how
especially the nagging question is:
- do we need to support children of mixed type
- and how can we support those, wihtout massively indirected calls
2016-02-20 00:19:01 +01:00
afbba968b5 WIP: decide how to target the task of mutating "unspecific" data structures 2016-02-19 20:25:30 +01:00
d22cc18c13 introduce a value assignment verb into the tree-diff-language
after sleeping one night over the problem, this seems to be
the most natural solution, since the possibility of assignment
naturally arises from the fact that, for tree diff, we have
to distinguish between the *identity* of an element node and
its payload (which could be recursive). Thus, IFF the payoad
is an assignable value, why not allow to assign it. Doing so
elegnatly solves the problem with assignment of attributes

Signed-off-by: Ichthyostega <prg@ichthyostega.de>
2016-02-19 17:22:41 +01:00
41c8c948e3 explicit size check to generate a meaningful error message
the values.child() call would also do a bounds check,
but only to rise a error::Invalid "index out of bounds".
So now we generate a clear message to indicate that
actually a runtime-checked type mismatch caused this problem
2016-02-13 22:55:57 +01:00
2a6e48d7b5 immutable-arguments(#989): verify the tuple builder can handle those too
incidentally, this uncovered yet another unwanted narrowing conversion,
namely from double via gavl_time_t to TimeValue or alternatively
from double via FSecs (= rational<long>) to Duration.

As in all the previos cases, actually the compiler is to blame,
and GCC-5 is known to get that one right, i.e. let the SFINAE fail
instead of passing it with a "narrowing conversion" warning.



Note: the real test for command binding with immutable types
can be found in BusTerm_test
2016-02-07 02:20:01 +01:00
536a3a94b9 add special iteration mechanism to visit enclosed child data
the rationale is that I deliberately do not want to provide
a mechanism to iterate "over all contents in stringified form".
Because this could be seen as an invitation to process GenNode-
datastructures in an imperative way. Please recall we do not
want that. Users shall either *match* contents (using a visitor),
or they are required to know the type of the contents beforehand.
Both cases favour structural and type based programming over
dynamic run-time based inspection of contents

The actual task prompting me to add this iteration mechanism
is that I want to build a diagnostic, which allows to verify
that a binding message was sent over the bus with some
specific parameter values.
2016-02-05 04:03:11 +01:00
1913620f37 integrate new stringify() variant and add test coverage
...also for the existing variant, which packages an
arbitrary number of arguments in stringified form
into a given container type. Moreover, the new
form of stringify allows to write util::join
in a clearer way, eliminating the lambda.
2016-02-04 23:30:49 +01:00
2cb1ea6920 devise a pipeline based variant of stringify() 2016-02-04 23:05:41 +01:00
8a33048cc7 simple number range iterator
very similar to boost::irange, but without heavyweight boost
includes, and moreover based on our Lumiera Forward Iterator concept

Such a inline-range construct makes writing simple tests easy
2016-02-04 22:01:48 +01:00
5abc44b813 additional coverage regarding the restrictive handling of LuidH 2016-01-28 23:30:13 +01:00
fc193da1ac unit-test for tuple initialisation from GenNode
- leave out the type conversion part
- instead verify error handling on some typical corner cases
2016-01-28 22:39:38 +01:00
47ce7ad96b research finished: build a (compiletime) tuple from runtime sequence
...should document this by a unit-test
2016-01-28 15:37:35 +01:00
ae7912dc99 refactoring: move new library helpers into final destination 2016-01-28 15:19:09 +01:00
f743784bc9 add accessor for Nth child to our Record type 2016-01-23 17:10:44 +01:00
297f986b5f now able to remove our old Tuple type (closes #988)
all unit-tests PASS again
2016-01-20 01:25:40 +01:00
f6d04d4d02 refactoring(#988): switch correspoinging tests to std::tuple
...with this changeset, our own tuple type should be
basically disconnected and not used anymore
2016-01-19 23:53:20 +01:00
3523b897c2 refactoring(#988): disentangle Tuple metafunctions
we made double use of our Tuple type, not only as a
generic record, but also as a metaprogramming helper.

This changeset replaces these helpers with other
metafunctions available for our typelists or type sequences

(with the exception of code directly related to Tuple itself,
since the intention is to delete this code alltogether shortly)
2016-01-17 00:19:10 +01:00
ecd1375e92 fix and adjust broken test defintions. Closes #985 2016-01-10 12:25:45 +01:00
e518a19435 wrap-up(#985): resolve various leftovers
- replace remaining usages of typeid(T).name()
- add another type simplification to handle the STL map allocator
- clean-up usage in lib/format-string
- complete the unit tests
- fix some more bugs
2016-01-10 11:21:34 +01:00
b56f5a8945 type-display(#985): improvements and supplements
- a regexp based function to discard non-identifier chars
- nice human readable display of boolean values
2016-01-10 03:59:01 +01:00
21c02e3015 type-display(#985): implement extractor for simple type designator
using a heuristic approach on a merely lexical level
2016-01-10 02:02:18 +01:00
08c3d5d4c5 type-display(#985): implement better simplification scheme
use a regexp to scan for some known obnoxious prefixes
2016-01-10 00:31:13 +01:00
88120eba1a unit-test(#985): define more tests 2016-01-09 22:23:50 +01:00
3672873ae6 unit-test(#985): preserve this problem solution as unit test
This clean-up action for Ticket #985 started out as search
for a lightweight generic solution. What is left from this
search now, after including the actual utility code into
our support library, might serve to document this new
feature for later referral
2016-01-09 22:23:50 +01:00
334f542897 clean-up(#985): remove code superseded by this rework
now finally able to remove most of the cruft from format-util.hpp
and get rid of the infamous util::str
2016-01-09 02:05:23 +01:00
615f112f5c clean-up(#985): unify various type-indicating helpers
over time, we got quite a jungle with all those
shome-me-the-type-of helper functions.

Reduced and unified all those into
- typeString : a human readable, slightly simplified full type
- typeSymbol : a single word identifier, extracted lexically from the type

note: this changeset causes a lot of tests to break,
since we're using unmangeled type-IDs pretty much everywhere now.
Beore fixing those, I'll have to implement a better simplification
scheme for the "human readable" type names....
2016-01-09 02:05:23 +01:00
034d5f99dc fix and adjust various test fixtures
due to the new automatic string conversion in operator<<
the representation of objects has changed occasionally.

I've investigated and verified all those incidents.
2016-01-08 00:16:14 +01:00
5e16431b44 fix a long standing Heisenbug in ScopedCollection_test
...other than intended, the bomb did explode on random occasions,
with an probability of about 4% (when rr >= 96).

Btw, there was also the mistake to throw an heap allocated
object by pointer. Damn Java habits.
2016-01-08 00:10:43 +01:00
2c20d407fc mass clean-up: adapt usage of std::cout pretty much everywhere
- remove unnecessary includes
- expunge all remaining usages of boost::format
- able to leave out the expliti string(elm) in output
- drop various operator<<, since we're now picking up
  custom string conversions automatically
- delete diagnostics headers, which are now largely superfluous
- use newer helper functions occasionally

I didn't blindly change any usage of <iostream> though;
sometimes, just using the output streams right away
seems adequate.
2016-01-07 20:12:46 +01:00
0c4495a451 reorganisation(#985): move basic typeString implementation into lib::meta
- simple function to pick up the mangled type
- pretty-printing is implemented in format-obj.cpp
- also move the demangleCxx()-Function to that location,
  it starts to be used for real, outside the test framework
2016-01-05 23:34:53 +01:00
f077c14d47 compiler evolution: get rid of a gcc-4.7 workaround
our minimal compiler requirement is gcc-4.9 since the
transition to Debian/Jessie as reference system.

gcc-4.9 is known to treat SFINAE on private fields properly
2016-01-05 23:16:18 +01:00
c104e28ebf inline(#985): provide our own minimal variant of enable_if
this is a stripped-down and very leightweight variant
of the well-known enable_if metaprogramming trick.

Providing this standard variant in a header with minimal
dependencies will allow us to phase out boost inclusions
from many further headers. As a plus, our own variant
is written such as to be more conciese in usage
(no "typename" and no acces of an embedded "::type" menber)
2016-01-05 22:00:53 +01:00
ff7ac5523f clean-up(#985): tighten basic header lib/meta/util.hpp
This header shall provide only very fundamental
metaprogramming helpers, since it is included pervasively
2016-01-05 22:00:53 +01:00
16a70ce9f8 some coverage for string prefix/suffix helper
so I'll sleep better tonight...
2016-01-02 22:50:15 +01:00
3230660d86 implement, cover and use the log clearing function 2016-01-02 02:00:07 +01:00
c6945a452e need helper functionality for tests to scrap existing log contents
...this is necessary whenever the mocked facility covered
by log matching is managed automatically as singleton,
because then other test cases will leave garbage
in the log
2016-01-02 01:41:53 +01:00
603f9e2b7d DOC: fix some Doxygen link syntax
I worked under the erroneous assumption, that Doxygen
will use its internal entity-IDs as the link-IDs when
generating mardown-links. Yes, this seemed logical and
this would be the way I'd implement it....

But seemingly, Doxygen is not so consistent when it
comes to questions of syntax. The same holds true for
markdown, which lacking a coherent definition anyway.

Another problem is that Doxygen's auto-link generation
frequently fails, for reasons not yet clear to me.
Sometimes it seems to be necessary to give it a nudge
by including the \ref command. While I'm not willing
to go into focussed invstigation of Doxygen syntax
right now, at least I've done a search-and-replace
to remove the malformed links I've written the
last days
2015-12-27 03:16:49 +01:00
3239ea1f87 occasional clean-up of somewhat confusing variable names in test
you'd expect a variable s1 to be a string, wouldn't you?
2015-12-26 02:34:22 +01:00
cb4a0a6e60 change the EventLog header to store a "this" attribute
seems more logical than calling the attribute "ID",
especially since we're now able to use the on("xyz") matcher
2015-12-15 23:44:34 +01:00
c8068496d1 EventLog unit test PASS
so this turned out to be rather expensive,
while actually not difficult to implement.
On the way, I've learned
- how to build a backtracking matcher, based on
  a filtering (monadic) structure and chained lambdas
- learned the hard way how (not) to return a container
  by move-reference
- made first contact with the regular expressions
  now available from the standard library
2015-12-13 05:03:36 +01:00
d0cdae2cee implement matching on regular expressions 2015-12-13 03:24:25 +01:00
c13b859aa5 fix typo in test assertion 2015-12-13 02:02:54 +01:00
42a5668831 implement further match refinements (type, attribute, target) 2015-12-12 23:41:24 +01:00
33f7fe116a implement refinement filter on log entry's arguments.
Whew! functional programming is such a powerful concept.
You get additional refinement and lazy backtracking
basically for free....
2015-12-12 03:13:32 +01:00
894ef68a8f EventLog: implement logging of function invocations 2015-12-12 01:01:46 +01:00
761154ae63 stub the code into submission.... 2015-12-11 20:02:30 +01:00
a9096d8781 WIP: draft further logging functionality to cover
damn nasty how much (eays to implement) functionality
you obviously want to have on any logging facility.
2015-12-11 02:27:14 +01:00
f489343401 WIP: draft behaviour of function call logging 2015-12-10 22:51:31 +01:00
bf92333339 implement log joining in shared heap storage 2015-12-09 01:18:15 +01:00
09afbb0e12 change implementation technique: use flags instead of exceptions
abandon the use of an assertion exception to signal match failure,
rather use a final bool conversion to retrieve the results.

Error messages are now delivered by side effect into STDERR


The reason is we're unable to deliver the desisred behaviour
with the chosen DSL syntax in C++ ; on a second thought the
new approach is even better aligned with the overall way
we're writing tests in Lumiera. And we produce match-trace
messages to indicate the complete matching path now
2015-12-08 03:20:52 +01:00
00df7ff477 draft behaviour of helper for negated machtes 2015-12-07 23:47:07 +01:00
a95f9a6cac draft how "log joining" shall work 2015-12-06 04:21:35 +01:00
c9d113be87 EventLog: implement match backwards
..based on the new IterCursor, which gives us the ability
to switch the iteration direction
2015-12-06 03:35:07 +01:00
eb208ea145 direction switching iterator unit test PASS 2015-12-06 02:28:47 +01:00
f9c0c4c3d0 WIP: draft a direction switching iterator
...we need that to allow matching backwards in the EventLog
2015-12-06 00:10:27 +01:00
5874b1b4dc change lib::Record string representation to handle empty parts better
...no need to enclose empty sections when there are no
attributes or no children. Makes test code way more readable.



TestEventLog_test PASS as far as implemented
2015-12-05 03:57:11 +01:00
6659a7dee1 augment extensible filter to add the obvious variations
that is
 - allow also for a disjunctive extension
 - allow for negated conditions
 - allow to flip the current condition

unit test PASS
2015-12-05 02:00:44 +01:00
075653a815 define the expected behaviour for an extensible filter iterator 2015-12-05 00:52:45 +01:00
68dd8a9e03 refine implementation draft: make FilterIter extensible on-the-fly
after looking into our various iterator tools,
it seems obvious that our filtering iterator implementation
has almost all of the required behaviour; we only need to
add a hook to rewrite and extend the filtering functor,
which can now nicely done with a lambda closure.

This means all memory management, if necessary, is
pushed into std::function and the automated memory
management for closures provided by the runtime.
2015-12-05 00:28:07 +01:00
d38b28da5b implement initial EventLog entry 2015-12-02 01:31:37 +01:00
b2542b86f7 stub and rectify interfaces defined thus far.
...compilation PASS again
2015-11-28 23:50:56 +01:00
809ed36b56 WIP: draft initial test for event logging helper 2015-11-28 19:20:10 +01:00
d04e6d74d8 WIP: arrange some elements needed for MockElm implementation 2015-11-27 19:24:00 +01:00
ba48aa306a fix missing header include in test
This omission was spotted when compiling with GCC-5 on Ubuntu/wily
2015-11-20 04:35:43 +01:00