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

Subject Stack #90

Open
bbatsche opened this issue Oct 18, 2022 · 3 comments
Open

Subject Stack #90

bbatsche opened this issue Oct 18, 2022 · 3 comments

Comments

@bbatsche
Copy link
Owner

bbatsche commented Oct 18, 2022

Problem

When switching verifiers, we may want to use the resolved value as a (temporary) subject. For example, in our docs on switching verifiers we go from verifying the return value of a method to file contents. The “subject” for the file verifier should never be the object or method, it should always be the returned value.

Abstract

Add the concept of an “original” subject versus resolved subject. The withVerifier() method will provide both. There must then be some consistent logic for what the target verifier will consider the subject under test. Some examples:

  • File verifier will always treat resolved value as the subject (aka, filename)
  • method()/__call()/attributeName()/)__get() will use the original subject if there has already been some assertions about the resolved value, otherwise it will resolve the subject and treat that as the SUT. This should allow verifying the result of method/attribute chains.
  • jsonContent() will always use the resolved subject. Using jsonContent() from the File verifier should use the file’s contents
  • arrayContent() is the inverse of method/attributes: it should use the resolved value if that has been triggered (via __get()). Otherwise revert back to the original subject. This should also allow for deeper array inspection

Solution

Add parameter to constructors for “previous verifier”, whenever we use withVerifier() pass along the previous verifier. Using any of the magic methods will target the current subject. If the method doesn’t work or make sense with the subject we will traverse up the stack until we find a subject where the method makes sense.

Add methods for previousSubject() and originalSubject() to allow user to explicitly traverse the stack

@bbatsche bbatsche added this to the 3.2.0 milestone Oct 18, 2022
@bbatsche
Copy link
Owner Author

How do we resolve something like this:

verify($subject)->/* ... */
    ->file_one->will()->endWith('.log')
    ->file()->contain('log content')
    ->file_two->will()->endWith('.json')
    ->file()->contain('some json')
    ->jsonContent()->some_key->is()->identicalTo('some value');

Do we try to do some heuristics on $subject to determine if it's an object/array/JSON? Probably not, too many pitfalls and better to be explicit in writing tests rather than making invisible assumptions on behalf of user.

Treat $subject as an object unless arrayContent() or jsonContent() is used. If we do that, can we use jsonContent() to parse the contents of a file? Maybe a different method? And then can we use arrayContent() inspect the values of that JSON data?

We're really diving deeper into one of the earliest challenges of writing assertions about both a parent subject and it's internal values.

@bbatsche
Copy link
Owner Author

Alternatively, do we create a "return to root" method that resets everything back to the original subject? So all assertions just go further and further down the chain unless reset? Would break existing behavior of attribute & method assertions. Really don't like that; that behavior is predictable and well optimized.

Perhaps a subject stack? And then some way to explicitly pop subjects? Or do we try to traverse up until we find a subject that would be compatible with whatever accessor we're using?

@bbatsche bbatsche added this to Verify Aug 4, 2023
@bbatsche bbatsche moved this to Backlog in Verify Aug 4, 2023
@bbatsche bbatsche changed the title Original & Resolved Subjects Subject Stack Aug 5, 2023
@bbatsche bbatsche modified the milestones: 3.2.0, 4.0.0 Aug 15, 2023
@bbatsche
Copy link
Owner Author

bbatsche commented Aug 17, 2023

Move away from multiple verifiers that extend Base / Value and instead create "subject resolvers". By default resolver is just getting original value, but methods will swap in property/method chain resolver, invoked object, array / JSON content, file content, etc

@github-project-automation github-project-automation bot moved this from Backlog to Done in Verify Aug 17, 2023
@bbatsche bbatsche reopened this Aug 17, 2023
@github-project-automation github-project-automation bot moved this from Done to Ready in Verify Aug 17, 2023
@bbatsche bbatsche moved this from Ready to Backlog in Verify Aug 17, 2023
@bbatsche bbatsche moved this from Backlog to Ready in Verify Aug 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready
Development

No branches or pull requests

1 participant