Implement custom rop rspec matcher
What does this MR do and why?
Issue: Implement custom Rspec matcher for ROP main cla... (#455126 - closed)
This change aims to improve testing experience by reducing the amount of code needed to write tests for ROP main classes. It does this by implementing a custom rspec matcher for ROP chain classes. This change also incorporates ideas from Allow arity -1 in ROP to improve testability (!151574 - closed) which allows us to directly mock functions and Use meta programming to make testing remote dev... (!152657 - closed) to determine what methods need to be mocked (railway classes always have single public method)
How the matcher works
The matcher works by:
- listing railway classes that are expected to be called and their expected result passing method (and_then or map)
- stating the initial value passed
- stating the expected return
like so:
expect_railway_to_have_been_called([settings_initializer_class, :map],
[current_settings_reader_class, :and_then],
[extensions_gallery_metadata_generator_class, :map],
[env_var_reader_class, :and_then]).with(input_value).and_return(
Result.err(RemoteDevelopment::Messages::SettingsEnvironmentVariableReadFailed.new(err_message_context))
)
Important notes:
- We need to determine the passer method as when propagating the input through the chain we need to know if the mocked method should return a plain value or a
Resulttype - the matcher uses the initial input, clones it and makes that clone be the expected input by the next rop class in the chain
- the last class in the chain is setup to return the value passed to
and_return
Compromises and issues
To keep the code needed for the matcher minimum, I avoided passing information about what class might return an error in the tuple e.g: [settings_initializer_class, :map, error]. This presented an issue:
When the test is expected to return an Result.err but ends with a map, the stubbing of the last chain class method wont work as map cannot return an error. To remedy this, you can limit the classes whose methods you want to mock in the rspec matcher to the first class in the chain that can return an error. I think this is acceptable because even if you are to mock methods down the chain after an earlier error occurs, you can not verify if the methods were called as errors are simply forwarded by the result class.
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Screenshots or screen recordings
Screenshots are required for UI changes, and strongly recommended for all other merge requests.
| Before | After |
|---|---|
How to set up and validate locally
Numbered steps to set up and validate the change are strongly suggested.
Merge request reports
Activity
assigned to @Saahmed
- A deleted user
added backend label
10 Warnings ⚠ This merge request is definitely too big (2190 lines changed), please split it into multiple merge requests. ⚠ 2e3bc04e: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ b41d1d0c: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ 69618dad: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ 83af9fdd: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ 733dee5f: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ a2c841df: The commit subject must contain at least 3 words. For more information, take a look at our Commit message guidelines. ⚠ 614f4fc5: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ 61311fad: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ⚠ This merge request does not refer to an existing milestone. 1 Message 📖 CHANGELOG missing: If this merge request needs a changelog entry, add the
Changelogtrailer to the commit message you want to add to the changelog.If this merge request doesn't need a CHANGELOG entry, feel free to ignore this message.
Reviewer roulette
Category Reviewer Maintainer backend @jwanjohi(UTC+1)
@grzesiek(UTC+2)
Please check reviewer's status!
Please refer to documentation page for guidance on how you can benefit from the Reviewer Roulette, or use the GitLab Review Workload Dashboard to find other available reviewers.
If needed, you can retry the
🔁 danger-reviewjob that generated this comment.Generated by
🚫 DangerEdited by Ghost Usermentioned in issue #455126 (closed)
added pipelinetier-1 label
- Resolved by 🤖 GitLab Bot 🤖
Proper labels assigned to this merge request. Please ignore me.
👋 @Saahmed - please see the following guidance and update this merge request.1 Error ❌ Please add typebug typefeature, or typemaintenance label to this merge request. Edited by 🤖 GitLab Bot 🤖
added devopscreate groupremote development labels
added sectiondev label
added Category:Workspaces typefeature workflowin dev + 1 deleted label
requested review from @pslaughter and @cwoolley-gitlab
- Resolved by Chad Woolley
Thanks for working on this @Saahmed! I've been OOO until today and haven't had a change to look at this yet. I should be able to get to this within the next 12-24 hours
👀