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

withSomeParams modifier for mockGetRequest #227

Merged
merged 2 commits into from
Aug 3, 2016

Conversation

youroff
Copy link
Contributor

@youroff youroff commented Aug 3, 2016

This PR introduces new functionality to match by some params. Here's the excerpt from documentation additions:

  // Create list of models
  let users = buildList('user', 2, 'with_hats');
  let user1 = users.get(0);

  mock = mockQuery('user').returns({ids: [user1.id]});

  mock.withParams({name:'Bob', age: 10})

  // When using 'withParams' modifier, params hash must match exactly
  store.query('user', {name:'Bob', age: 10}}).then(function(models) {
    // models will be one model and it will be user1
  });

  // The following call will not be caught by the mock
  store.query('user', {name:'Bob', age: 10, hair: 'brown'}})

  // 'withSomeParams' is designed to catch requests by partial match
  // It has precedence over strict params matching once applied
  mock.withSomeParams({name:'Bob'})

  // Now both requests will be intercepted
  store.query('user', {name:'Bob', age: 10}})
  store.query('user', {name:'Bob', age: 10, hair: 'brown'}})

Probably both withParams and withSomeParams calls might need to clear opposite object to be able to switch between behaviors in flight.

kudos to @ryedeer 👍 👍 👍

@danielspaniel danielspaniel merged commit cd5c333 into adopted-ember-addons:master Aug 3, 2016
@danielspaniel
Copy link
Collaborator

Hmm .. interesting .. and useful .. me like

@mdentremont
Copy link
Contributor

This is great! It might be nice to s/withParams/withExactParams just to make it a bit more explicit (and we maybe we could spit a deprecation warning on withParams)?

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Yeah, was thinking about this. Can do it along with 'mutual reset' feature.
So right now withSomeParams has precedence over withParams, and to switch back to exact match, the one needs to call withSomeParams({}) first. So I think it would be good if withSomeParams / withParams took over in one step.

@danielspaniel
Copy link
Collaborator

maybe something like:

 withParams(blah).matchSome()
 withParams(blah).matchExact()

but by default it would be matchExact

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Not sure.. this looks longer. It would make sense if you wanted to test with exact/partial match with the same params object, but it doesn't look like a common use-case.

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Actually, it might be good idea to just use matchExact(blah) / matchSome(blah) to align with match(payload) on mutating mocks.

@danielspaniel
Copy link
Collaborator

I just don't like too many things like withSomeParams, withExactParams , withMyPetPonyParams .. etc ..
right now it is ok .. but I prefer things like

withParams(blah);  // which means exact match ( by default ) 
or 
withParams().matchSome() // if that is what you mean

this way you can do:

mock.matchSome()
or mock.matchExtact()
anytime later and switch it.

and it seems easier to learn this new syntax since you dont have to rewrite your old code

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Well, to keep less methods, this might be an argument for withParams(blah, exact) where exact is boolean.
What I don't like in just matchSome() / matchExact() is:

  1. It will be 3 methods instead of just 2.
  2. Most common use-case will involve calling 2 (or 1 if used default exact match) methods.
  3. I really don't see why would you want to switch from exact match to some match (and back) with the same set of params. Usually you want to update params as well.

@danielspaniel
Copy link
Collaborator

I see what you mean that about the match(payload)
that is another issue where your matching attributes in a payload for mockUpdate/mockCreate
and for mockQuery /queryRecord .. you matching parameters

but maybe since there is no payload in mockGet's then it is obvious what you are matching.
but there could be parameters in mockUpdate AND payload attributes ( which I suppose are params too ) .. but they are found in different location .. I am now confusing myself... ugh.

@danielspaniel
Copy link
Collaborator

danielspaniel commented Aug 4, 2016

I like that one

withParams({}, exact) // exact defaults to true

Only reason I throw out other examples is I not sure about use case. I thought you wanted to switch and change the mock from exact to some match .. so I was confused there .. usually you want one or the other I thought

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Are there real parameters with mockUpdate / mockCreate? I mean can they technically exist with standard ember-data adaptor?

Yes, the initial idea was to just setup mock to match by exact or some params and that's it, but later I really liked the idea that you can use the same mock with new settings as your test goes on. And it makes perfect sense, especially if that mock-stack is something that could affect performance (which we're still investigating).

Also I think that it might be good idea to set default exact to false if we stick to withParams({}, exact) notation. Cause it pairs with match(payload) and I guess that is what you would want to do in most cases. For example, in our app we have couple of critical routes that have about 10 queryParams each and they're sent undefined on server every time. So when we test, we don't care about other params (that are default or undefined), but we do care about those that changed (and how they changed).

@danielspaniel
Copy link
Collaborator

I hope so ( about params with update ) with ember-data .. I will let you know .. because I trying to pull that out of my hat today.

Interesting about sending queryParams that are undefined ( does not ember usually not send param if it is undefined .. ). You might have different use case for that.

maybe so about withParams({}, exact) // where you like exact to be false by default ..

but right now it is true by default .. so as long as it does not break all existing tests .. I don't mind too much.

Also, the match(attrs) in mockUpdate / mockCreate is exact match .. there is not the idea of partial match .. is there? I am mistaken .. where you get the idea that was partial matching going on there ?

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Ummm... maybe I was wrong, but it's just naturally assumed. Let's say, you have a form, but model also has some attributes that not in the form but have defaults (for example). So you'd expect that those attributes get to payload as well, but you're testing just one field in the form.

  1. You fill in that field
  2. mockCreate('model').match({field: value})
  3. Trigger submit
    So if match was strict here, it wouldn't work for the case. You would have to provide complete attributes hash there. So I was sure it wasn't exact..

@danielspaniel
Copy link
Collaborator

It is exact because you only provide the attrs that you want to exactly match.

Oh .. I see what you mean now. So yes, your right, it is partial match. Because you match on what you want to match, though there could be more attrs in the payload .. duuuuuuuhhhhh
meaning it is matching exactly the few that you provide === matchSome of these

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Yeah, right... So I think that match-some-approach is more general for testing. That's why I propose to align modifiers of get-mocks and post-mocks. This could be just more straight-forward for beginners.

@danielspaniel
Copy link
Collaborator

danielspaniel commented Aug 4, 2016

right .. I got you now.

Though one more note.

There is still a difference between:
match({attrs}) // match these attrs to the many model attributes ( and all these attrs have to match )
and withParams({params}, some=true) // match these params to the many url params ( and just don't be too picky, as long as some match I am ok )

so that is what was confusing me
In fact ..I can say .. I am confused still ( as to how to make the two kinda similar ) .. cause they sort of are and are not.

As long as you can lay out a nice plan though, that makes sense I am up for it.

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Hmm... Right now it's very similar. All params supplied to withSomeParams must match, but request may have other params. So it's exactly like attributes in match. Payload may have other attributes, but we're looking to match provided key-value pairs.

I have another idea... what if we rename public methods to matchAttributes and matchParams respectively. Also both of them may have exact argument. It's pretty rare case for exact-matching payload, but why not? This will allow to test serializers, for example. What do you think?

@ryedeer
Copy link
Contributor

ryedeer commented Aug 4, 2016

In my opinion, using matchAttributes (or maybe matchAttrs for shortness) and matchParams with an additional argument seems to be a good idea. These method names clearly show what data should be matched, and the optional second argument will make additional modifier methods unnecessary. After all, I can hardly imagine a case when one would need to switch between partial and full matching with the same set of parameters.

@danielspaniel
Copy link
Collaborator

Boy this brings up the idea from a long time ago ( see open issues about with vs withParams ) where someone suggested doing with({params: {}} with({attributes: attrs})

so I like the suggestion, and am just slightly suggesting something else
match({params: {}} match({attributes: attrs}) , which could also have
match({params: {}, exact: true} match({attributes: attrs, exact: true})

though I am just saying this to stir up ideas because I like matchAttributes or matchParams too.
Trying to think of how to make things easy to remember and streamline the api

@youroff
Copy link
Contributor Author

youroff commented Aug 4, 2016

Actually, this is pretty good idea. Besides clarity, generalizing match might make code simpler by providing just one implementation in base class. Give me couple of days to play with it and I'll be back with PR or something...

@danielspaniel
Copy link
Collaborator

ok . sure thing .. I like to sit and ponder on things too just to let the particles of ideas settle down a bit

@ryedeer ryedeer deleted the matchparams branch August 5, 2016 13:25
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.

4 participants