Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
smaramba committed Oct 26, 2018
1 parent c22a0b2 commit bc5ded6
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 51 deletions.
28 changes: 28 additions & 0 deletions README.md
Expand Up @@ -131,6 +131,34 @@ self.dispatch(Show("add item screen"))

Learn more about the navigation [here](http://tempura.bendingspoons.com/Classes/Navigator.html)

### ViewController containment

You can have ViewControllers inside other ViewControllers, this is useful if you want to reuse portions of UI including the logic. To do that, in the parent ViewController you need to provide a `ContainerView` that will receive the view of the child ViewController as subview.

```swift
class ParentView: UIView, ViewControllerModellableView {
var childView = ContainerView()
}
```

Then, in the parent ViewController you just need to add the child ViewController:

```swift
class ParentViewController: ViewController<ParentView> {
let childVC: ChildViewController<ChildView>!

override func setup() {
childVC = ChildViewController(store: self.store)
self.add(childVC, in: self.rootView.childView)
}
}
```

All of the automation will work out of the box.
You will now have a `ChildViewController` inside the `ParentViewController`, the ChildViewController's view will be hosted inside the `childView`.



### UI Testing

Tempura has a UI testing system that can be used to take screenshots of your views in all possible states, with all devices and all supported languages.
Expand Down
12 changes: 8 additions & 4 deletions Tempura.xcodeproj/project.pbxproj
Expand Up @@ -32,6 +32,7 @@
646B03F7BDF4F9F857124D2B /* AddItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65BD49BEEC5984A9FE893FB3 /* AddItemViewController.swift */; };
6506175121820AA400D9C6EE /* Tempura.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8A6B80CA27551310DFE47630 /* Tempura.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
650617542182211B00D9C6EE /* ViewController+Containment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650617532182211B00D9C6EE /* ViewController+Containment.swift */; };
650617582182F6BF00D9C6EE /* ViewControlerContainmentSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650617572182F6BF00D9C6EE /* ViewControlerContainmentSpec.swift */; };
655CFAC22181FCDF00602543 /* ChildViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 655CFAC12181FCDF00602543 /* ChildViewController.swift */; };
6708BA66963C651491A3A686 /* String+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A5D20495241273A74CF0DD /* String+Random.swift */; };
6AA037B540B41299BCF0874D /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC63AF968F64847B54F746AC /* Source.swift */; };
Expand Down Expand Up @@ -70,7 +71,7 @@
DBEEDC5070F1927CE2560282 /* ViewControllerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B1DFC03BB4FDA7BD20AC40 /* ViewControllerSpec.swift */; };
DD09610E6461E833B3FA6236 /* DependenciesContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00DD4CFFDBDD14CB66C4794A /* DependenciesContainer.swift */; };
E004EA54447E1A911B2D9C2B /* DemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86EE1E3D4E6D15D61928C89E /* DemoTests.swift */; };
E1976753698708E504DE26EA /* ViewControllerWithLocalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2067F5E2669FA20801183DE0 /* ViewControllerWithLocalState.swift */; };
E1976753698708E504DE26EA /* ViewControllerWithLocalStateSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2067F5E2669FA20801183DE0 /* ViewControllerWithLocalStateSpec.swift */; };
E38E38B57718A80FA1A632A6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E30FE8B5C021F357FE2C84A /* Foundation.framework */; };
E7A40310BF53C477558660EB /* Tempura.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B1C39AEB59B5BE80D2A81B /* Tempura.h */; settings = {ATTRIBUTES = (Public, ); }; };
E7E2A15E2F43D5648D7F2380 /* ViewControllerModellableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E6F5C44777CAC59EA5986C /* ViewControllerModellableView.swift */; };
Expand Down Expand Up @@ -131,7 +132,7 @@
18736DA8E9077F04A3700C7D /* Pods-DemoTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DemoTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DemoTests/Pods-DemoTests.release.xcconfig"; sourceTree = "<group>"; };
1A5A0B668E2DD5AAFA1FB47C /* CollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionView.swift; sourceTree = "<group>"; };
1BD94E381324B88145DAC193 /* ViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
2067F5E2669FA20801183DE0 /* ViewControllerWithLocalState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ViewControllerWithLocalState.swift; sourceTree = "<group>"; };
2067F5E2669FA20801183DE0 /* ViewControllerWithLocalStateSpec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ViewControllerWithLocalStateSpec.swift; sourceTree = "<group>"; };
23A61E64E61A01C89A3F168A /* Models.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = "<group>"; };
24A72485EA8186BC7C9116B1 /* Pods-Tempura-Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tempura-Demo.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tempura-Demo/Pods-Tempura-Demo.release.xcconfig"; sourceTree = "<group>"; };
24E6F5C44777CAC59EA5986C /* ViewControllerModellableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ViewControllerModellableView.swift; sourceTree = "<group>"; };
Expand All @@ -152,6 +153,7 @@
5DADC016CF7CDA8114A79501 /* TempuraTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TempuraTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
61372EC0A04886BC73F0385A /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
650617532182211B00D9C6EE /* ViewController+Containment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewController+Containment.swift"; sourceTree = "<group>"; };
650617572182F6BF00D9C6EE /* ViewControlerContainmentSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControlerContainmentSpec.swift; sourceTree = "<group>"; };
655CFAC12181FCDF00602543 /* ChildViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChildViewController.swift; sourceTree = "<group>"; };
65BD49BEEC5984A9FE893FB3 /* AddItemViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddItemViewController.swift; sourceTree = "<group>"; };
724D934C812B7C374C74714F /* Pods_Tempura_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tempura_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -467,7 +469,8 @@
isa = PBXGroup;
children = (
13B1DFC03BB4FDA7BD20AC40 /* ViewControllerSpec.swift */,
2067F5E2669FA20801183DE0 /* ViewControllerWithLocalState.swift */,
2067F5E2669FA20801183DE0 /* ViewControllerWithLocalStateSpec.swift */,
650617572182F6BF00D9C6EE /* ViewControlerContainmentSpec.swift */,
);
path = TempuraTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -984,7 +987,8 @@
buildActionMask = 2147483647;
files = (
DBEEDC5070F1927CE2560282 /* ViewControllerSpec.swift in Sources */,
E1976753698708E504DE26EA /* ViewControllerWithLocalState.swift in Sources */,
E1976753698708E504DE26EA /* ViewControllerWithLocalStateSpec.swift in Sources */,
650617582182F6BF00D9C6EE /* ViewControlerContainmentSpec.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
72 changes: 46 additions & 26 deletions Tempura.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme
Expand Up @@ -7,91 +7,111 @@
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "NO"
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES">
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "674CA9A75FF5B74E10AC0DC1"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "Demo.app">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO">
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "68B734BF364920E7AE76F00F"
BuildableName = "DemoTests.xctest"
BlueprintName = "DemoTests"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "DemoTests.xctest">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<AdditionalOptions>
</AdditionalOptions>
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "68B734BF364920E7AE76F00F"
BuildableName = "DemoTests.xctest"
BlueprintName = "DemoTests"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "DemoTests.xctest">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83B7964A9B0AD49AD46BD823"
BuildableName = "TempuraTests.xctest"
BlueprintName = "TempuraTests"
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "674CA9A75FF5B74E10AC0DC1"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
buildConfiguration = "Debug"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "674CA9A75FF5B74E10AC0DC1"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "Demo.app">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES">
<BuildableProductRunnable>
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "674CA9A75FF5B74E10AC0DC1"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "Demo.app">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
Expand Down
60 changes: 41 additions & 19 deletions Tempura.xcodeproj/xcshareddata/xcschemes/TempuraTesting.xcscheme
Expand Up @@ -7,65 +7,87 @@
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "NO"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO">
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FDEFCB512DC61502B745008B"
BuildableName = "TempuraTesting.framework"
BlueprintName = "TempuraTesting"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "TempuraTesting.framework">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83B7964A9B0AD49AD46BD823"
BuildableName = "TempuraTests.xctest"
BlueprintName = "TempuraTests"
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FDEFCB512DC61502B745008B"
BuildableName = "TempuraTesting.framework"
BlueprintName = "TempuraTesting"
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
buildConfiguration = "Debug"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FDEFCB512DC61502B745008B"
BuildableName = "TempuraTesting.framework"
BlueprintName = "TempuraTesting"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "TempuraTesting.framework">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES">
<BuildableProductRunnable>
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FDEFCB512DC61502B745008B"
BuildableName = "TempuraTesting.framework"
BlueprintName = "TempuraTesting"
ReferencedContainer = "container:Tempura.xcodeproj"
BuildableName = "TempuraTesting.framework">
ReferencedContainer = "container:Tempura.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
Expand Down
7 changes: 5 additions & 2 deletions Tempura/Core/ViewController+Containment.swift
Expand Up @@ -9,19 +9,22 @@
/// ViewController containment
extension ViewController {
/// Add a ViewController (and its rootView) as a child of self
/// You must provide a ContainerView inside self.rootView to receive the rootView of the child ViewController
/// You must provide a ContainerView inside self.rootView, that container view
/// will automatically receive the rootView of the child ViewController as child
public func add<View: ViewControllerModellableView>(_ child: ViewController<View>, in view: ContainerView) {
self.addChild(child)
view.addSubview(child.rootView)
child.didMove(toParent: self)
}

/// Remove a child ViewController
/// Remove self as child ViewController of parent
public func remove() {
guard let _ = parent else { return }
self.willMove(toParent: nil)
self.removeFromParent()
self.rootView.removeFromSuperview()
self.viewWillDisappear(false)
self.viewDidDisappear(false)
}
}

Expand Down

0 comments on commit bc5ded6

Please sign in to comment.