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

Add shared instance to the Printer #483

Merged
merged 7 commits into from
Aug 23, 2019
Merged

Add shared instance to the Printer #483

merged 7 commits into from
Aug 23, 2019

Conversation

pepicrft
Copy link
Contributor

@pepicrft pepicrft commented Aug 19, 2019

Resolves #351

Short description 📝

Our current approach of using utilities like the FileHandler, System, or Printer, is cumbersome and requires a lot of boilerplate code and passing instances around.

Solution 📦

I added a shared static instance to the Printer.

import TuistCore

Printer.shared.print("whatever")

Any class in the project can access the shared instance of Printer easily.
That removes the need of having to inject the dependencies through the constructor and define instance variables to hold references to them.

When it comes to testing, I added a convenience static method that can be used from a test case to replace all utilities with their mocks. Here's an example of how the tests look:

import XCTestCase

class MyTest: XCTestCase {

  override func setUp() {
    mockEnvironment()
  }

}

Moreover, I added an extension to XCTestCase with some XCT assertion functions that can be used with context:

XCTAssertPrinterOutputContains("Project generated successfully")
XCTAssertPrinterErrorContains("The generation of the project failed")

@pepicrft pepicrft requested a review from a team August 19, 2019 18:54
@pepicrft pepicrft self-assigned this Aug 19, 2019
Copy link
Collaborator

@ollieatkinson ollieatkinson left a comment

Choose a reason for hiding this comment

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

Thanks for doing this work.

It might be good to consider what other refactorings we might want to do in follow up pull requests for similar objects.

e.g.

  1. FileHander
  2. System
  3. ResourceLocator
  4. ...

/// Mocks the shared context instance and returns the mock.
///
/// - Returns: Mocked context.
static func mockSharedContext() -> MockContext {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be good to set this up automatically using XCTestObservation (see https://developer.apple.com/documentation/xctest/xctestobservation)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea 😛

var deprecator: Deprecating { get }
}

public final class Context: Contexting {
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 just exposing public var printer: Printing and public var deprecator: Deprecating as top level variables. I was trying to understand what the benefit of grouping these in a single object is.

Context.shared.printer.print(deprecation: message)
printer.print(deprecation: message)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point. I can remove one level of indirection there. Thanks for the suggestion @ollieatkinson

@pepicrft pepicrft mentioned this pull request Aug 22, 2019
@pepicrft
Copy link
Contributor Author

@ollieatkinson I got rid of the Context class. The printer can now be accessed with Printer.shared. I looked into using XCTestObservation but it's not feasible because it requires adding an entry to the Info.plist, something that the Swift Package Manager doesn't allow.

What I did instead was extending the XCTestCase and add two methods, mockEnvironment() and mockPrinter(). They can be called explicitly from the tests when developers want to mock the environment.

@pepicrft
Copy link
Contributor Author

@kwridan / @marciniwanicki could you have a look at this PR?

@tuistbot
Copy link
Contributor

tuistbot commented Aug 22, 2019

2 Warnings
⚠️ Please include a CHANGELOG entry.
You can find it at CHANGELOG.md.
⚠️ Have you introduced any user-facing changes? If so, please take some time to update the documentation. Keeping the documentation up to date makes it easier for users to learn how to use Tuist.

SwiftLint found issues

Warnings

File Line Reason
MockPrinter.swift 56 SwiftLint rule 'force_try' did not trigger a violation in the disabled region. Please remove the disable command. (superfluous_disable_command)
MockPrinter.swift 61 SwiftLint rule 'force_try' did not trigger a violation in the disabled region. Please remove the disable command. (superfluous_disable_command)
ProjectGenerator.swift 77 Function body should span 40 lines or less excluding comments and whitespace: currently spans 41 lines (function_body_length)
UpHomebrew.swift 39 Use allSatisfy instead (reduce_boolean)

Generated by 🚫 Danger

@codecov
Copy link

codecov bot commented Aug 22, 2019

Codecov Report

Merging #483 into master will increase coverage by 0.22%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #483      +/-   ##
==========================================
+ Coverage    92.4%   92.63%   +0.22%     
==========================================
  Files         348      347       -1     
  Lines       17809    17752      -57     
==========================================
- Hits        16457    16444      -13     
+ Misses       1352     1308      -44
Impacted Files Coverage Δ
...ratorTests/Generator/WorkspaceGeneratorTests.swift 92.37% <ø> (-0.07%) ⬇️
Sources/TuistKit/Models/Up/UpCustom.swift 21.62% <0%> (ø) ⬆️
Sources/TuistKit/Commands/BuildCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistEnvKit/Commands/VersionCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistGenerator/Dot/DotGraphGenerator.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Models/Up/Up.swift 73.68% <0%> (ø) ⬆️
Sources/TuistKit/Commands/VersionCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Commands/EmbedCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Commands/FocusCommand.swift 38.88% <0%> (+2.99%) ⬆️
...stEnvKitTests/Commands/UninstallCommandTests.swift 100% <100%> (ø) ⬆️
... and 58 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 71a3ec0...83954a5. Read the comment docs.

@codecov
Copy link

codecov bot commented Aug 22, 2019

Codecov Report

Merging #483 into master will increase coverage by 0.22%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #483      +/-   ##
==========================================
+ Coverage    92.4%   92.63%   +0.22%     
==========================================
  Files         348      347       -1     
  Lines       17809    17752      -57     
==========================================
- Hits        16457    16444      -13     
+ Misses       1352     1308      -44
Impacted Files Coverage Δ
...ratorTests/Generator/WorkspaceGeneratorTests.swift 92.37% <ø> (-0.07%) ⬇️
Sources/TuistKit/Models/Up/UpCustom.swift 21.62% <0%> (ø) ⬆️
Sources/TuistKit/Commands/BuildCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistEnvKit/Commands/VersionCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistGenerator/Dot/DotGraphGenerator.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Models/Up/Up.swift 73.68% <0%> (ø) ⬆️
Sources/TuistKit/Commands/VersionCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Commands/EmbedCommand.swift 0% <0%> (ø) ⬆️
Sources/TuistKit/Commands/FocusCommand.swift 38.88% <0%> (+2.99%) ⬆️
...stEnvKitTests/Commands/UninstallCommandTests.swift 100% <100%> (ø) ⬆️
... and 58 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 71a3ec0...519c742. Read the comment docs.

@pepicrft pepicrft changed the title Add context shared utility and move printer to it Add shared instance for the Printer Aug 23, 2019
@pepicrft pepicrft changed the title Add shared instance for the Printer Add shared instance to the Printer Aug 23, 2019
@pepicrft pepicrft requested a review from a team August 23, 2019 10:33
Copy link
Collaborator

@ollieatkinson ollieatkinson left a comment

Choose a reason for hiding this comment

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

Lots of similar changes, and running locally still shows the correct output! 👍

@kwridan
Copy link
Collaborator

kwridan commented Aug 23, 2019

Thanks for making the sweeping changes @pepibumur

Personally, I quite liked the previous approach of having explicit dependencies. I agree that passing them around everywhere was quite cumbersome - for that @marciniwanicki's suggestions would help address that not only for those lower level components but for some of the other bigger ones too.

I don't have a strong view on this, so let's give the changes here a go and revisit it when needed 🙂

The good thing here is we can still control this for testing and when using Tuist as a library 👍

@pepicrft pepicrft merged commit 27bb970 into master Aug 23, 2019
@pepicrft pepicrft deleted the context branch August 23, 2019 12:59
@pepicrft pepicrft mentioned this pull request Aug 23, 2019
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.

Dependency injection
4 participants