DangerDSL mocking [IDEA]
Nikoloutsos opened this issue · comments
Hi, first of all thanks for this danger-js wrapper it is so cool 🎉.
I do have an idea that I'd like to hear your opinion about:
As I was developing a danger plugin I wanted to make it fully-testable. For doing that I had to mock DangerDSL which I spent a lot of time and the only way I found was initialising through JSON files. So if i have 200 tests I should have 200 JSONs (1000 lines each) . So i came up with this idea 👇
Proposal
We can make use of Runtime library https://github.com/wickwirew/Runtime that will allow us to change let properties of dangerDSL😆.
At this point in my repo I have implemented this and working well.
/// Gives the ability to a struct/class to modify properties even let through runtime mirroring
protocol RuntimeModifiable {
/// Use this method to change a property on your RuntimeModifiable
/// ```swift
/// // In case you want to pass nil!
/// try mutablePR.rchange(property: "assignee", with: Optional<GitHub.User>.none)
/// ```
mutating func rchange(property: String, with value: Any) throws
}
extension RuntimeModifiable {
mutating func rchange(property: String, with value: Any) throws {
let info = try typeInfo(of: type(of: self))
let property = try info.property(named: property)
try property.set(value: value, on: &self)
}
}
// MARK: DangerDSL struct
extension GitHub.PullRequest: RuntimeModifiable {}
extension GitHub: RuntimeModifiable {}
extension DangerDSL: RuntimeModifiable {}
extension GitHub.User: RuntimeModifiable {}
...
and test now looks like this (in this test we make dangerDSL to have an assignee):
func testAssigneeExist() throws {
// Given
var fixture = githubWithFilesDSL()
var mutableGithub = fixture.github!
var mutablePR = fixture.github.pullRequest
try mutablePR.rchange(property: "assignees", with: [GitHub.User(id: 0, login: "", userType: .user)])
try mutableGithub.rchange(property: "pullRequest", with: mutablePR)
try fixture.rchange(property: "github", with: mutableGithub)
let sut = AssigneeExistsStep(danger: fixture)
// When
sut.execute()
// Then
XCTAssertTrue(sut.status.isSuccess)
}
By doing this we can stub what we want in dangerDSL in contrast of bombarding the whole package with JSON files.
Maybe this idea can be a seperate package (danger plugin) that can be used for easier DangerDSL mocking.
What do you think?
Hey @Nikoloutsos, thank you for putting this proposal together :)
We already have something similar to allow you to modify the DangerDSL:
Look for example this test file, where the created files are modified from the DSL in the test https://github.com/f-meloni/danger-swift-coverage/blob/master/Tests/DangerSwiftCoverageTests/CoverageTests.swift.
This only allows you to modify the created/modified/deleted files, and allows you to create a fileMap to stub also the content of the file when you go to read it with danger.utils, so is a lot simpler than what you suggest, and would be cool to have something more complex :).
We have https://github.com/danger/swift/tree/master/Sources/DangerFixtures that is already a testing lib, and I would be happy to see something like the code you suggest, or something like a builder there, that can then help the creators of Danger plugins :)