Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return a map from match? #110

Merged
merged 12 commits into from
Apr 8, 2020
Merged

return a map from match? #110

merged 12 commits into from
Apr 8, 2020

Conversation

dchelimsky
Copy link
Contributor

No description provided.

@dchelimsky
Copy link
Contributor Author

Addressing #108

@dchelimsky
Copy link
Contributor Author

@sovelten I still need to add the report->actual fn before I submit this as "not a draft". Feel free to review now or wait.

(state/ensure-step ~actual))]
(state/ensure-step ~actual))
report# (state/return (matcher-combinators/match ~expected actual#))]
(state/modify update :match/results (fnil conj []) (assoc report# :match/desc flow-desc#))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to modify the state or the meta?
I was thinking that state-flow specific stuff could be on the meta, while user specific stuff on the state, so as not to conflict with whatever the user wants to have as a state.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On another note, this statement is a bit too big, maybe it deserves its own function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: this doesn't even need to be here yet. I added it (yes, to the wrong place - will put on meta) with reporting in mind, so the runner can analyze the match results and print failure information when appropriate. I may end up removing it from here for now and restore it when we get to that decoupling.

(m/fmap (comp :value last)
(probe/probe state
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want to fetch the result of all tries instead of only value of the last try here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sovelten I removed the bit about storing these results in the state (or meta) from this PR, so I don't think that matters (for this PR). Agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my mind. The return of match? now looks like this when (> times-to-try 1)

{:probe/sleep-time   110
 :probe/times-to-try 3
 :probe/results      [{:check-result false :value 0}
                      {:check-result true  :value 2}]
 :match/expected     2
 :match/actual       2
 :match/result       :match}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI - adding this to the meta of the state will allow us to move the cljtest reporting to the cljtest namespace

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 🎉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I'm not sure about is whether we should document the keys in that map or just say "a map with information about the success or failure of the match, the details of which are used internally by state-flow and subject to change". I want to discourage anybody, for now, from treating that map's shape as an API the you can program against. I might see this differently once we have the decoupling design worked out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I would keep this model as internal for now (or ever I don't know)

@dchelimsky dchelimsky marked this pull request as ready for review April 6, 2020 23:03
@dchelimsky dchelimsky requested a review from a team April 6, 2020 23:03
@dchelimsky
Copy link
Contributor Author

@sovelten I added the report->actual fn we discussed in #108. I'm not in love with the name, but I don't know that I have a better choice. WDYT about extract-actual, or something cute like <<actual?

[actual (<<actual (match? 3 (+ 1 2)))]

match? was deciding whether to use probe to try 1 or more times, and
then probe was making the same decision. Now it only happens in probe,
letting us remove duplicate conditional logic from match?
[report-or-match]
`(m/do-let
[report# (state/ensure-step ~report-or-match)]
(state/return (:match/actual report#))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of this approach. I'm not a fan of the so called "true union types" like things can be one thing or the other.
I find it quite confusing, not well-typed 😬 .

What are the problems you see with just a function? Is it to avoid exposure to fmap? fmap is beautiful ✨ . But also avoidable with just a function by using :let.

Also I don't understand the need for a macro here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match? supports a step or a value for actual. I was just going along w/ that idea, but I appreciate your perspective here. Changing it to a function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe it is just a longing for orderliness but that is also one reason why I was defending a different match? for probing.

But that may be a different case, because you cannot write match-probe? in terms of match? but you can compose report->actual with fmap.

Just rambling, don't mind me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK @sovelten - it's a fn now and there's even fmap in the test.

Also move match? tests to a matcher-combinators-test namespace and
clean some things up.
@dchelimsky dchelimsky requested a review from a team April 7, 2020 19:25
[matcher-combinators.matchers :as matchers]
[state-flow.assertions.matcher-combinators :as assertions.matcher-combinators]
[state-flow.test-helpers :as test-helpers :refer [this-line-number]]
[state-flow.assertions.matcher-combinators :as mc]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid acronyms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree 99.9999% of the time. assertions.matcher-combinators/xxx all over the place was making my eyes bleed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, matcher-combinators/xxx would be confusing, since it's not coming from the matcher-combinators library. I guess assertions could work, but that's also confusing :) So I went with a plua (you know, a poor, lonely, unwanted acronym).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about matcher?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather just go back to assertions.matcher-combinators, which won't be confused with things in other parts of the test suite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could just refer match? and report->actual, but then we'd end up with:

(testing "with explicit matcher for expected"
  (let [[ret state] (state/run (match? (matchers/equals 3) 3) {})]
    (is (match? {:match/result :match} ret))))

The two match?s are different. They both work because one is a function and the other is a symbol used to dispatch a multimethod, but they are confusing together!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going with the acronym for this PR. We can always revisit this later.

(state/modify (fn [state]
(future (do (Thread/sleep delay-ms)
(swap! (:value state) + 2)))
(apply f state args)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That only works for atoms though. Applying a pure function would be kinda pointless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make all of state an atom? Then we could have (apply swap! state f args)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we expect state to be a map. If the whole state is an atom there is no point of passing it around, the atom is always the same. But this is test code, I'm not really concerned. Just wondering why you took that route.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find that every time I look at these tests I have to go look at the definition of delayed-add-two, so I wanted to refactor it so I can see what's happening in the test while still avoiding some of the duplication.

Copy link
Collaborator

@sovelten sovelten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 💯

I would just make sure to bump a major version to send a clear warning that this is a breaking change.
Also point out how to adapt old code.

Nice work :)

CHANGELOG.md Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated
;; if you were doing this before
[actual (match? <expected> <step-that-produces-actual>)]
;; you can do this, now
[actual (fmap report->actual (match? <expected> <step-that-produces-actual>)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[actual (clojure.cats.core/fmap report->actual (match? <expected> <step-that-produces-actual>))]

^-- missing a parenthesis at the end as well 😬

also add this other option?

[report (match? <expected> <step-that-produces-actual>)
 :let [actual (report->actual report)]]

Copy link
Contributor

@fernando-nubank fernando-nubank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants