Gibheer has quit [Read error: Connection reset by peer]
<dkubb>
solnic: good morning
<solnic>
dkubb: I have a question related to --rspec-dm2 strategy
<solnic>
dkubb: I saw you wrote that every public method should be specced separately otherwise you're relying on accidental coverage
<solnic>
I was wondering about cases when to check behavior of one method, you use another one
<solnic>
for instance, there's #track and #tracked? in rom-session
<solnic>
I can test behavior of #track by calling foo.track(bar) and then expect(foo.tracked?(bar).to be(true)
<solnic>
I'm having trouble coming up with any reasons to test both methods in isolation
Gibheer_ is now known as Gibheer
zekefast has quit [Quit: Leaving.]
<dkubb>
yeah, that's not really what I was talking about
<dkubb>
it's fine to use one method to check the state of another command method
<dkubb>
what I'm more concerned about is when you have a public method that *uses* another public method, and you don't write any tests for the second one because you're relying on incidental coverage. if the first method ever changes it's implementation then the second one becomes uncovered, and there's the possibility of api drift
<dkubb>
if you're relying on incidental coverage you're writing integration tests
<dkubb>
you're also losing out on the benefits of using the test to drive the design of the public interface. you're not using the test to help the design, but rather soley for behavior verification.. which is fine as long as you know that's what's happening, but the problem is that most people who do this think they are getting the same benefits and they're not
<solnic>
dkubb: ok but in this specific case, don't you think a separate test for tracked? is just totally redundant?
<dkubb>
the gap between code written using those two approaches is usually fairly clear
<solnic>
I mean...it's basically THE same test, but reversed (if you know what I mean)
<solnic>
I need to think about this
<dkubb>
solnic: you're talking about a really narrow use case. you could very well TDD out the #track method and decide instead of modifying state you return a new kind of object that represents the state change, and it's #tracked? method always returns true, etc
<dkubb>
solnic: there's always an exception to every rule of course
<solnic>
hmm
<dkubb>
solnic: you've read GOOS right? I just want to make sure we're on the same page
<solnic>
I don't recall reading it
<solnic>
it's the one with Java examples?
<solnic>
well, if I change behavior of track, my test would fail
<dkubb>
it's been a year or so since I looked at it, I'm almost due for anothe read-through
<solnic>
and I agree with it
<dkubb>
I consider it foundational
<dkubb>
I try to read my foundational books every 1-2 years
<solnic>
my only concern is having too many, too detailed tests, that's why I'm discussing this stuff with you guys
<dkubb>
I think writing a test for the public interface directly is valuable
<dkubb>
if someone else relies on an interface I think it should be tested
<solnic>
I've seen way too many tests checking various implementation details
<dkubb>
because it would be easy to modify a method, and then modify the methods that use it, and for all the tests to continue passing
<dkubb>
yet code that uses that public interface is broken
<dkubb>
you have to separate implementation detail from behaviour
<dkubb>
sometimes you can get them confused
<dkubb>
sometimes it *is* the job of a method to send a message to another object
<solnic>
sometimes
<dkubb>
in which case you'd better have a test for that
<solnic>
but it's usually pretty easy to spot on tests checking implementation details
<dkubb>
I dunno. I think it's actually quite difficult
<solnic>
really?
<dkubb>
so there's a cycle everyone goes through with testing
<dkubb>
first you mock all the things
<dkubb>
then you realize your specs are too brittle
<dkubb>
so then you do integration testing for everything
<dkubb>
then you realize your specs are too slow
<dkubb>
then you most likely bounce back and forth between those two extremes for a while (forever?), except with less extreme positions each time
<solnic>
sounds about right
<dkubb>
when I'm designing a method I think "what message does this need to send to the object", and I will write a test for that. I don't test what happens to the other object or what it does with it, just that my method is doing what it's told
<dkubb>
however, what I try to do is use things like as_null_object and only assert the smallest possible things I can about the object I injected
<dkubb>
I try to keep it *just* to the exact things I care about
<solnic>
yup
<dkubb>
the other thing about this bouncing is that each time you jump back you come back to it with a bit better understanding (or at least it feels that way) and you can spot some of the flaws you made last time you were doing it
<solnic>
what I was trying to do recently was to focus more on behavior of the objects
<dkubb>
yeah, externally verifiable behaviour
<dkubb>
I think that's important, but I also think verifying messages is important.. I use different strategies for testing different kinds of objects
<dkubb>
immutable objects lend themselves really nice to verifying state
<dkubb>
because you can do something, and check the state of the new object.. and state changes are explicit and happen kind of "inside out" when compared to normal objects
<dkubb>
with mutable objects I tend to verify message passing, because verifying state is a bit harder
<solnic>
that's true
<solnic>
it's very different with immutable objects
<dkubb>
I think classicist TDD fits nicely with immutable objects, and mockist TDD fits nicely with mutable objects (very, very broadly speaking)
<dkubb>
I like to have immutable objects at the core of my system mostly.. sort of like how Gary Bernhardt describes in http://www.confreaks.com/videos/1314-rubyconf2012-boundaries .. although I arrived at the same conclusions independently a few years ago
<solnic>
yeah I read that article recently
<solnic>
yes me too, I guess it leads to such design in a natural way once you start using immutable objects
<solnic>
I arrived at the same conclusion...2 months ago :P
<dkubb>
:)
<dkubb>
veritas was such a good playground for this
<dkubb>
I learned so much about immutable objects, how to test them, and where they work and where mutable objects work
<solnic>
dkubb: ok I gotta focus on work, thanks for chat and ttyl :)
<snusnu>
* Actually support observers for actions that are
<snusnu>
configuring a dispatcher actually made this
<snusnu>
used as chain pivot handlers (the old way of
<snusnu>
impossible).
<snusnu>
mbj: maybe this was also part of your confusion wrt to chains
<snusnu>
mbj: wdyt about adding Concord::Initializer.new(:foo, :bar) which only adds #initialize without readers and equalizer?
<snusnu>
mbj: it could dry up (and thus reduce flay score) for cases where you need specific equalizer behavior but still want to do a simple composition of objects
<snusnu>
mbj: i have 2 places in substation where i could use that
<snusnu>
mbj: if you agree, i would do the PR
cored has joined #rom-rb
cored has joined #rom-rb
snusnu has quit [Ping timeout: 246 seconds]
snusnu has joined #rom-rb
snusnu has quit [Client Quit]
_whitelogger_ has joined #rom-rb
zekefast has quit [*.net *.split]
kalleth has quit [*.net *.split]
_whitelogger has quit [*.net *.split]
snusnu has joined #rom-rb
_whitelogger__ has joined #rom-rb
zekefast has joined #rom-rb
<snusnu>
mbj: do you have any idea why flay score increases from 107 to 121 if all i do is move a previously nested class into its own file?
<snusnu>
mbj: imo that's a bug
<snusnu>
mbj: oh wait, i'm crazy
<snusnu>
mbj: nice, it was actually flay telling me friendly that i forgot to remove (now duplicated defs) that came with me copying them over to the extra file :)
<snusnu>
mbj: all is good
_whitelogger_ has quit [*.net *.split]
kalleth_ has quit [*.net *.split]
zekefast1 has quit [*.net *.split]
ChanServ has quit [*.net *.split]
cored has quit [Remote host closed the connection]
cored has joined #rom-rb
snusnu1 has joined #rom-rb
mongreli1n has joined #rom-rb
ChanServ has joined #rom-rb
snusnu has quit [*.net *.split]
mongrelion has quit [*.net *.split]
snusnu1 has quit [Quit: Leaving.]
kapowaz has quit [Ping timeout: 241 seconds]
snusnu has joined #rom-rb
cored has quit [Remote host closed the connection]
cored has joined #rom-rb
kapowaz has joined #rom-rb
snusnu has quit [Client Quit]
snusnu has joined #rom-rb
ChanServ has quit [*.net *.split]
<snusnu>
mbj: how can i run mutant for my integration tests? i'm curious how many mutations they don't cover
<cored>
but implemented with the chain of responsability pattern?
<snusnu>
cored: well, yes and no, it's not at all concerned with http routing, but it basically allows you to name all your actions, and then invoke them by that name
<snusnu>
cored: an http route might simply call a named action
<snusnu>
cored: really, at its core, it's an implementation of the chain of responsibility pattern
<snusnu>
cored: you can plug it behind rails/sinatra/rack whatever
<snusnu>
cored: the beauty (well, at least imho), is that it gently guides you towards designing your app "properly" … typically encountered steps like sanitization/authentication/authorization/validation/presenter wrapping/rendering .. can (and imo should) be implemented in dedicated classes, making them *very* easy to test
ChanServ has quit [*.net *.split]
<snusnu>
dkubb: btw, if you happen to build any toy (web) app at some point and want to try something different from rails, i'd really appreciate it if you'd take a closer look at substation, and provide feedback :)
<Gibheer>
snusnu: what is concord?
<snusnu>
dkubb: i'm saying web app, but really any kind of request/response cycle app
<snusnu>
Gibheer: it's a little gem by mbj which defines a simple #initialize for you, along with equalizer definitions .. it's meant for simple composed objects, that don't need anything else but assignment of the params passed to #initialize
<snusnu>
Gibheer: plus the equalizer behavior
<dkubb>
snusnu: cool, I'll keep it in mind
<Gibheer>
snusnu: ah, okay. It isn't at all obvious, that it does that :/
<snusnu>
dkubb: i'm obviously biased, but imo it's the clearest, easiest and most maintainable way i've written web apps so far
<Gibheer>
I just saw Concord::Public.new(:foo), looked at foo.rb and it had the same line ...
<snusnu>
dkubb: it provides gentle guidelines, in ~300 lines of mutation covered code :) plug it behind rack + http_router and you're all set
<snusnu>
Gibheer: Concord::Public.new(:foo) makes the attr_reader :foo public … Concord.new(:foo) would make it protected only (since that's enough for equalizer)
<snusnu>
Gibheer: the beauty with concord is that once you know it, seeing it being included in a class, immediately tells you a few things: 1) it's a simple composition of the objects named like params passed to Concord.new 2) it equalizes on those params 3) it provides public/protected readers for those objects
<Gibheer>
if you can remember it, yeah
<snusnu>
Gibheer: trust me, you can, fast
<snusnu>
;)
<Gibheer>
snusnu: sure, thee is much one can learn with time
<Gibheer>
but after I tried haskell, I don't like hiding functionality anymore ^^
<dkubb>
yeah, it's no more difficult than remembering what attr_reader does. except imho it's nicer because it doesn't monkey patch Object to provide it's behaviour
<Gibheer>
nothing against the lib though, it is a good idea
<Gibheer>
maybe just a naming problem ^^
mbj has joined #rom-rb
<snusnu>
yo mbj
<mbj>
snusnu: jo
<mbj>
sitting in train and we can talk.
<mbj>
Was a big fat meeting, but fun!
<snusnu>
mbj: awesome
<snusnu>
mbj: so, how would i run mutant against my integration specs?
<snusnu>
mbj: —rspec-integration isn't a recognized strategy anymore
<snusnu>
dkubb: btw, our devtools coverage task makes it kinda hard to run it for integration tests only
<mbj>
snusnu: We need to add it again.
<snusnu>
damn
<snusnu>
:p
<mbj>
snusnu: BTW I consider killing the strategy concept!
<mbj>
snusnu: The new spec lookup would work like this:
<mbj>
1. Load all spec/**/*_spec.rb files after loading spec_helper.rb to populate the rspec world
<mbj>
2. Run the most specific spec via filtering specs by description.
<mbj>
3. If there is no spec wide the selector
<mbj>
3. If there is still no spec wide the selector
<mbj>
n. Runn all specs.
<snusnu>
sounds like a plan!
<mbj>
So for a subject Foo::Bar#baz we run spec with description "Foo::Bar#baz" first, than: "Foo::Bar", than "Foo" than all!
<mbj>
If we find a specific spec that does not kill mutation it will be an error
<mbj>
if you have a spec for Foo::Bar#baz but it does not kill mutations on Foo::Bar#baz it will error, regardless if spec "Foo::Bar" would kill.
<snusnu>
obviously we'd *try* tun run Foo::Bar#baz, then Foo::Bar etc, not run all of them, if they're even present?
<snusnu>
ah ok, yeah, fair enough
<mbj>
This will be the default behavior. + I'll add subject specific overrides.
<mbj>
So we can match all subjects within SQL::Generator::Emitter to a specific spec.
<mbj>
This will be far more flexible and accessible.
<snusnu>
yeah
<mbj>
You can still follow --rspec-dm2 if you like.
<mbj>
But you can also follow --rspec-unit
<mbj>
or whatever.
<snusnu>
so, in the meantime, there is NO WAY i can run mutant on my integration specs?
<mbj>
rm -r spec/unit; mutant --rspec-full
<mbj>
git checkout spec/unit :D
<snusnu>
heh
<snusnu>
ok
<mbj>
snusnu: BTW I need a specific kind of substation action/chain/handler/processor
<snusnu>
mbj: pls explain
<mbj>
That merges results from various child chains/action/handler/processor
<snusnu>
you can use Evaluator::Transformer and write your own handler for it
<mbj>
Or places them under a specific hash key, ideally instantiates an anima based dto.
<snusnu>
well, you can currently only use transformer as an outgoing processor tho
<snusnu>
if it's incoming, you're anyways free to return whatever from your evaluator handlers (provided you follow the contract)
<snusnu>
i.e. you can stick whatever you want into Result#output
<mbj>
snusnu: The problem is, I'd like to reuse specific processors.
<mbj>
I can invoke them for my own.
<mbj>
But I'll have to do this often to merge the results of two processor chains.
<snusnu>
mbj: btw, if you have time, please check out the latest codes (especially *since* 0.0.9), i nuked tons of stuff (like, the old config hash) .. and added support for observable actions *inside* chains
<mbj>
snusnu: hehe
<mbj>
snusnu: Okay
<snusnu>
mbj: do it a few times, use substation, then we'll see if it can/should be generalized
<mbj>
yeah
<snusnu>
mbj: basically, you can now do: SUBSTATION_ENV.action(SOME_HANDLER, [ SOME, OBSEVERS ])
<snusnu>
mbj: and then you can use those action "proxies" as pivot handlers in chains
<snusnu>
mbj: making sure observers get called
<snusnu>
mbj: without that stupid hash config
<snusnu>
mbj: i was so happy when i nuked utils.rb with all that ugly methods ;)
<snusnu>
mbj: also, i FINALLY have a nice integration spec
<dkubb>
mbj: I wonder if it would be possible to use set_trace_func to identify which lines of code are hit by which specs, then when we mutate a line of code, we can just run the specs that relate to it?
<dkubb>
mbj: I believe in set_trace_func you can access caller to associate a line with a spec
<mbj>
dkubb: Isnt the key concept of mutant to make the specs cover the code, not the code cover the spec?
<mbj>
That trace func approach will not force the spec author to write specs for uncovered codes.
<mbj>
As an additional advanced sanity check, yeah. But not as primary operation scenario.
<mbj>
snusnu: nice!
<dkubb>
mbj: yeah, I was just offering alternate approaches. my personal preference would be to use YARD annotations to narrow down which parts of the public interface have tests
<mbj>
BTW, I JUST KILLED MY HEADPHONES.
<mbj>
I'm without music now.
<mbj>
:( getting noked out of the zone
<mbj>
dkubb: Okay, got your point.
<mbj>
dkubb: Lets add a todo item or enhancement issue?
<dkubb>
mbj: I can do that. this would probably be an alternate strategy.. fwiw I still like the idea of strategies, but I think your idea about having something that starts off narrow and gradually widens is fine for a default strategy
<mbj>
dkubb: I plan to add a list of "slow killed mutations" and the killing spec location, this will allow you to spot cases where you might have to use another granularity
<dkubb>
mbj: that's a good idea
<mbj>
dkubb: I'll nuke all but the --rspec-dm2 strategy
<snusnu>
fwiw, i really like the idea that mutant is "driven" by @api public yard tags
<mbj>
dkubb: So while heavily refactoring or spiking you still have good muation coverage support and know easily where your specs need to be refactored
<mbj>
yeah, I'll realize this via a mutant-yard plugin
<snusnu>
and that all those @api public methods have isolated specs
<mbj>
I dont think mutant should depend on yard.
<dkubb>
yeah, there's also the @private tag in yard that you can use to annotate private classes
<snusnu>
mbj: re depending on yard, agreed
<dkubb>
I'm fine with that as long as we can distribute gems that plug into mutant
<snusnu>
mbj: btw, do you agree, that in case an action (a pivot handler) raises an exception, *no observers* should be called?
<mbj>
I'll provide an abstract class for strategies, so we can use that register style to register new strategies that would automagically get picked up by the cli.
<snusnu>
mbj: there's always a chain specific failure chain that gets invoked in case an action raises an uncaught exception
<mbj>
*as long the "plugin" is loaded with mutant.
<snusnu>
mbj: ok, mutant running —rspec-full for integration specs now ....
ChanServ has joined #rom-rb
<snusnu>
chanserv has its troubles today ....
<snusnu>
mbj: wow, the integration specs have 90.68% mutation coverage (!)
<mbj>
snusnu: nice!
<snusnu>
mbj: i'll even pimp it a bit, it actually shows a few mutations that can (and imo should) be covered with integration specs too
ChanServ has quit [*.net *.split]
ChanServ has joined #rom-rb
<mbj>
snusnu: nice
ChanServ has quit [*.net *.split]
<snusnu>
mbj: integration specs now have 92.31% mutation coverage .. i'm down with that
<snusnu>
mbj: wdyt, does the fact that very few integration specs can lead to 100% linecov and 92.31% mutcov speak for a nice and tight public api?
zekefast has quit [Quit: Leaving.]
fphilipe has joined #rom-rb
dkubb has joined #rom-rb
<dkubb>
snusnu: I think it's interesting how you're looking at mutation coverage for integration tests
<snusnu>
dkubb: yeah, i had this thought, because basically, if i can still exercise most codepaths with calling very few methods (in fact, *one* method), it has a "tight" feeling to it
<snusnu>
dkubb: even this one method, is called with a very limited set of different parameters, so yeah, the overall input needed to exercise almost all of substation's codebase seems like the "code is very much tailored towards the domain" .. if you know what i mean
<dkubb>
snusnu: do you find it particularly slow?
<snusnu>
dkubb: nope, 287secs
<snusnu>
dkubb: granted, the codebase is pretty small .. 676 mutations in 276loc
<snusnu>
dkubb: which makes me happy btw, imo it can have quite some positive effect on the overall app design, for such little code :)
<dkubb>
snusnu: I was thinking maybe mutant doesn't need strategies if mbj decides to implement something that uses a "most specific match first" approach. we could easily have another tool that simply verifies the layout of the specs match dm2 style, or the yard style I was talking about
<dkubb>
snusnu: I kinda would like to have it so I can just do: mutant MyClass#method spec/unit
mbj has quit [Read error: Connection reset by peer]
<dkubb>
so I would specify the path for mutant to look in, and then it would look for the most specific match first
<dkubb>
looking for a per-method spec, then per-class, then project-wide
<dkubb>
I also think it might be interesting having it look at ancestor/descendant specs too
<snusnu>
wdym by that?
<dkubb>
well, sometimes I have behaviour in a method that is solely for the benefit of descendant classes, like in say an abstract class
<snusnu>
you mean Foo as ancestor of Foo::Bar .. and Foo::Bar::Baz as descendant?
<snusnu>
or inheritance, ok
<dkubb>
if I do mutant MyClass#name spec/unit .. it should maybe look at spec/unit/my_descdant/name_spec.rb
<dkubb>
you get the idea
<dkubb>
I find it annoying that I have to write specs for modules and abstract classes directly, I would rather write shared specs and then have specs for the "concrete" implementations
<snusnu>
yeah, that annoyed me too already
cored has quit [Ping timeout: 276 seconds]
<snusnu>
so yeah, i think that's a good idea, this sort of specs are mostly stupid duplication currently
<snusnu>
i have quite a few of them in substation
cored has joined #rom-rb
<snusnu>
i already considered rewriting the specs to work with —rspec-unit .. but i ditched that idea, and will wait till mutant is improved in that area
<snusnu>
sometimes i found it a bit tiresome having to change shitloads of specs when my actual integration spec still was passing happily after a refactoring
<snusnu>
then again, i do agree with your point that @api public methods should still have their own isolated unit specs, for all the reasons you mentioned
<snusnu>
i'm actually coming closer to a point where i want to pin down (as in properly tag) the @api public
<dkubb>
yeah
<dkubb>
I mean, if you have a WIP, don't nail the public interface down
<dkubb>
but as you approach something 1.0 quality, and people will be depending on the code, you should down the public parts of the api
<snusnu>
yeah, the nice thing (and i wonder if that's related to the high integration spec mutcov) is that substation actually needs *very little* public api
<dkubb>
it's fine if you want to keep it a thin layer, with a private center. I don't think it matters as long as your specs can kill every mutation via the public interface
ChanServ has joined #rom-rb
<dkubb>
if you have a part of the code that can't be reached or killed from the public interface, then maybe it's dead code
<dkubb>
I see nothing wrong with thin public interfaces as long as it's clear what's public and what is private
<snusnu>
yeah, most certainly
<dkubb>
I do think that code has more utility when it can be used publicly though
<snusnu>
yeah, the thinner the public api, the more focused the library … as a thought
<dkubb>
rails is an example of something that has a thin public api, and a large private api
<dkubb>
and it's pieces are not usable outside the monolith
<dkubb>
I would rather have a thin public *and* private api ;)
<snusnu>
yeah :/
<snusnu>
heh
<dkubb>
there's a balance of course
<dkubb>
but I tend to like small, single purpose pieces, and I think if you go in that direction a thin public/private interface is a side effect
<snusnu>
hah i wanted to say exactly that just now
mbj has joined #rom-rb
<snusnu>
as the private interfaces consist of the public ones provided by the smaller single purpose pieces
<dkubb>
I also think it's a nice idea to pull reusable components into the support directory too, and get them ready for extraction
<mbj>
snusnu: nice (integration coverage)
<mbj>
BTW, why dont we measure amount of code via amount of mutations?
ChanServ has quit [*.net *.split]
fphilipe has quit [Ping timeout: 240 seconds]
<mbj>
I think this is the most valid measurement! Mostly because statement count does not weight statement complexity
<dkubb>
I think mutation count is probably better than LOC for measuring code complexity
<snusnu>
something like mutations/loc ?
<mbj>
LOC as metric is stupid.
<mbj>
snusnu: This is quality :D
<snusnu>
heh
<mbj>
*maybe
<dkubb>
I would love to have a scatter plot graph of mutations per class
<dkubb>
see where the outliers are
<mbj>
dkubb: mutcov!
<snusnu>
dkubb: as a poorman solution, look at the green dots mutant produces as a bar chart ;)
<mbj>
I think my current contract lets me buffer enough to focus on that service!
<dkubb>
I've said this before, but in general I think if you take most metrics, put them on a scatterplot, the goal should be a tighter cluster of "dots"
<dkubb>
haha
<snusnu>
the more dots, the higher the bar => outliers
<mbj>
dkubb: +1
<dkubb>
you want a tighter cluster, and then you want to move that cluster along the X/Y axis towards whatever is "better" (which may be higher or lower, left or right depending on the metric)
<snusnu>
i loved when i saw that "high bar" go away when i nuked Substation::Utils :)
<dkubb>
sometimes top-left is better, sometimes, bottom-right is better
<dkubb>
although I think I like it when bottom-left is better.. I would rather see that used more
<snusnu>
yeah, that'd be a nice visualization
<dkubb>
with top-right being worse
<snusnu>
i wonder how my bar chart abstraction (desiring low bars) fits with our "raising the bar" approach :D
<snusnu>
lol, i always smile when i think about james cameron ...
<dkubb>
snusnu: you have a metric you track, or is this just mentally?
<dkubb>
haha, me too
<snusnu>
dkubb: it's just mentally, the way i visualize mutant's dots currently
<dkubb>
bars are aI think a bar chart is ok, but I like the scatterplot visualization because it's easier to see outliers imho
<snusnu>
absolutely
<dkubb>
I hate outliers in code
<snusnu>
they are to be hated
<dkubb>
I prefer homogenous distribution of complexity
<dkubb>
I suppose I should qualify that as negative outliers
<dkubb>
something at the very "bottom left" of a scatterplot would be alright with me. sometimes you do have a few things that are much simpler than the majority of code
<snusnu>
yeah, otherwise you always have code you don't actually want to see in the back of your head :)
<dkubb>
the ones I worry about is where you put a ton of complexity in one spot
<dkubb>
chances are that spot is the weakest link.. most likely to be buggy, and least likely to be tested well
<snusnu>
well in terms of "ease of testing", not (mut)cov i assume :)
<snusnu>
what i mean is, you can assume it's tested well if its mutation covered, but that doesn't tell you what horrible spec setup you had to write for that
<mbj>
snusnu: I'm thinking hard about an rspec alternative with familiar syntax focusing on "subject/object/context" and lots of implicit behavior
<mbj>
I really dislike the high amount of terminal duplication in our specs.
<snusnu>
terminal duplication?
<dkubb>
mbj: I would want something concurrent by default :)
<snusnu>
i'd second that
<snusnu>
:)
<mbj>
snusnu: If you have a grammar that produces chars on your terminal these chars are terminals.
<mbj>
Its "grammar speek"
<dkubb>
I don't see the point in test frameworks that do everything serially by default. it should be the other way around, you should have to specify when tests need to be run serially, otherwise everything happens in parallel
<dkubb>
it would be awesome for testing immutable objects too
<snusnu>
mbj: ok, i'm familiar with that concept, just didn't get the link
<mbj>
snusnu: nice
<mbj>
After fighting literal duplication I now started to hate terminal duplication :D
<snusnu>
hehe
<dkubb>
I would probably want something that makes testing command and query methods specifically. a command could be run once, and then each resulting behaviour could be asserted using the same input/output, concurrently
<mbj>
dkubb: Yeah, you remember that implicit spec defaults that reflected on __FILE__ of a _spec.rb to set some defaults?
<snusnu>
mbj: btw, looking at it this way, substation code evolved towards what you call removing terminal duplication
<dkubb>
sort of like what we had to do with the before(:all) setup hack
<mbj>
I now have gone far bejond this, conceptually.
<mbj>
The whole dsl is around building a specific method call
<dkubb>
mbj: oh yeah?
<dkubb>
mbj: so something declarative?
<snusnu>
mbj? dsl? so soon?
<snusnu>
:p
<dkubb>
hah
<mbj>
lulz
<dkubb>
well written methods should be possible to test with a limited grammar
ChanServ has joined #rom-rb
<mbj>
I linked that file multiple times
<dkubb>
assuming you stick to command/query separation
<mbj>
it does setup subject, object, arguments to object arguments to subject (method) implicitly
<dkubb>
the worst are command + query combos.. like how resource.valid? is
<dkubb>
mbj: I wonder if some of the ideas behind quickcheck could be worked into that
<mbj>
dkubb: hehe, vanguard turns out to be a big improvement.
<mbj>
BTW the first time I was questioning that strategy concept in mutant was when I relaized vanguard needs mutant proofe specs!
<mbj>
proov
<mbj>
proof
<mbj>
dunno.
<snusnu>
proof
<snusnu>
vanguard is nice
<dkubb>
mbj: with quickcheck you specify the behaviour of a method, usually with an alternate algorithm to verify things
<dkubb>
mbj: then it generates random inputs using your specification and asserts the result
<mbj>
dkubb: yeah, I remember we talked about this already.
<snusnu>
i dunno why, but this always feels a bit "wasteful" to me
<mbj>
I more and more see: I could dedicate myself to mutant and help the rom-rb project more here than with working on anything else.
<mbj>
Apart from adapters :D
<snusnu>
as long as you use substation for client code, that's fine
<snusnu>
:p
<mbj>
lulz
<snusnu>
cause i really need your input for that as well :)
<snusnu>
not now, generally speaking ...
<mbj>
Substation is fully mutation covered, even at its young I dont have bad feelings using such a lib for clients stuff.
<mbj>
s/at/as/
<dkubb>
I actually see quickcheck as something you could use alongside normal tests, like how mutant works
<dkubb>
it finds bugs that you write a failing test for and then fix. so I wouldn't normally want to replace unit tests with it
<dkubb>
more like augment the testing
<mbj>
dkubb: couldnt mutant provide quickcheck like functionallity?
<mbj>
It is very close to what mutant does
<dkubb>
I don't know if it finds the same classes of errors as mutant though.. I suspect it intersects, but does not completely overlap
<snusnu>
so, when mutant can actually mutate "all" that makes sense to mutate .. which kind of bugs would quickcheck still be able to find?
<dkubb>
it's close, but not exactly the same thing. I think if mutant used YARD annotations it could get closer
<mbj>
BTW how to call __LINE__ and __FILE__
<mbj>
meta literals?
<mbj>
macros
<mbj>
pseudo values
<snusnu>
builtin consts ?
<mbj>
preprocessor expansions?
<mbj>
s/call/name/
<mbj>
snusnu: it is not really const :D
<snusnu>
trudat
<mbj>
use it twice to see a new value
<mbj>
* at different locations
<snusnu>
:)
<snusnu>
mbj: speaking of eliminating terminal duplication .. do you think observers could be useful to have for any sort of handler in a chain? probably rather for incoming handlers than outgoing ones?
<dkubb>
mbj: fwiw, I would much rather see a *good* property based testing framework than a new TDD framework ;)
<snusnu>
mbj: so basically, can you think of a situation where you'd want to register an observer for any processing step *before* the actual action (pivot handler) is called?
<dkubb>
mbj: there's a few attempts in ruby, but nothing that has caught on
<mbj>
dkubb: I bet I can make a very fast unit test framework.
<mbj>
dkubb: *fast for mutant!
<dkubb>
mbj: yeah, I think we're on the same page
<dkubb>
mbj: yeah, I'm sure we can make something specialized that runs the tests 2-5x faster than what they do now
<dkubb>
mbj: I suppose if you focus on keeping it *really* small, then it wouldn't be as much effort.. and would likely be faster
<mbj>
dkubb: And we have a pending low hanging performance fruit
<mbj>
dkubb: EACH MUTATION PARSES spec/foo/bar/baz_spec.rb
<mbj>
and spec_helper.rb, spec/support/* etc.
<mbj>
I'd *love* to load them in the parent process!
<dkubb>
mbj: can they be required once, and then forked.. using CoW it should be possible to only have them pased one time
<dkubb>
of course ruby 2.0 would benefit, while 1.9.3 would not, which I am fine with
<dkubb>
mbj: this is a neat presentation: http://htmlpreview.github.io/?https://raw.github.com/strangeloop/lambdajam2013/master/slides/Norton-QuickCheck.html .. I love how they used quickcheck to find bugs in a db, sort of like how we did
<dkubb>
mbj: except it's neat because they found the bug through a series of random commands.. so it would likely expose different classes of bugs when compared to mutation testing
<dkubb>
this is closer to the fuzz testing stuff we did in axiom
solnic has joined #rom-rb
ChanServ has quit [*.net *.split]
postmodern has joined #rom-rb
ChanServ has joined #rom-rb
cored has quit [Ping timeout: 260 seconds]
cored has joined #rom-rb
cored has quit [Changing host]
cored has joined #rom-rb
ChanServ has quit [shutting down]
ChanServ has joined #rom-rb
ChanServ has quit [*.net *.split]
knowtheory has quit [*.net *.split]
kapowaz has quit [*.net *.split]
snusnu has quit [*.net *.split]
dbussink has quit [*.net *.split]
Gibheer has quit [*.net *.split]
namelessjon has quit [*.net *.split]
mongreli1n has quit [*.net *.split]
stormwind has quit [*.net *.split]
xargoon has quit [*.net *.split]
xybre has quit [*.net *.split]
kpwz has quit [*.net *.split]
elskwid has quit [*.net *.split]
dkubb has quit [*.net *.split]
shingara has quit [*.net *.split]
jdsiegel has quit [*.net *.split]
coxandrew has quit [*.net *.split]
cored has quit [*.net *.split]
mbj has quit [*.net *.split]
postmodern has quit [*.net *.split]
pdswan has quit [*.net *.split]
indrek has quit [*.net *.split]
kalleth has quit [Excess Flood]
kalleth has joined #rom-rb
solnic has quit [Ping timeout: 260 seconds]
mbj_ has joined #rom-rb
cored has joined #rom-rb
ChanServ has joined #rom-rb
postmodern has joined #rom-rb
zekefast has joined #rom-rb
knowtheory has joined #rom-rb
snusnu has joined #rom-rb
pdswan has joined #rom-rb
dkubb has joined #rom-rb
namelessjon has joined #rom-rb
dbussink has joined #rom-rb
jdsiegel has joined #rom-rb
xargoon has joined #rom-rb
elskwid has joined #rom-rb
shingara has joined #rom-rb
coxandrew has joined #rom-rb
mongreli1n has joined #rom-rb
kapowaz has joined #rom-rb
Gibheer has joined #rom-rb
indrek has joined #rom-rb
stormwind has joined #rom-rb
xybre has joined #rom-rb
kpwz has joined #rom-rb
<cored>
well, it was not for productino stuff
<cored>
it was just for experimentation
<snusnu>
cored: once dkubb finishes the axiom-memory-adapter, rom dev will be sped up again
<cored>
I see
<snusnu>
cored: because once we have a stable "store" for values, we can flesh out any of the missing apis
<snusnu>
cored: and actually, once we have a proper in memory adapter, i will immediately switch our app to rom
<cored>
interesting
<snusnu>
cored: i don't care if the changes are lost on reboot .. i can always hook a yaml export on shutdown/crash
solnic has joined #rom-rb
<snusnu>
cored: of course that's only during development, i wouldn't want to go live with an in memory db only :)
<cored>
oh sure
<cored>
for development that's it
<dkubb>
I'm fairly close to having axiom-memory-adapter working. it's about 90% of the way there
<solnic>
dkubb: !!!!!
<snusnu>
dkubb: that's awesome news!
<dkubb>
the integration tests all pass, but I need to finish the unit tests and mutationn test it
<solnic>
IF basic stuff is passing I'm more then happy to plug it into rom-relation and use in rom-session already
<solnic>
I just need it for very basic use cases
<solnic>
(initially)
<dkubb>
right now I'm in between longer term contracts, and you'd think I'd have more time, but I've got a bunch of small projects back to back so working in oss time has been hard
<solnic>
dkubb: yeah I hear you
<solnic>
that's "too bad"
<dkubb>
although I have been trying to use devtools on this rails project, which has allowed me to contribute stuff back in that area.. like the rubocop stuff
<solnic>
rite
<dkubb>
although I wish I was able to use ROM with it ;)
<solnic>
don't say ;)
<snusnu>
i will use it, from the day the in memory adapter works, no joke
<snusnu>
:p
<snusnu>
who needs relationships ....
<snusnu>
lol, that sounds strange in many ways ...
<dkubb>
relationships would work fine
<solnic>
yeah man that doesn't sound like a joke
<dkubb>
there'd be no distinguishable difference between a memory adapter and an rdbms adapter
<cored>
I probably will use it, too
<solnic>
we SUPPORT relationships
<solnic>
we don't have DSL to define them
<solnic>
that's IT
<snusnu>
dkubb: we nuked the relationship dsl
<snusnu>
right
<snusnu>
which basically is why i don't care that much about it :)
<solnic>
I think first release of ROM will be pretty sweet
<dkubb>
ahh yeah, I guess the memory adapter does require you to define base relations up-front. with an rdbms you could reflect that from the db
<solnic>
I think my mind was deeply infected with what we have in AR and DM1
<solnic>
so I looked at ROM through features of AR and DM1
<snusnu>
dkubb: i have my schema defined in dm1 models (as i still use stuff like nested_set etc) .. so i just generate the rom schema from the dm1 models
<solnic>
if you know what I mean
<dkubb>
yeah, like mass assignment
<solnic>
I know kinda see things differently
<cored>
also dkubb most of the axiom to axiom-types refactor is broken :-P
<cored>
will work on it, in a couple of hours though
<cored>
I mean keep debugging at least
<dkubb>
cored: hehe, well, the important thing is that it's moving from really broken to less broken
<mbj_>
snusnu, dkubb: FYI I released unparser-0.0.9 allowing to correctly reproduce __FILE__ and __LINE__
<snusnu>
sweet mbj_
<dkubb>
cored: I have a few refactorings to axiom to make in relation to this memory adapter
<cored>
dkubb: yes
<cored>
dkubb: I guess that will impact the axiom-types refactor, right ?
<cored>
I mean the refactor will impact the adapter
<dkubb>
like for example, a base relation will have two parameters.. a name, and another relation. the other relation can be anything. in an in-memory adapter it'll be a materialized relation. in an rdbms it'll simply be a relation with a header
<dkubb>
cored: no I don't think it'll affect it too much. those things should be decoupled
<snusnu>
i'm already looking forward to writing plugins for rom .. i always liked writing plugins .. that's how i got in touch with dm1 dev in the first place
<dkubb>
I'd like to circle back to the rdbms adapter once axiom-memory-adapter is ready
<snusnu>
it'll be easy
<snusnu>
dkubb: sounds like a plan!
<dkubb>
specifically sql generation and writes
<solnic>
dkubb: yeah me too
<snusnu>
prettypleaseyes
<snusnu>
:)
<solnic>
dkubb: I want to "finish" rom-session (as in add missing specs and merge the thing in)
<solnic>
and then move back to sql
<dkubb>
snusnu: you know that vanguard example, I wonder why we even need to use AMo style method names?
<solnic>
oh and I'd vote for pushing 0.0.1 already when basic stuff works with in-memory adapter
<snusnu>
dkubb: please, let's nuke them
<dkubb>
snusnu: we could simply have #present, #length, etc
<dkubb>
solnic: yeah
<snusnu>
yeah
<dkubb>
solnic: I assume we'll probably do a few iterations across the whole stack as we tighten things up
<solnic>
few? :D
<dkubb>
solnic: the important thing is the direction we're moving in feels more or less right.. there'll obviously be tweaking along the way, and holes we missed, but I'm happy with where we are going
<dkubb>
if there weren't problems I would actually be really worried..it'd be we weren't looking hard enough ;)
<dkubb>
there's no way a stack like this can be developed without learning things we never could've know at the start
<snusnu>
yeah, initially i was a bit sad (not really) about more or less nuking dm-mapper .. but really, it feels good now, nothing else
<dkubb>
snusnu: it'd be nice if vanguard could use axiom-types under the hood to declare the types for each attribute. it already has built-in constraint checking stuff
<solnic>
snusnu: we nuked it but a lot of stuff from it will be re-introduced
<snusnu>
solnic: yeah, i'm totally cool with that, it started to become cruft, too much working around the broken design
<solnic>
like graph, path resolution, prefixing etc
<snusnu>
solnic: we have a much better picture now
<solnic>
and obviously THE JERSEY THING
<snusnu>
mwhaha
<solnic>
I really want to call one release the jersey thing ;(
<solnic>
j/k
<snusnu>
i'd be angry if we don't
<snusnu>
:p
<solnic>
oh lol
<solnic>
ok ;)
<snusnu>
but even more so, i'd like to name one release "James Cameron"
<snusnu>
lol
<snusnu>
ROM-1.0 The James Cameron release
<snusnu>
haha
<solnic>
you know what
<solnic>
THAT
<solnic>
would be ever more awesoe
<solnic>
awesome even
<snusnu>
hehe
<solnic>
we raised the bar, welcome in ROM
<snusnu>
i will never ever in my life forget that SP episode, never ever
<solnic>
speaking of which
<mbj_>
dkubb: I plan to come up with a new validation dsl. But in absense of new ideas I just keept the old one
<solnic>
I should watch some episode and hit bed :)
mbj_ is now known as mbj
<snusnu>
solnic: sounds like a plan
<snusnu>
solnic: also, in case you don't know, there are new futuramas
<solnic>
I'm in Oslo and need to get up early tomorrow to do some work and then catch a flight back to Poland
<dkubb>
mbj: yeah, we could work on the dsl together if you want
<solnic>
snusnu: yeah man futurama is still on my list of stuff to watch...
<snusnu>
solnic: just do it :)
<solnic>
right ;)
<dkubb>
mbj: I'm still not totally happy with the actual implementation of axiom-types, but I do like the DSL. even if I change it to be object based rather than class based, I'd probably keep most of it. we could have something similar in a way
<dkubb>
mbj: the interesting thing is that defining a schema is actually a very similar process to defining constraints for validation. in some ways they are two sides of the same coin
<snusnu>
bbiab
snusnu has quit [Quit: Leaving.]
<mbj>
dkubb: yeah
<mbj>
dkubb: I'd love vanguard sharing code with axiom types.
<mbj>
Or axiom-logic (still to be extracted).
<mbj>
I'm up for 18h now, going to sleep cu tormorrow