-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deploying to gh-pages from @ 07d5617 🚀
- Loading branch information
0 parents
commit 2a467e8
Showing
1,876 changed files
with
5,583 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
9 changes: 9 additions & 0 deletions
9
0.4.0/css/documentation-topic~topic~tutorials-overview.82acfe22.css
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"primaryContentSections":[{"kind":"content","content":[{"anchor":"Overview","level":2,"type":"heading","text":"Overview"},{"type":"paragraph","inlineContent":[{"type":"text","text":"XCTest Dynamic Overlay provides APIs for invoking XCTest’s "},{"type":"codeVoice","code":"XCTFail"},{"type":"text","text":" directly in your application and library code."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/xctestdynamicoverlay"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Define XCTest assertion helpers directly in your application and library code."}],"kind":"symbol","metadata":{"roleHeading":"Framework","externalID":"XCTestDynamicOverlay","title":"XCTestDynamicOverlay","symbolKind":"module","role":"collection","modules":[{"name":"XCTestDynamicOverlay"}]},"hierarchy":{"paths":[[]]},"topicSections":[{"title":"Essentials","identifiers":["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/GettingStarted"]},{"title":"Overlays","identifiers":["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:)","doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:file:line:)"]},{"title":"Unimplemented Dependencies","identifiers":["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTUnimplemented(_:placeholder:)-1ho66","doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTUnimplemented(_:)-3obl5"]}],"references":{"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay":{"role":"collection","title":"XCTestDynamicOverlay","abstract":[{"type":"text","text":"Define XCTest assertion helpers directly in your application and library code."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTUnimplemented(_:placeholder:)-1ho66":{"role":"symbol","title":"XCTUnimplemented(_:placeholder:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTUnimplemented"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"A"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"Result"},{"kind":"text","text":">(() -> "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":", "},{"kind":"externalParam","text":"placeholder"},{"kind":"text","text":": () -> "},{"kind":"typeIdentifier","text":"Result"},{"kind":"text","text":") -> ("},{"kind":"typeIdentifier","text":"A"},{"kind":"text","text":") "},{"kind":"keyword","text":"async"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Result"}],"abstract":[{"type":"text","text":"Returns a closure that generates a failure when invoked."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTUnimplemented(_:placeholder:)-1ho66","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctunimplemented(_:placeholder:)-1ho66"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTUnimplemented(_:)-3obl5":{"role":"symbol","title":"XCTUnimplemented(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTUnimplemented"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"A"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"Result"},{"kind":"text","text":">(() -> "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":") -> ("},{"kind":"typeIdentifier","text":"A"},{"kind":"text","text":") "},{"kind":"keyword","text":"async"},{"kind":"text","text":" "},{"kind":"keyword","text":"throws"},{"kind":"text","text":" -> "},{"kind":"typeIdentifier","text":"Result"}],"abstract":[{"type":"text","text":"Returns a closure that generates a failure when invoked."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTUnimplemented(_:)-3obl5","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctunimplemented(_:)-3obl5"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTFail(_:)":{"role":"symbol","title":"XCTFail(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":")"}],"abstract":[{"type":"text","text":"This function generates a failure immediately and unconditionally."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:)","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctfail(_:)"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTFail(_:file:line:)":{"role":"symbol","title":"XCTFail(_:file:line:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":", "},{"kind":"externalParam","text":"file"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StaticString","preciseIdentifier":"s:s12StaticStringV"},{"kind":"text","text":", "},{"kind":"externalParam","text":"line"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"UInt","preciseIdentifier":"s:Su"},{"kind":"text","text":")"}],"abstract":[{"type":"text","text":"This function generates a failure immediately and unconditionally."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:file:line:)","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctfail(_:file:line:)"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/GettingStarted":{"role":"article","title":"Getting Started","abstract":[],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/GettingStarted","kind":"article","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/gettingstarted"}}} |
1 change: 1 addition & 0 deletions
1
0.4.0/data/documentation/xctestdynamicoverlay/gettingstarted.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"primaryContentSections":[{"kind":"content","content":[{"anchor":"Overview","level":2,"type":"heading","text":"Overview"},{"type":"paragraph","inlineContent":[{"type":"text","text":"A real world example of using this is in our library, the "},{"type":"reference","isActive":true,"identifier":"https:\/\/github.com\/pointfreeco\/swift-composable-architecture"},{"type":"text","text":". That library vends a "},{"type":"codeVoice","code":"TestStore"},{"type":"text","text":" type whose purpose is to make it easy to write tests for your application’s logic. The "},{"type":"codeVoice","code":"TestStore"},{"type":"text","text":" uses "},{"type":"codeVoice","code":"XCTFail"},{"type":"text","text":" internally, and so that forces us to move the code to a dedicated test support module. However, due to how SPM works you cannot currently have that module in the same package as the main module, and so we would be forced to extract it to a separate "},{"type":"emphasis","inlineContent":[{"type":"text","text":"repo"}]},{"type":"text","text":". By loading "},{"type":"codeVoice","code":"XCTFail"},{"type":"text","text":" dynamically we can keep the code where it belongs."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"As another example, let’s say you have an analytics dependency that is used all over your application:"}]},{"type":"codeListing","syntax":"swift","code":["struct AnalyticsClient {"," var track: (Event) -> Void",""," struct Event: Equatable {"," var name: String"," var properties: [String: String]"," }","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"If you are disciplined about injecting dependencies, you probably have a lot of objects that take an analytics client as an argument (or maybe some other fancy form of DI):"}]},{"type":"codeListing","syntax":"swift","code":["class LoginViewModel: ObservableObject {"," ...",""," init(analytics: AnalyticsClient) {"," ..."," }",""," ...","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"When testing this view model you will need to provide an analytics client. Typically this means you will construct some kind of “test” analytics client that buffers events into an array, rather than sending live events to a server, so that you can assert on what events were tracked during a test:"}]},{"type":"codeListing","syntax":"swift","code":["func testLogin() {"," var events: [AnalyticsClient.Event] = []"," let viewModel = LoginViewModel("," analytics: .test { events.append($0) }"," )",""," ...",""," XCTAssertEqual(events, [.init(name: \"Login Success\")])","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"This works really well, and it’s a great way to get test coverage on something that is notoriously difficult to test."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"However, some tests may not use analytics at all. It would make the test suite stronger if the tests that don’t use the client could prove that it’s never used. This would mean when new events are tracked you could be instantly notified of which test cases need to be updated."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"One way to do this is to create an instance of the "},{"type":"codeVoice","code":"AnalyticsClient"},{"type":"text","text":" type that simply performs an "},{"type":"codeVoice","code":"XCTFail"},{"type":"text","text":" inside the "},{"type":"codeVoice","code":"track"},{"type":"text","text":" endpoint:"}]},{"type":"codeListing","syntax":"swift","code":["import XCTest","","extension AnalyticsClient {"," static let unimplemented = Self("," track: { _ in XCTFail(\"\\(Self.self).track is unimplemented.\") }"," )","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"With this you can write a test that proves analytics are never tracked, and even better you don’t have to worry about buffering events into an array anymore:"}]},{"type":"codeListing","syntax":"swift","code":["func testValidation() {"," let viewModel = LoginViewModel("," analytics: .unimplemented"," )",""," ...","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"However, you cannot ship this code with the target that defines "},{"type":"codeVoice","code":"AnalyticsClient"},{"type":"text","text":". You either need to extract it out to a test support module (which means "},{"type":"codeVoice","code":"AnalyticsClient"},{"type":"text","text":" must also be extracted), or the code must be confined to a test target and thus not shareable."}]},{"type":"paragraph","inlineContent":[{"type":"text","text":"However, with XCTest Dynamic Overlay we can have our cake and eat it too 😋. We can define both the client type and the unimplemented instance right next to each in application code without needing to extract out needless modules or targets:"}]},{"type":"codeListing","syntax":"swift","code":["struct AnalyticsClient {"," var track: (Event) -> Void",""," struct Event: Equatable {"," var name: String"," var properties: [String: String]"," }","}","","import XCTestDynamicOverlay","","extension AnalyticsClient {"," static let unimplemented = Self("," track: { _ in XCTFail(\"\\(Self.self).track is unimplemented.\") }"," )","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"XCTest Dynamic Overlay also comes with a helper that simplifies this exact pattern: "},{"type":"codeVoice","code":"XCTUnimplemented"},{"type":"text","text":". It creates failing closures for you:"}]},{"type":"codeListing","syntax":"swift","code":["extension AnalyticsClient {"," static let unimplemented = Self("," track: XCTUnimplemented(\"\\(Self.self).track\")"," )","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"And it can simplify the work of more complex dependency endpoints, which can throw or need to return a value:"}]},{"type":"codeListing","syntax":"swift","code":["struct AppDependencies {"," var date: () -> Date = Date.init,"," var fetchUser: (User.ID) async throws -> User,"," var uuid: () -> UUID = UUID.init","}","","extension AppDependencies {"," static let unimplemented = Self("," date: XCTUnimplemented(\"\\(Self.self).date\", placeholder: Date()),"," fetchUser: XCTUnimplemented(\"\\(Self.self).fetchUser\"),"," date: XCTUnimplemented(\"\\(Self.self).uuid\", placeholder: UUID())"," )","}"]},{"type":"paragraph","inlineContent":[{"type":"text","text":"The above "},{"type":"codeVoice","code":"placeholder"},{"type":"text","text":" parameters can be left off, but will fatal error when the endpoint is called."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/xctestdynamicoverlay\/gettingstarted"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/GettingStarted","interfaceLanguage":"swift"},"kind":"article","metadata":{"roleHeading":"Article","title":"Getting Started","role":"article","modules":[{"name":"XCTestDynamicOverlay"}]},"hierarchy":{"paths":[["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay"]]},"references":{"https://github.com/pointfreeco/swift-composable-architecture":{"title":"Composable Architecture","titleInlineContent":[{"type":"text","text":"Composable Architecture"}],"type":"link","identifier":"https:\/\/github.com\/pointfreeco\/swift-composable-architecture","url":"https:\/\/github.com\/pointfreeco\/swift-composable-architecture"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay":{"role":"collection","title":"XCTestDynamicOverlay","abstract":[{"type":"text","text":"Define XCTest assertion helpers directly in your application and library code."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay"}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"message"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":" = \"\")"}],"languages":["swift"],"platforms":["macOS"]}]},{"kind":"parameters","parameters":[{"name":"message","content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"An optional description of the assertion, for inclusion in test"},{"type":"text","text":" "},{"type":"text","text":"results."}]}]}]},{"kind":"content","content":[{"anchor":"discussion","level":2,"type":"heading","text":"Discussion"},{"type":"paragraph","inlineContent":[{"type":"text","text":"Dynamically creates and records an "},{"type":"codeVoice","code":"XCTIssue"},{"type":"text","text":" under the hood that captures the source code"},{"type":"text","text":" "},{"type":"text","text":"context of the caller. Useful for defining assertion helpers that fail in indirect code"},{"type":"text","text":" "},{"type":"text","text":"paths, where the "},{"type":"codeVoice","code":"file"},{"type":"text","text":" and "},{"type":"codeVoice","code":"line"},{"type":"text","text":" of the failure have not been realized."}]}]}],"schemaVersion":{"major":0,"minor":3,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/xctestdynamicoverlay\/xctfail(_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"This function generates a failure immediately and unconditionally."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":")"}],"title":"XCTFail(_:)","roleHeading":"Function","role":"symbol","symbolKind":"func","externalID":"s:20XCTestDynamicOverlay7XCTFailyySSF","modules":[{"name":"XCTestDynamicOverlay"}]},"hierarchy":{"paths":[["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay"]]},"seeAlsoSections":[{"title":"Overlays","identifiers":["doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:file:line:)"],"generated":true}],"references":{"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTFail(_:)":{"role":"symbol","title":"XCTFail(_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":")"}],"abstract":[{"type":"text","text":"This function generates a failure immediately and unconditionally."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:)","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctfail(_:)"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay/XCTFail(_:file:line:)":{"role":"symbol","title":"XCTFail(_:file:line:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"XCTFail"},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"String","preciseIdentifier":"s:SS"},{"kind":"text","text":", "},{"kind":"externalParam","text":"file"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"StaticString","preciseIdentifier":"s:s12StaticStringV"},{"kind":"text","text":", "},{"kind":"externalParam","text":"line"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"UInt","preciseIdentifier":"s:Su"},{"kind":"text","text":")"}],"abstract":[{"type":"text","text":"This function generates a failure immediately and unconditionally."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay\/XCTFail(_:file:line:)","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay\/xctfail(_:file:line:)"},"doc://XCTestDynamicOverlay/documentation/XCTestDynamicOverlay":{"role":"collection","title":"XCTestDynamicOverlay","abstract":[{"type":"text","text":"Define XCTest assertion helpers directly in your application and library code."}],"identifier":"doc:\/\/XCTestDynamicOverlay\/documentation\/XCTestDynamicOverlay","kind":"symbol","type":"topic","url":"\/documentation\/xctestdynamicoverlay"}}} |
Oops, something went wrong.