├── .gitignore
├── LICENSE
├── Podfile
├── Podfile.lock
├── README.md
├── Snapshots.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── Snapshots.xcworkspace
└── contents.xcworkspacedata
├── Snapshots
├── ARLabel.h
├── ARLabel.m
├── App.swift
├── AppDelegate.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ └── Main.storyboard
├── BridgingHeader.h
├── DeveloperDirWatcher.swift
├── Grepper.swift
├── Info.plist
├── Log.swift
├── LogSnapshotsPreviewViewController.swift
├── NSColor+ORSnapshotColours.h
├── NSColor+ORSnapshotColours.m
├── NSFileManager+RecursiveFind.h
├── NSFileManager+RecursiveFind.m
├── NSString+StringBetweenStrings.h
├── NSString+StringBetweenStrings.m
├── ORKaleidoscopeController.h
├── ORKaleidoscopeController.m
├── ORLogReader.h
├── ORLogReader.m
├── ORSlidingImageView.h
├── ORSlidingImageView.m
├── ORTestsSuiteModels.h
├── ORTestsSuiteModels.m
├── SnapshotsViewController.swift
└── ViewController.swift
├── SnapshotsTests
├── DeveloperDirWatcherSpecs.swift
├── Info.plist
├── LogReaderSpecs.swift
├── MultipleSnapshotsErrors.log
├── NewSnapshotsRecorded.log
├── QuickJustNewSnapshot.log
└── QuickNewSnapshot.log
└── design
├── Browse.png
├── Run.png
└── snapshots-app-design.sketch
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | build/
3 | *.pbxuser
4 | !default.pbxuser
5 | *.mode1v3
6 | !default.mode1v3
7 | *.mode2v3
8 | !default.mode2v3
9 | *.perspectivev3
10 | !default.perspectivev3
11 | <<<<<<< HEAD
12 | !default.xcworkspace
13 | xcuserdata
14 | profile
15 | *.moved-aside
16 | DerivedData
17 | .idea/
18 | *.xcscmblueprint
19 | Pods
20 | .pt
21 | .build
22 | tmtags
23 | tmtagsHistory
24 | config/releasenotes.txt
25 | .bundle
26 | Podfile.local
27 | chairs/
28 | .github
29 |
30 | Snapshots.xcodeproj/project.xcworkspace/xcshareddata/
31 |
32 | # Artsy Development APN certificate
33 | net.artsy.artsy.dev.pem
34 | .clang-format
35 |
36 | # Fastlane
37 | Preview.html
38 | fastlane/report.xml
39 | fastlane/Preview.html
40 |
41 | iOSInjectionProject/
42 |
43 | xcuserdata
44 | *.xccheckout
45 | *.moved-aside
46 | DerivedData
47 | *.hmap
48 | *.ipa
49 | *.xcuserstate
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
56 | #
57 | # Pods/
58 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Orta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx, '10.11'
2 | use_frameworks!
3 |
4 | target 'Snapshots' do
5 | pod 'Interstellar'
6 | pod 'FileKit'
7 | pod 'AsyncSwift'
8 | pod 'PXSourceList'
9 |
10 | target 'SnapshotsTests' do
11 | inherit! :search_paths
12 |
13 | pod 'Quick'
14 | pod 'Nimble'
15 | end
16 | end
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - AsyncSwift (1.7.2)
3 | - FileKit (2.0.0)
4 | - Interstellar (1.4.0):
5 | - Interstellar/Core (= 1.4.0)
6 | - Interstellar/Warpdrive (= 1.4.0)
7 | - Interstellar/Core (1.4.0)
8 | - Interstellar/Warpdrive (1.4.0):
9 | - Interstellar/Core
10 | - Nimble (4.0.0)
11 | - PXSourceList (2.0.7)
12 | - Quick (0.9.1)
13 |
14 | DEPENDENCIES:
15 | - AsyncSwift
16 | - FileKit
17 | - Interstellar
18 | - Nimble
19 | - PXSourceList
20 | - Quick
21 |
22 | SPEC CHECKSUMS:
23 | AsyncSwift: 46a78bceb11f0e5bb52747f740d9692ec78d2d7c
24 | FileKit: fd360f82f62a1f70dd2ccdbe0950d3a6d1e25d1d
25 | Interstellar: 40fc666872436d6c1b3524c59437ebdb5dec1c6a
26 | Nimble: 72bcc3e2f02242e6bfaaf8d9412ca7bfe3d8b417
27 | PXSourceList: 8e37978a5db6c8d8d255f8913603bcea322c6445
28 | Quick: a5221fc21788b6aeda934805e68b061839bc3165
29 |
30 | PODFILE CHECKSUM: a9b50005461c9a49d1dca176a558f21fd8b28de5
31 |
32 | COCOAPODS: 1.0.0
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Snapshots App for Xcode
2 |
3 | Ignore this, see https://github.com/Antondomashnev/FBSnapshotsViewer
4 |
5 | ---
6 |
7 | ### An App to show the state of FBSnapshot Tests.
8 |
9 | I think Facebook have [view testing](https://github.com/facebook/ios-snapshot-test-case) right. So I build
10 | an Xcode plugin, then I decided maybe the plugin isn't the right approach, so I started an app.
11 |
12 | #### Main Features
13 |
14 | * Showing new images as they're created
15 | * Showing the differences between failed snapshot tests
16 | * Open specific diffs in Kaleidoscope
17 | * Turns red if you've created a view with a zero frame
18 |
19 | #### Installation
20 |
21 | Will provide a zip.
22 |
23 | #### Contributing
24 |
25 | It's all UI work, I'm taking a lot of the log parsing from the Xcode plugin.
26 |
--------------------------------------------------------------------------------
/Snapshots.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Snapshots.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Snapshots/ARLabel.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | /// These labels don't get mangled by transparency
4 |
5 | @interface ARLabel : NSTextField
6 | @end
7 |
--------------------------------------------------------------------------------
/Snapshots/ARLabel.m:
--------------------------------------------------------------------------------
1 | #import "ARLabel.h"
2 |
3 | @interface ARLabelCell : NSTextFieldCell
4 |
5 | @end
6 |
7 |
8 | @implementation ARLabelCell
9 |
10 |
11 | @end
12 |
13 | @implementation ARLabel
14 |
15 | - (void)awakeFromNib
16 | {
17 | [super awakeFromNib];
18 | [self setup];
19 | }
20 |
21 | - (instancetype)initWithFrame:(NSRect)frameRect
22 | {
23 | self = [super initWithFrame:frameRect];
24 | if (!self) return nil;
25 |
26 | [self setup];
27 | return self;
28 | }
29 |
30 | - (BOOL)allowsVibrancy
31 | {
32 | return NO;
33 | }
34 |
35 | - (void)setup
36 | {
37 | self.bezeled = NO;
38 | self.editable = NO;
39 | self.drawsBackground = NO;
40 | }
41 |
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Snapshots/App.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FileKit
3 | import Async
4 |
5 | class App: NSObject, NSCopying {
6 | let name: String
7 | let lastUpdated: NSDate
8 |
9 | let reader = ORLogReader()
10 | var logs = [Log]()
11 |
12 | var prettyName: String {
13 | return name.componentsSeparatedByString("-").first ?? "-"
14 | }
15 |
16 | init(name: String, date: NSDate) {
17 | self.name = name
18 | self.lastUpdated = date
19 | }
20 |
21 | func copyWithZone(zone: NSZone) -> AnyObject {
22 | let app = App(name: self.name, date: self.lastUpdated)
23 | app.logs = self.logs
24 | return app
25 | }
26 |
27 | func readLogs() {
28 | Async.background {
29 | for log in self.logs {
30 | // look into http://blog.krzyzanowskim.com/2015/01/10/nsscanner-for-raw-data-and-files/ ?
31 |
32 | guard let content = try? NSString(contentsOfURL: log.path.URL, encoding: NSUTF8StringEncoding) as String else { continue }
33 | if log.path.contains("SOKKWK") {
34 | print("OK")
35 | }
36 |
37 | self.reader.readLog(content)
38 | log.updateWithReader(self.reader)
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Snapshots/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Interstellar
2 | import Cocoa
3 | import FileKit
4 |
5 | @NSApplicationMain
6 | class AppDelegate: NSObject, NSApplicationDelegate {
7 |
8 | func applicationDidFinishLaunching(aNotification: NSNotification) {
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Snapshots/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/Snapshots/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 | %{value1}@
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
994 |
1001 |
1008 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
--------------------------------------------------------------------------------
/Snapshots/BridgingHeader.h:
--------------------------------------------------------------------------------
1 | #import "ORLogReader.h"
2 |
3 | //#import "libgrep.h"
4 | //#import "regex.h"
--------------------------------------------------------------------------------
/Snapshots/DeveloperDirWatcher.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FileKit
3 | import Interstellar
4 | import Async
5 |
6 | class DeveloperDirWatcher: NSObject {
7 | var fileManager: NSFileManager = NSFileManager.defaultManager()
8 | var library = Path.UserLibrary
9 | var derivedDataDir = "Developer/Xcode/DerivedData"
10 |
11 | let appNamesUpdateSignal = Signal<[App]>()
12 | let appsWithMetadataUpdatedSignal = Signal<[App]>()
13 |
14 | let appUpdatedSignal = Signal()
15 |
16 | func startParsing() {
17 | Async.background {
18 | let apps = self.getAllAppNamesWithTests()
19 | let sorted = apps.sort { $0.lastUpdated.compare($1.lastUpdated) == .OrderedDescending }
20 |
21 | // Optional, note used though
22 | Async.main { self.appNamesUpdateSignal.update(sorted) }
23 |
24 | for app in apps {
25 | self.getLogsForApp(app.name).next {
26 | app.logs = $0.map { Log(path: $0) }
27 | Async.main { self.appsWithMetadataUpdatedSignal.update(sorted) }
28 | }
29 | }
30 |
31 | Async.main { self.appsWithMetadataUpdatedSignal.update(sorted) }
32 | }
33 | }
34 |
35 | func getAllAppNamesWithTests() -> [App] {
36 | Path.fileManager = fileManager
37 |
38 | let derived = library + derivedDataDir
39 | let paths = derived.find(searchDepth: 3) { path in
40 | return path.rawValue.hasSuffix("/Logs/Test")
41 | }
42 |
43 | // Looks like:
44 | // "/Users/orta/Library/Developer/Xcode/DerivedData/Aerodramus-elioeeoyxfebivbqkcrplnueiqkk/Logs/Test"
45 |
46 | return paths.flatMap { path in
47 | let date = path.modificationDate ?? NSDate.distantPast()
48 | return App(name: path.parent.parent.fileName, date: date)
49 | }
50 | }
51 |
52 | func getLogsForApp(name: String) -> Signal<[Path]> {
53 | let appLogs = self.library + self.derivedDataDir + name + "Logs" + "Test"
54 | let queries = ["replace recordSnapshot with a check", "expected a matching snapshot"]
55 | return Grepper.getPathsMatchingPattern(queries, fromPath: appLogs)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Snapshots/Grepper.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import Interstellar
3 | import FileKit
4 | import Async
5 |
6 | class Grepper: NSObject {
7 |
8 | class func getPathsMatchingPattern(patterns:[String], fromPath: Path) -> Signal<[Path]> {
9 | let signal = Signal<[Path]>()
10 |
11 | Async.background {
12 | let task:NSTask = NSTask()
13 | let pipe:NSPipe = NSPipe()
14 |
15 | task.launchPath = "/usr/bin/grep"
16 | var arguments = ["-lr"]
17 | for pattern in patterns { arguments.append("-e"); arguments.append(pattern) }
18 | arguments.append(fromPath.rawValue)
19 |
20 | // print("grep ", arguments.joinWithSeparator(" "))
21 |
22 | task.arguments = arguments
23 | task.standardOutput = pipe
24 | task.launch()
25 |
26 | let handle = pipe.fileHandleForReading
27 | let data = handle.readDataToEndOfFile()
28 |
29 | guard let pathString = NSString(data: data, encoding: NSUTF8StringEncoding) else {
30 | Async.main { signal.update([]) }
31 | return
32 | }
33 |
34 | let pathStrings = pathString.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
35 |
36 | guard pathString.length > 0 else {
37 | Async.main { signal.update([]) }
38 | return
39 | }
40 |
41 | print("Found useful test logs:", pathStrings)
42 | Async.main { signal.update(pathStrings.map { Path($0) }) }
43 | }
44 |
45 | return signal
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/Snapshots/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2016 Orta. All rights reserved.
29 | NSMainStoryboardFile
30 | Main
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Snapshots/Log.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FileKit
3 |
4 | class Log: NSObject, NSCopying {
5 | let path: Path
6 | var parsed: Bool = false
7 |
8 | var valid: Bool {
9 | return hasSnapshotErrors || hasNewSnapshots
10 | }
11 |
12 | var hasSnapshotErrors: Bool {
13 | return snapshotErrors.isEmpty == false
14 | }
15 |
16 | var hasNewSnapshots: Bool {
17 | return newSnapshots.isEmpty == false
18 | }
19 |
20 | var newSnapshots = [ORSnapshotCreationReference]()
21 | var snapshotErrors = [ORKaleidoscopeCommand]()
22 |
23 | var title: String {
24 | var message = ""
25 | if hasSnapshotErrors {
26 | message += "Recorded new Snapshots"
27 | }
28 | if hasNewSnapshots {
29 | if message.isEmpty == false { message += ", " }
30 | message += "Got Snapshots Errors"
31 | }
32 | return message
33 | }
34 |
35 | var name: String {
36 | return path.fileName
37 | }
38 |
39 | init(path: Path) {
40 | self.path = path
41 | }
42 |
43 | func copyWithZone(zone: NSZone) -> AnyObject {
44 | let log = Log(path: self.path)
45 | log.parsed = parsed
46 | log.newSnapshots = newSnapshots
47 | log.snapshotErrors = snapshotErrors
48 | return log
49 | }
50 |
51 | func updateWithReader(reader: ORLogReader) {
52 | parsed = true
53 | snapshotErrors = reader.uniqueDiffCommands()
54 | newSnapshots = reader.newSnapshots()
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Snapshots/LogSnapshotsPreviewViewController.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import Quartz
3 | import Interstellar
4 |
5 | class LogSnapshotsPreviewViewController: NSViewController {
6 |
7 | @IBOutlet weak var imageBrowser: IKImageBrowserView!
8 | @IBOutlet weak var titleTextField: NSTextField!
9 |
10 | let newLogSelected = Signal()
11 | private var log: Log?
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | newLogSelected.next { log in
17 | self.log = log
18 | self.imageBrowser.reloadData()
19 | self.titleTextField.stringValue = log.title
20 | print("OK \(log.valid) errors")
21 |
22 | }
23 | }
24 |
25 | override func imageBrowserSelectionDidChange(aBrowser: IKImageBrowserView!) {
26 |
27 | }
28 |
29 | override func imageBrowser(aBrowser: IKImageBrowserView!, itemAtIndex index: Int) -> AnyObject! {
30 | return ""
31 | }
32 |
33 | override func numberOfItemsInImageBrowser(aBrowser: IKImageBrowserView!) -> Int {
34 | guard let log = log else { return 0 }
35 | return log.snapshotErrors.count + log.newSnapshots.count
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Snapshots/NSColor+ORSnapshotColours.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+ORSnapshotColours.h
3 | // SnapshotDiffs
4 | //
5 | // Created by Orta on 6/15/14.
6 | // Copyright (c) 2014 Orta. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSColor (ORSnapshotColours)
12 |
13 | + (NSColor *)or_orangeColour;
14 | + (NSColor *)or_blueColour;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Snapshots/NSColor+ORSnapshotColours.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+ORSnapshotColours.m
3 | // SnapshotDiffs
4 | //
5 | // Created by Orta on 6/15/14.
6 | // Copyright (c) 2014 Orta. All rights reserved.
7 | //
8 |
9 | #import "NSColor+ORSnapshotColours.h"
10 |
11 | @implementation NSColor (ORSnapshotColours)
12 |
13 | + (NSColor *)or_orangeColour
14 | {
15 | return [NSColor colorWithCalibratedRed:0.842 green:0.495 blue:0.202 alpha:1.000];
16 | }
17 |
18 | + (NSColor *)or_blueColour
19 | {
20 | return [NSColor colorWithCalibratedRed:0.556 green:0.605 blue:0.802 alpha:1.000];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Snapshots/NSFileManager+RecursiveFind.h:
--------------------------------------------------------------------------------
1 | @interface NSFileManager (ORRecursiveFind)
2 |
3 | - (NSString *)or_findFileWithNamePrefix:(NSString *)name inFolder:(NSString *)folder;
4 |
5 | @end
--------------------------------------------------------------------------------
/Snapshots/NSFileManager+RecursiveFind.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @implementation NSFileManager (ORRecursiveFind)
5 |
6 | - (NSString *)or_findFileWithNamePrefix:(NSString *)name inFolder:(NSString *)folder
7 | {
8 | @try {
9 | // Sure glad I built OROpenInAppCode already :)
10 |
11 | NSDocument *document = [NSApp orderedDocuments].firstObject;
12 | NSURL *workspaceDirectoryURL = [[[document valueForKeyPath:@"_workspace.representingFilePath.fileURL"] URLByDeletingLastPathComponent] filePathURL];
13 |
14 | NSFileManager *fileManager = [NSFileManager defaultManager];
15 | NSDirectoryEnumerator *enumerator = nil;
16 | enumerator = [fileManager enumeratorAtURL:workspaceDirectoryURL
17 | includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
18 | options:NSDirectoryEnumerationSkipsHiddenFiles
19 | errorHandler:^BOOL(NSURL *url, NSError *error) {
20 | NSLog(@"[Error] %@ (%@)", error, url);
21 | return YES;
22 | }];
23 |
24 | NSMutableArray *mutableFileURLs = [NSMutableArray array];
25 | for (NSURL *fileURL in enumerator) {
26 |
27 | NSString *filename;
28 | [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil];
29 |
30 | NSNumber *isDirectory;
31 | [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
32 |
33 | // Skip directories with '_' prefix, for example
34 | if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) {
35 | [enumerator skipDescendants];
36 | continue;
37 | }
38 |
39 | if (![isDirectory boolValue]) {
40 | [mutableFileURLs addObject:fileURL];
41 | }
42 |
43 | if ([filename hasPrefix:name] && [fileURL.absoluteString rangeOfString:folder].location != NSNotFound) {
44 | return fileURL.absoluteString;
45 | }
46 | }
47 | }
48 | @catch (NSException *exception) {
49 | return nil;
50 | }
51 |
52 | return nil;
53 | }
54 |
55 | @end
--------------------------------------------------------------------------------
/Snapshots/NSString+StringBetweenStrings.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NSString (StringBetweenStrings)
4 |
5 | // on a string "hello world" with arguments "e" and "d"
6 | // will return "llo world" or nil if it can't find the start or end.
7 |
8 | - (NSString *)or_substringBetween:(NSString *)start and:(NSString *)end;
9 | @end
10 |
--------------------------------------------------------------------------------
/Snapshots/NSString+StringBetweenStrings.m:
--------------------------------------------------------------------------------
1 | #import "NSString+StringBetweenStrings.h"
2 |
3 | @implementation NSString (StringBetweenStrings)
4 |
5 | - (NSString *)or_substringBetween:(NSString *)start and:(NSString *)end {
6 | NSRange startingRange = [self rangeOfString:start];
7 | NSRange endingRange = [self rangeOfString:end];
8 |
9 | if (startingRange.location == NSNotFound || endingRange.location == NSNotFound) {
10 | return nil;
11 | }
12 |
13 | NSUInteger length = endingRange.location - startingRange.location - startingRange.length;
14 | NSUInteger location = startingRange.location + startingRange.length;
15 |
16 | if (length + location > self.length) {
17 | return nil;
18 | }
19 |
20 | return [self substringWithRange:NSMakeRange(location, length)];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Snapshots/ORKaleidoscopeController.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface ORKaleidoscopeController : NSObject
4 |
5 | + (BOOL)isInstalled;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/Snapshots/ORKaleidoscopeController.m:
--------------------------------------------------------------------------------
1 | #import "ORKaleidoscopeController.h"
2 | #import
3 |
4 | @implementation ORKaleidoscopeController
5 |
6 | + (BOOL)isInstalled
7 | {
8 | // If no application could be found,
9 | // * NULL is returned and outError (if not NULL) is populated with kLSApplicationNotFoundErr.
10 |
11 | CFErrorRef error = NULL;
12 | CFArrayRef result = LSCopyApplicationURLsForBundleIdentifier (CFSTR("com.blackpixel.kaleidoscope"), &error );
13 | if (result) { CFRelease(result); }
14 | return error != nil;
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Snapshots/ORLogReader.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "ORTestsSuiteModels.h"
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface ORLogReader : NSObject
7 |
8 | - (void)readLog:(NSString *)log;
9 |
10 | - (NSArray *)uniqueDiffCommands;
11 | - (NSArray *)ksdiffCommands;
12 | - (NSArray *)newSnapshots;
13 |
14 | - (NSArray *)testSuites;
15 |
16 | - (BOOL)hasNewSnapshots;
17 | - (BOOL)hasCGErrors;
18 | - (BOOL)hasSnapshotTestErrors;
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/Snapshots/ORLogReader.m:
--------------------------------------------------------------------------------
1 | #import "ORLogReader.h"
2 | #import "NSFileManager+RecursiveFind.h"
3 | #import "NSString+StringBetweenStrings.h"
4 |
5 | @interface ORLogReader()
6 | @property (nonatomic, readwrite, assign) BOOL hasCGErrors;
7 | @property (nonatomic, readonly, strong) NSMutableOrderedSet *mutableTestSuites;
8 | @property (nonatomic, readonly, strong) NSMutableOrderedSet *mutableDiffCommands;
9 | @property (nonatomic, readonly, strong) NSMutableOrderedSet *mutableSnapshotCreations;
10 | @end
11 |
12 | @implementation ORLogReader
13 |
14 | - (instancetype)init
15 | {
16 | self = [super init];
17 | if (!self) return nil;
18 |
19 | _mutableDiffCommands = [NSMutableOrderedSet orderedSet];
20 | _mutableTestSuites = [NSMutableOrderedSet orderedSet];
21 | _mutableSnapshotCreations = [NSMutableOrderedSet orderedSet];
22 | _hasCGErrors = NO;
23 |
24 | return self;
25 | }
26 |
27 | - (NSArray *)testSuites
28 | {
29 | return self.mutableTestSuites.array;
30 | }
31 |
32 |
33 | - (ORTestSuite *)latestTestSuite
34 | {
35 | return self.mutableTestSuites.lastObject;
36 | }
37 |
38 |
39 | - (void)readLog:(NSString *)log
40 | {
41 | for (NSString *line in [log componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet]) {
42 | if ([line rangeOfString:@"Test Suite"].location != NSNotFound) {
43 | ORTestSuite *suite = [ORTestSuite suiteFromString:line];
44 | if (suite) [self.mutableTestSuites addObject:suite];
45 | }
46 |
47 | if ([line rangeOfString:@"Test Case"].location != NSNotFound) {
48 | if ([line rangeOfString:@"started."].location != NSNotFound) {
49 | ORTestCase *testCase = [ORTestCase caseFromString:line];
50 | if (testCase) [self.latestTestSuite.testCases addObject:testCase];
51 |
52 | } else if ([line rangeOfString:@"' failed ("].location != NSNotFound) {
53 | for (ORKaleidoscopeCommand *command in self.mutableDiffCommands) {
54 | [command setFails:YES];
55 | }
56 | }
57 | }
58 |
59 | if ([line rangeOfString:@"ksdiff"].location != NSNotFound) {
60 | NSString *commandString = [self extractCommandFromLine:line];
61 | ORKaleidoscopeCommand *command = [ORKaleidoscopeCommand commandFromString:commandString];
62 | if (command) {
63 | [self.mutableDiffCommands addObject:command];
64 | [self.latestTestSuite.latestTestCase addCommand:command];
65 | }
66 | }
67 |
68 | if ([line rangeOfString:@"This application, or a library it uses, is using an invalid context"].location != NSNotFound) {
69 | _hasCGErrors = YES;
70 | }
71 |
72 | if ([line rangeOfString:@"]"].location != NSNotFound && [line rangeOfString:@"expected a matching snapshot"].location != NSNotFound) {
73 | NSString *filepathAndLine = [line or_substringBetween:@"] " and:@" expected a matching snapshot"];
74 | if (filepathAndLine && filepathAndLine.length > 1) {
75 | [self.latestTestSuite.latestTestCase.commands makeObjectsPerformSelector:@selector(setProjectLocation:) withObject:filepathAndLine];
76 | }
77 | }
78 |
79 | if ([line rangeOfString:@"successfully recorded"].location != NSNotFound) {
80 | ORSnapshotCreationReference *snapshot = [ORSnapshotCreationReference referenceFromString:line];
81 |
82 | if (snapshot) {
83 | ORTestCase *testCase = self.latestTestSuite.latestTestCase;
84 | NSString *path = [[NSFileManager defaultManager] or_findFileWithNamePrefix:snapshot.name inFolder:self.latestTestSuite.name];
85 | path = [path stringByReplacingOccurrencesOfString:@"file://" withString:@""];
86 | snapshot.path = [path stringByReplacingOccurrencesOfString:@"%20" withString:@" "];
87 |
88 | if (![self.mutableSnapshotCreations containsObject:snapshot]) {
89 | [self.mutableSnapshotCreations addObject:snapshot];
90 | [testCase addSnapshot:snapshot];
91 | }
92 | }
93 | }
94 | }
95 | }
96 |
97 | - (NSString *)extractCommandFromLine:(NSString *)line
98 | {
99 | return [line componentsSeparatedByString:@"diff:\n"].lastObject;
100 | }
101 |
102 | - (BOOL)hasNewSnapshots
103 | {
104 | return (self.mutableSnapshotCreations.count > 0);
105 | }
106 |
107 | - (BOOL)hasSnapshotTestErrors
108 | {
109 | return (self.uniqueDiffCommands.count > 0);
110 | }
111 |
112 | - (NSArray *)ksdiffCommands
113 | {
114 | return [self.mutableDiffCommands.array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ORKaleidoscopeCommand *command, NSDictionary *bindings) {
115 | return command.fails;
116 | }]];
117 | }
118 |
119 | - (NSArray *)uniqueDiffCommands
120 | {
121 | NSArray *commands = [self ksdiffCommands];
122 | if (commands.count == 1) return commands;
123 |
124 | return [commands filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ORKaleidoscopeCommand *command, NSDictionary *bindings) {
125 | return [[NSFileManager defaultManager] contentsEqualAtPath:command.afterPath andPath:command.beforePath] == NO;
126 | }]];
127 | }
128 |
129 | - (NSArray *)newSnapshots
130 | {
131 | return _mutableSnapshotCreations.array;
132 | }
133 |
134 | @end
135 |
--------------------------------------------------------------------------------
/Snapshots/ORSlidingImageView.h:
--------------------------------------------------------------------------------
1 | @import Cocoa;
2 |
3 | @interface ORSlidingImageView : NSView
4 |
5 | @property (nonatomic, strong) NSImage *frontImage;
6 | @property (nonatomic, strong) NSImage *backImage;
7 |
8 | @property (readwrite, nonatomic, strong) NSString *frontMessage;
9 | @property (readwrite, nonatomic, strong) NSString *backMessage;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/Snapshots/ORSlidingImageView.m:
--------------------------------------------------------------------------------
1 | @import Quartz;
2 |
3 | #import "ORSlidingImageView.h"
4 | #import "NSColor+ORSnapshotColours.h"
5 | #import "ARLabel.h"
6 |
7 | static CGFloat ORContentInset = 8;
8 |
9 | @interface ORSlidingImageView()
10 | @property (nonatomic, weak) NSImageView *frontImageView;
11 | @property (nonatomic, weak) NSImageView *backImageView;
12 |
13 | @property (nonatomic, strong) NSTextField *frontViewLabel;
14 | @property (nonatomic, strong) NSTextField *backViewLabel;
15 |
16 | @property (nonatomic, strong) NSTrackingArea *trackingArea;
17 | @property (nonatomic, weak) NSView *divider;
18 | @end
19 |
20 | @implementation ORSlidingImageView
21 |
22 | - (void)setFrontImage:(NSImage *)frontImage
23 | {
24 | _frontImage = frontImage;
25 |
26 | if (!self.frontImageView) {
27 | NSImageView *frontImageView = [self createImageView];
28 | [self addSubview:frontImageView];
29 |
30 | self.frontImageView = frontImageView;
31 | self.frontImageView.layer.borderColor = [NSColor or_blueColour].CGColor;
32 | }
33 |
34 | self.frontImageView.image = frontImage;
35 | [self moveLabelsToFront];
36 | }
37 |
38 | - (void)setBackImage:(NSImage *)backImage
39 | {
40 | _backImage = backImage;
41 | if (!self.backImageView) {
42 | NSImageView *backImageView = [self createImageView];
43 |
44 | NSView *front = self.frontImageView;
45 | [self.frontImageView removeFromSuperview];
46 | [self addSubview:backImageView];
47 | [self addSubview:front];
48 |
49 | backImageView.layer.borderColor = [NSColor or_orangeColour].CGColor;
50 | self.backImageView = backImageView;
51 |
52 | [self createDivider];
53 | }
54 |
55 | self.backImageView.image = backImage;
56 | [self maskViewsWithX:CGRectGetMidX(self.bounds)];
57 | [self moveLabelsToFront];
58 | }
59 |
60 | - (void)setBackMessage:(NSString *)backMessage
61 | {
62 | if (!self.backViewLabel) {
63 | NSTextField *textViewLabel = [[ARLabel alloc] initWithFrame:[self frameForTheBottomOfImageView:self.backImageView]];
64 | textViewLabel.drawsBackground = YES;
65 | textViewLabel.backgroundColor = [NSColor colorWithRed:1 green:1 blue:1 alpha:0.5];
66 |
67 | self.backViewLabel = textViewLabel;
68 | [self.backImageView addSubview:textViewLabel];
69 | }
70 |
71 | self.backViewLabel.stringValue = backMessage;
72 | [self moveLabelsToFront];
73 | }
74 |
75 | - (void)setFrontMessage:(NSString *)frontMessage
76 | {
77 | if (!self.frontViewLabel) {
78 | NSTextField *textViewLabel = [[ARLabel alloc] initWithFrame:[self frameForTheBottomOfImageView:self.frontImageView]];
79 | textViewLabel.drawsBackground = YES;
80 | textViewLabel.backgroundColor = [NSColor colorWithRed:1 green:1 blue:1 alpha:0.5];
81 |
82 | self.frontViewLabel = textViewLabel;
83 |
84 | [self.frontImageView addSubview:textViewLabel];
85 | }
86 |
87 | self.frontViewLabel.stringValue = frontMessage;
88 | [self moveLabelsToFront];
89 | }
90 |
91 | - (void)moveLabelsToFront
92 | {
93 | [self.frontViewLabel removeFromSuperview];
94 | [self.frontImageView addSubview:self.frontViewLabel positioned:NSWindowAbove relativeTo:nil];
95 |
96 | [self.backViewLabel removeFromSuperview];
97 | [self.backImageView addSubview:self.backViewLabel positioned:NSWindowAbove relativeTo:nil];
98 | }
99 |
100 | - (CGRect)frameForTheBottomOfImageView:(NSImageView *)imageView
101 | {
102 | return CGRectMake(6, 0, 64, 20);
103 | }
104 |
105 | - (BOOL) wantsDefaultClipping
106 | {
107 | return NO;
108 | }
109 |
110 | - (void)createDivider
111 | {
112 | if (self.divider) return;
113 |
114 | NSView *divider = [[NSView alloc] initWithFrame:self.boundsForDivider];
115 | divider.wantsLayer = YES;
116 | divider.layer.backgroundColor = [NSColor blackColor].CGColor;
117 | [self addSubview:divider];
118 | self.divider = divider;
119 | }
120 |
121 | - (NSImageView *)createImageView
122 | {
123 | CGRect frame = CGRectInset(self.bounds, 0, ORContentInset);
124 | NSImageView *imageView = [[NSImageView alloc] initWithFrame:frame];
125 | imageView.imageFrameStyle = NSImageFrameNone;
126 | imageView.wantsLayer = YES;
127 | imageView.layer.masksToBounds = YES;
128 | imageView.layer.borderWidth = 2;
129 | return imageView;
130 | }
131 |
132 | - (void)ensureTrackingArea
133 | {
134 | if (self.trackingArea == nil) {
135 | _trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:NSTrackingInVisibleRect | NSTrackingActiveAlways | NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited owner:self userInfo:nil];
136 | }
137 | }
138 |
139 | - (void)updateTrackingAreas
140 | {
141 | [super updateTrackingAreas];
142 | [self ensureTrackingArea];
143 | if (![[self trackingAreas] containsObject:self.trackingArea]) {
144 | [self addTrackingArea:self.trackingArea];
145 | }
146 | }
147 |
148 | - (void)mouseMoved:(NSEvent *)event
149 | {
150 | NSPoint location = [self convertPoint:event.locationInWindow fromView:nil];
151 | [self maskViewsWithX:location.x];
152 | }
153 |
154 | - (void)mouseDragged:(NSEvent *)theEvent
155 | {
156 | [self mouseMoved:theEvent];
157 | }
158 |
159 | - (void)maskViewsWithX:(CGFloat)x
160 | {
161 | x = roundf(x);
162 |
163 | CGPathRef mask = [self newRightMaskPathWithX:x];
164 | CAShapeLayer *rightBasedMaskLayer = [CAShapeLayer layer];
165 | [rightBasedMaskLayer setPath:mask];
166 | CGPathRelease(mask);
167 |
168 | self.frontImageView.layer.mask = rightBasedMaskLayer;
169 |
170 | mask = [self newLeftMaskPathWithX:x];
171 | CAShapeLayer *leftBasedMaskLayer = [CAShapeLayer layer];
172 | [leftBasedMaskLayer setPath:mask];
173 | CGPathRelease(mask);
174 |
175 | self.backImageView.layer.mask = leftBasedMaskLayer;
176 |
177 | CGRect frame = [self boundsForDivider];
178 | frame.origin.x = x;
179 | self.divider.frame = frame;
180 | }
181 |
182 | - (CGRect)boundsForDivider
183 | {
184 | return CGRectMake(0, -20, 1, CGRectGetHeight(self.bounds) + 40);
185 | }
186 |
187 | - (CGPathRef)newRightMaskPathWithX:(CGFloat)x;
188 | {
189 | CGMutablePathRef maskPath = CGPathCreateMutable();
190 |
191 | CGRect rect = CGRectMake(0, 0, x, CGRectGetHeight(self.bounds));
192 | CGPathAddRect(maskPath, NULL, rect);
193 |
194 | CGPathCloseSubpath(maskPath);
195 |
196 | return maskPath;
197 | }
198 |
199 | - (CGPathRef)newLeftMaskPathWithX:(CGFloat)x;
200 | {
201 | CGMutablePathRef maskPath = CGPathCreateMutable();
202 |
203 | CGRect rect = CGRectMake(x, 0, CGRectGetWidth(self.bounds) - x, CGRectGetHeight(self.bounds));
204 | CGPathAddRect(maskPath, NULL, rect);
205 |
206 | CGPathCloseSubpath(maskPath);
207 |
208 | return maskPath;
209 | }
210 |
211 | @end
212 |
--------------------------------------------------------------------------------
/Snapshots/ORTestsSuiteModels.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class ORTestCase, ORKaleidoscopeCommand, ORSnapshotCreationReference;
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface ORTestSuite : NSObject
8 | @property (nonatomic, copy) NSString *name;
9 | @property (nonatomic, strong) NSMutableArray *testCases;
10 |
11 | - (NSArray *)failingTestCases;
12 | - (BOOL)hasFailingTests;
13 | - (BOOL)hasNewSnapshots;
14 |
15 | + (ORTestSuite *)suiteFromString:(NSString *)line;
16 | - (ORTestCase *)latestTestCase;
17 | @end
18 |
19 | @interface ORTestCase : NSObject
20 |
21 | @property (nonatomic, copy) NSString *name;
22 | @property (nonatomic, strong) NSMutableArray *commands;
23 | @property (nonatomic, strong) NSMutableArray *snapshots;
24 |
25 | - (NSArray *)uniqueDiffCommands;
26 |
27 | @property (nonatomic, assign) BOOL hasFailingTests;
28 |
29 | + (ORTestCase *)caseFromString:(NSString *)line;
30 | - (void)addCommand:(ORKaleidoscopeCommand *)command;
31 | - (void)addSnapshot:(ORSnapshotCreationReference *)snapshot;
32 | - (ORKaleidoscopeCommand *)latestCommand;
33 | @end
34 |
35 |
36 | @interface ORKaleidoscopeCommand : NSObject
37 |
38 | - (void)launch;
39 | - (void)swapImages;
40 | - (void)openInFinder;
41 | - (void)openInPreview;
42 |
43 | @property (nonatomic, assign) BOOL fails;
44 | @property (nonatomic, copy) NSString *beforePath;
45 | @property (nonatomic, copy) NSString *afterPath;
46 | @property (nonatomic, copy) NSString *fullCommand;
47 | @property (nonatomic, weak) ORTestCase *testCase;
48 | @property (nonatomic, copy) NSString *projectLocation;
49 |
50 |
51 | + (instancetype)commandFromString:(NSString *)command;
52 | @end
53 |
54 | @interface ORSnapshotCreationReference : NSObject
55 |
56 | @property (nonatomic, copy) NSString *name;
57 | @property (nonatomic, copy) NSString *path;
58 | @property (nonatomic, weak) ORTestCase *testCase;
59 |
60 | + (instancetype)referenceFromString:(NSString *)line;
61 | @end
62 |
63 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/Snapshots/ORTestsSuiteModels.m:
--------------------------------------------------------------------------------
1 | #import "ORTestsSuiteModels.h"
2 | #import "NSFileManager+RecursiveFind.h"
3 | #import "ORKaleidoscopeController.h"
4 | #import
5 |
6 | @implementation ORTestSuite
7 |
8 | + (ORTestSuite *)suiteFromString:(NSString *)line
9 | {
10 | NSArray *components = [line componentsSeparatedByString:@"Test Suite '"];
11 | NSArray *endComponents = [line componentsSeparatedByString:@"' started at"];
12 |
13 | if (components.count == 2 && endComponents.count == 2) {
14 | ORTestSuite *suite = [[ORTestSuite alloc] init];
15 | suite.testCases = [NSMutableArray array];
16 | suite.name = [[components.lastObject componentsSeparatedByString:@"'"] firstObject];
17 | return suite;
18 | }
19 |
20 | return nil;
21 | }
22 |
23 | - (ORTestCase *)latestTestCase
24 | {
25 | return self.testCases.lastObject;
26 | }
27 |
28 | - (NSArray *)failingTestCases
29 | {
30 | return [self.testCases filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ORTestCase *testCase, NSDictionary *bindings) {
31 | return testCase.hasFailingTests;
32 | }]];
33 | }
34 |
35 | - (BOOL)hasFailingTests
36 | {
37 | return self.failingTestCases.count > 0;
38 | }
39 |
40 | - (BOOL)hasNewSnapshots
41 | {
42 | for (ORTestCase *testCase in self.testCases) {
43 | if (testCase.snapshots.count > 0) {
44 | return YES;
45 | }
46 | }
47 | return NO;
48 | }
49 |
50 |
51 | @end
52 |
53 | @implementation ORTestCase
54 |
55 | + (ORTestCase *)caseFromString:(NSString *)line
56 | {
57 | NSArray *components = [line componentsSeparatedByString:@"Test Case '-["];
58 | NSArray *endComponents = [line componentsSeparatedByString:@"]' started."];
59 |
60 | if (components.count == 2 && endComponents.count == 2) {
61 | ORTestCase *testCase = [[ORTestCase alloc] init];
62 | testCase.commands = [NSMutableArray array];
63 | testCase.snapshots = [NSMutableArray array];
64 |
65 | // Let's make it readable
66 | NSString *name = [[components.lastObject componentsSeparatedByString:@"'"] firstObject];
67 | name = [[name componentsSeparatedByString:@" "] lastObject];
68 | name = [[name componentsSeparatedByString:@"]"] firstObject];
69 | name = [name stringByReplacingOccurrencesOfString:@"_" withString:@" "];
70 |
71 | // We avoid hitting ends of words by adding the space, but that potentially misses the first one
72 | name = [@" " stringByAppendingString:name];
73 | name = [name stringByReplacingOccurrencesOfString:@" hasn t" withString:@" hasn't"];
74 | name = [name stringByReplacingOccurrencesOfString:@" isn t" withString:@" isn't"];
75 | name = [name stringByReplacingOccurrencesOfString:@" won t" withString:@" won't"];
76 | name = [name stringByReplacingOccurrencesOfString:@" don t" withString:@" don't"];
77 | name = [name stringByReplacingOccurrencesOfString:@" doesn t" withString:@" doesn't"];
78 | name = [name stringByReplacingOccurrencesOfString:@" shouldn t" withString:@" shouldn't"];
79 | name = [name stringByReplacingOccurrencesOfString:@" can t" withString:@" can't"];
80 |
81 | // So we take the 2nd char and move it to be the first
82 | NSString *firstCharacterCaps = [[name substringWithRange:NSMakeRange(1, 1)] uppercaseString];
83 | name = [name stringByReplacingCharactersInRange:NSMakeRange(0,2) withString:firstCharacterCaps];
84 | testCase.name = name;
85 | return testCase;
86 | }
87 |
88 | return nil;
89 | }
90 |
91 | - (void)addCommand:(ORKaleidoscopeCommand *)command
92 | {
93 | [self.commands addObject:command];
94 | command.testCase = self;
95 | }
96 |
97 | - (void)addSnapshot:(ORSnapshotCreationReference *)snapshot
98 | {
99 | [self.snapshots addObject:snapshot];
100 | snapshot.testCase = self;
101 | }
102 |
103 | - (ORKaleidoscopeCommand *)latestCommand
104 | {
105 | return self.commands.lastObject;
106 | }
107 |
108 | - (BOOL)hasFailingTests
109 | {
110 | return self.uniqueDiffCommands.count > 0;
111 | }
112 |
113 | - (NSArray *)uniqueDiffCommands
114 | {
115 | NSOrderedSet *commands = [NSOrderedSet orderedSetWithArray: [self.commands filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ORKaleidoscopeCommand *command, NSDictionary *bindings) {
116 | return command.fails;
117 | }]]];
118 |
119 | if (commands.count == 1) return commands.array;
120 |
121 | return [commands.array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ORKaleidoscopeCommand *command, NSDictionary *bindings) {
122 | return [[NSFileManager defaultManager] contentsEqualAtPath:command.afterPath andPath:command.beforePath] == NO;
123 | }]];
124 | }
125 |
126 |
127 | @end
128 |
129 | @implementation ORKaleidoscopeCommand
130 |
131 | + (instancetype)commandFromString:(NSString *)command
132 | {
133 | NSArray *components = [command componentsSeparatedByString:@"\""];
134 | if(components.count > 4){
135 | ORKaleidoscopeCommand *obj = [[self alloc] init];
136 | obj.fullCommand = command;
137 | obj.beforePath = components[1];
138 | obj.afterPath = components[3];
139 | return obj;
140 | }
141 | return nil;
142 | }
143 |
144 | - (NSURL *)beforeURL
145 | {
146 | return [NSURL fileURLWithPath:self.beforePath];
147 | }
148 |
149 | - (NSURL *)afterURL
150 | {
151 | return [NSURL fileURLWithPath:self.afterPath];
152 | }
153 |
154 | - (BOOL)isEqual:(ORKaleidoscopeCommand *)anObject
155 | {
156 | return [self.beforePath isEqual:anObject.beforePath] && [self.afterPath isEqual:anObject.afterPath] && self.fails == anObject.fails;
157 | }
158 |
159 | - (NSUInteger)hash
160 | {
161 | return [self.beforePath stringByAppendingString:self.afterPath].hash;
162 | }
163 |
164 | - (void)launch
165 | {
166 | NSTask *task = [[NSTask alloc] init];
167 | if ([ORKaleidoscopeController isInstalled]) {
168 | [task setLaunchPath: @"/usr/local/bin/ksdiff"];
169 | }else{
170 | [task setLaunchPath: @"/usr/bin/open"];
171 | }
172 | NSArray *arguments = @[ self.beforePath, self.afterPath];
173 | [task setArguments: arguments];
174 | [task launch];
175 | }
176 |
177 | - (void)swapImages
178 | {
179 | NSError *error = nil;
180 |
181 | NSArray *components = [self.beforeURL pathComponents];
182 | NSString *name = [components.lastObject stringByReplacingOccurrencesOfString:@"reference_" withString:@""];
183 | NSString *folder = components[components.count -2];
184 |
185 | NSString *originalReference = [[NSFileManager defaultManager] or_findFileWithNamePrefix:name inFolder:folder];
186 | originalReference = [originalReference stringByReplacingOccurrencesOfString:@"file://" withString:@""];
187 | originalReference = [originalReference stringByReplacingOccurrencesOfString:@"%20" withString:@" "];
188 | NSURL *originalFileURL = [NSURL fileURLWithPath:originalReference];
189 |
190 | if (![[NSFileManager defaultManager] removeItemAtURL:originalFileURL error:&error]) {
191 | NSLog(@"Error deleting before %@", error);
192 | }
193 |
194 |
195 | if (![[NSFileManager defaultManager] copyItemAtURL:[self afterURL] toURL:originalFileURL error:&error]) {
196 | NSLog(@"Error moving before to after %@", error);
197 | }
198 | }
199 |
200 | - (void)openInFinder
201 | {
202 | [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[ self.beforeURL ]];
203 | }
204 |
205 | - (void)openInPreview
206 | {
207 | NSString *lastPathComponent = [self.beforePath lastPathComponent];
208 | NSRange underscoreRange = [lastPathComponent rangeOfString:@"_"];
209 | NSString *diffFilename = [lastPathComponent stringByReplacingCharactersInRange:NSMakeRange(0, underscoreRange.location) withString:@"diff"];
210 | NSString *diffPath = [self.beforePath stringByReplacingOccurrencesOfString:lastPathComponent withString:diffFilename];
211 | [[NSWorkspace sharedWorkspace] openFile:diffPath withApplication:@"Preview"];
212 | }
213 |
214 | @end
215 |
216 |
217 | @implementation ORSnapshotCreationReference
218 |
219 | + (instancetype)referenceFromString:(NSString *)line
220 | {
221 | // 2014-06-16 11:34:57.579 ArtsyFolio[45418:60b] /Users/orta/dev/ios/energy/ArtsyFolio Tests/ARAdminPartnerSelectViewControllerTests.m:40 snapshot looks_right_on_phone successfully recorded, replace recordSnapshot with a check
222 |
223 | // 2014-07-28 14:17:39.979 FolioDev[15613:607] /Users/orta/spiel/ios/energy/ArtsyFolio Tests/ARExpectaExtensions.m:18 snapshot default state as ipad dark successfully recorded, replace recordSnapshot with a check
224 |
225 | // /Users/orta/dev/ios/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidHistoryViewControllerTests.swift:28: error: -[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21] : failed - , got snapshot nil successfully recorded, replace recordSnapshot with a check
226 |
227 | NSArray *components = [line componentsSeparatedByString:@"snapshot "];
228 | NSArray *endComponents = [line componentsSeparatedByString:@" successfully recorded, replace recordSnapshot with a check"];
229 |
230 | if (components.count == 2 && endComponents.count == 2) {
231 |
232 | ORSnapshotCreationReference *obj = [[self alloc] init];
233 | obj.name = [endComponents.firstObject componentsSeparatedByString:@"snapshot "].lastObject;
234 | return obj;
235 | }
236 | return nil;
237 | }
238 |
239 |
240 | - (BOOL)isEqual:(ORSnapshotCreationReference *)anObject
241 | {
242 | return [self.path isEqual:anObject.path];
243 | }
244 |
245 | - (NSUInteger)hash
246 | {
247 | return self.path.hash;
248 | }
249 |
250 |
251 | @end
--------------------------------------------------------------------------------
/Snapshots/SnapshotsViewController.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import PXSourceList
3 | import Interstellar
4 | import FileKit
5 |
6 | class SnapshotsViewController: NSViewController {
7 |
8 | let dev = DeveloperDirWatcher()
9 |
10 | @IBOutlet var sourceListDelegate: SourceListController!
11 | @IBOutlet var appsDataSource: SourceListDataSource!
12 | @IBOutlet var logsDataSource: SnapshotLogDataSource!
13 |
14 | @IBOutlet weak var sourceList: PXSourceList!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | dev.startParsing()
20 |
21 | dev.appsWithMetadataUpdatedSignal.next { names in
22 | self.appsDataSource.updateNames(names)
23 | self.sourceList.reloadData()
24 | }
25 |
26 | sourceListDelegate.appSelected.next { app in
27 | self.dev.getLogsForApp(app.name).next { paths in
28 | app.logs = paths.map { Log(path: $0) }
29 |
30 | self.logsDataSource.logsForSelectedApp = app.logs
31 | app.readLogs()
32 | }
33 | }
34 |
35 | logsDataSource.logSelected.next { log in
36 | let s = self.snapshotsPreviewController
37 | s.newLogSelected.update(log)
38 | }
39 | }
40 |
41 | @IBAction func reloadAppsForSnapshots(sender: AnyObject) {
42 | dev.startParsing()
43 | }
44 |
45 | var splitController: NSSplitViewController {
46 | return childViewControllers.filter { $0.isKindOfClass(NSSplitViewController) }.first! as! NSSplitViewController
47 | }
48 |
49 |
50 | var snapshotsPreviewController: LogSnapshotsPreviewViewController {
51 | return splitController.childViewControllers.filter { $0.isKindOfClass(LogSnapshotsPreviewViewController) }.first! as! LogSnapshotsPreviewViewController
52 | }
53 | }
54 |
55 | class SnapshotLogController: NSObject {
56 | let reader = ORLogReader()
57 | }
58 |
59 | class SnapshotLogDataSource: NSObject {
60 | dynamic var logsForSelectedApp = [Log]()
61 |
62 | let logSelected = Signal()
63 |
64 | @IBOutlet weak var logsTableView: NSTableView!
65 |
66 | override func awakeFromNib() {
67 | NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(selectionChanged), name: NSTableViewSelectionDidChangeNotification, object: logsTableView)
68 | }
69 |
70 | deinit {
71 | NSNotificationCenter.defaultCenter().removeObserver(self)
72 | }
73 |
74 | func selectionChanged(notification: NSNotification) {
75 | guard let table = notification.object as? NSTableView else { return }
76 | if table.selectedRow >= 0 {
77 | logSelected.update(logsForSelectedApp[table.selectedRow])
78 | }
79 | }
80 | }
81 |
82 | class SourceListController: NSObject, PXSourceListDelegate {
83 |
84 | let appSelected = Signal()
85 |
86 | func sourceList(aSourceList: PXSourceList!, isGroupAlwaysExpanded group: AnyObject!) -> Bool {
87 | return true
88 | }
89 |
90 | func sourceList(sourceList: PXSourceList!, viewForItem item: AnyObject!) -> NSView! {
91 | guard let item = item as? PXSourceListItem else { return NSView() }
92 |
93 | let identifier = sourceList.levelForItem(item) == 0 ? "HeaderCell" : "MainCell"
94 | guard let cellView = sourceList.makeViewWithIdentifier(identifier, owner: nil) as? PXSourceListTableCellView else { return NSView() }
95 |
96 | guard let app = item.representedObject as? App else {
97 | // Must be a header
98 | cellView.textField?.stringValue = item.title
99 | return cellView
100 | }
101 |
102 | cellView.textField?.stringValue = app.prettyName
103 | return cellView;
104 | }
105 |
106 | func sourceListSelectionDidChange(notification: NSNotification!) {
107 | let sourceList = notification.object as! PXSourceList
108 | guard let newSelectedItem = sourceList.itemAtRow(sourceList.selectedRow) as? PXSourceListItem else { return }
109 | guard let app = newSelectedItem.representedObject as? App else { return }
110 |
111 | appSelected.update(app)
112 | }
113 | }
114 |
115 | class SourceListDataSource: NSObject, PXSourceListDataSource {
116 |
117 | var snapshots = PXSourceListItem(title: "Snapshots", identifier: "root")
118 |
119 | var sourceListItems = [PXSourceListItem]()
120 |
121 | var rootNodes: [PXSourceListItem] {
122 | return [snapshots]
123 | }
124 |
125 | func updateNames(apps: [App]) {
126 | snapshots.removeChildItems(snapshots.children)
127 | let useful:[PXSourceListItem] = apps.filter { $0.logs.isEmpty == false }.map {
128 | return PXSourceListItem(representedObject: $0, icon:nil)
129 | }
130 | snapshots.children = useful
131 | }
132 |
133 | func sourceList(aSourceList: PXSourceList!, child index: UInt, ofItem item: AnyObject!) -> AnyObject! {
134 | if item == nil { return rootNodes[Int(index)] }
135 | guard let item = item as? PXSourceListItem else { return nil }
136 | return item.children[Int(index)]
137 | }
138 |
139 | func sourceList(sourceList: PXSourceList!, numberOfChildrenOfItem item: AnyObject!) -> UInt {
140 | if item == nil { return UInt(rootNodes.count) }
141 | guard let item = item as? PXSourceListItem else { return 0 }
142 | return UInt(item.children.count)
143 | }
144 |
145 | func sourceList(aSourceList: PXSourceList!, isItemExpandable item: AnyObject!) -> Bool {
146 | guard let item = item as? PXSourceListItem else { return false }
147 | return item.hasChildren()
148 | }
149 |
150 | func sourceList(aSourceList: PXSourceList!, objectValueForItem item: AnyObject!) -> AnyObject! {
151 | return NSObject()
152 | }
153 | }
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/Snapshots/ViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | import Cocoa
3 |
4 | class ViewController: NSViewController {
5 |
6 | override func viewDidLoad() {
7 | super.viewDidLoad()
8 |
9 | // Do any additional setup after loading the view.
10 | }
11 |
12 | override var representedObject: AnyObject? {
13 | didSet {
14 | // Update the view, if already loaded.
15 | }
16 | }
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/SnapshotsTests/DeveloperDirWatcherSpecs.swift:
--------------------------------------------------------------------------------
1 | import Quick
2 | import Nimble
3 |
4 | class DeveloperDirWatcherSpecs: QuickSpec {
5 | override func spec() {
6 |
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/SnapshotsTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SnapshotsTests/LogReaderSpecs.swift:
--------------------------------------------------------------------------------
1 | import Quick
2 | import Nimble
3 | import Cocoa
4 |
5 | @testable import Snapshots
6 |
7 | class LogReaderSpecs: QuickSpec {
8 |
9 | func getLog(named: String) -> String {
10 | let bundle = NSBundle(forClass: LogReaderSpecs.self)
11 | let logPath = bundle.pathForResource(named, ofType:".log")!
12 | return try! NSString(contentsOfFile: logPath, encoding: NSUTF8StringEncoding) as String
13 | }
14 |
15 | override func spec() {
16 | it("gives an expected amout of tests") {
17 | let log = self.getLog("MultipleSnapshotsErrors")
18 | let reader = ORLogReader()
19 | reader.readLog(log)
20 |
21 | expect(reader.hasSnapshotTestErrors()) == true
22 | expect(reader.hasNewSnapshots()) == false
23 |
24 | expect(reader.ksdiffCommands().count) == 8
25 | expect(reader.uniqueDiffCommands().count) == 8
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/SnapshotsTests/MultipleSnapshotsErrors.log:
--------------------------------------------------------------------------------
1 |
2 | Test Suite 'ARTopViewControllerSpec' started at 2015-04-22 15:52:50 +0000
3 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_as_ipad]' started.
4 | 2015-04-22 11:52:50.063 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
5 | 2015-04-22 11:52:50.301 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
6 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_default state as ipad dark@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_default state as ipad dark@2x.png"
7 | 2015-04-22 11:52:50.301 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:44 expected a matching snapshot named default state as ipad dark
8 | NSLocalizedDescription: Images different
9 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:44: error: -[ARTopViewControllerSpec test_visuals__default_state_as_ipad] : expected a matching snapshot named default state as ipad dark
10 | NSLocalizedDescription: Images different
11 | 2015-04-22 11:52:50.305 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
12 | 2015-04-22 11:52:50.541 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
13 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_default state as ipad light@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_default state as ipad light@2x.png"
14 | 2015-04-22 11:52:50.542 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:44 expected a matching snapshot named default state as ipad light
15 | NSLocalizedDescription: Images different
16 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:44: error: -[ARTopViewControllerSpec test_visuals__default_state_as_ipad] : expected a matching snapshot named default state as ipad light
17 | NSLocalizedDescription: Images different
18 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_as_ipad]' failed (0.496 seconds).
19 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_as_iphone]' started.
20 | 2015-04-22 11:52:50.559 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
21 | 2015-04-22 11:52:50.584 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
22 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_as_iphone]' passed (0.059 seconds).
23 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_ipad]' started.
24 | 2015-04-22 11:52:50.620 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
25 | 2015-04-22 11:52:50.853 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
26 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_default state for collector folio as ipad dark@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_default state for collector folio as ipad dark@2x.png"
27 | 2015-04-22 11:52:50.853 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:50 expected a matching snapshot named default state for collector folio as ipad dark
28 | NSLocalizedDescription: Images different
29 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:50: error: -[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_ipad] : expected a matching snapshot named default state for collector folio as ipad dark
30 | NSLocalizedDescription: Images different
31 | 2015-04-22 11:52:50.857 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
32 | 2015-04-22 11:52:51.091 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
33 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_default state for collector folio as ipad light@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_default state for collector folio as ipad light@2x.png"
34 | 2015-04-22 11:52:51.092 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:50 expected a matching snapshot named default state for collector folio as ipad light
35 | NSLocalizedDescription: Images different
36 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:50: error: -[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_ipad] : expected a matching snapshot named default state for collector folio as ipad light
37 | NSLocalizedDescription: Images different
38 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_ipad]' failed (0.491 seconds).
39 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_iphone]' started.
40 | 2015-04-22 11:52:51.110 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
41 | 2015-04-22 11:52:51.133 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
42 | Test Case '-[ARTopViewControllerSpec test_visuals__default_state_for_collector_folio_as_iphone]' passed (0.059 seconds).
43 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_ipad]' started.
44 | 2015-04-22 11:52:51.168 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
45 | 2015-04-22 11:52:51.409 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
46 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_showing edit in albums mode as ipad dark@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_showing edit in albums mode as ipad dark@2x.png"
47 | 2015-04-22 11:52:51.409 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:58 expected a matching snapshot named showing edit in albums mode as ipad dark
48 | NSLocalizedDescription: Images different
49 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:58: error: -[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_ipad] : expected a matching snapshot named showing edit in albums mode as ipad dark
50 | NSLocalizedDescription: Images different
51 | 2015-04-22 11:52:51.413 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
52 | 2015-04-22 11:52:51.654 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
53 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_showing edit in albums mode as ipad light@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_showing edit in albums mode as ipad light@2x.png"
54 | 2015-04-22 11:52:51.654 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:58 expected a matching snapshot named showing edit in albums mode as ipad light
55 | NSLocalizedDescription: Images different
56 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:58: error: -[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_ipad] : expected a matching snapshot named showing edit in albums mode as ipad light
57 | NSLocalizedDescription: Images different
58 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_ipad]' failed (0.504 seconds).
59 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_iphone]' started.
60 | 2015-04-22 11:52:51.673 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
61 | 2015-04-22 11:52:51.697 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
62 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_in_albums_mode_as_iphone]' passed (0.062 seconds).
63 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_mode_for_albums_as_ipad]' started.
64 | 2015-04-22 11:52:51.750 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
65 | 2015-04-22 11:52:51.982 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
66 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_showing edit mode for albums as ipad dark@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_showing edit mode for albums as ipad dark@2x.png"
67 | 2015-04-22 11:52:51.982 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:66 expected a matching snapshot named showing edit mode for albums as ipad dark
68 | NSLocalizedDescription: Images different
69 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:66: error: -[ARTopViewControllerSpec test_visuals__showing_edit_mode_for_albums_as_ipad] : expected a matching snapshot named showing edit mode for albums as ipad dark
70 | NSLocalizedDescription: Images different
71 | 2015-04-22 11:52:52.001 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
72 | 2015-04-22 11:52:52.232 FolioDev[15845:607] If you have Kaleidoscope installed you can run this command to see an image diff:
73 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/reference_showing edit mode for albums as ipad light@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/91CEFD41-40FA-4240-B239-B68D3BB54333/data/Applications/6B54B9B7-81C1-402A-9016-806EBC3A6D84/tmp/ARTopViewControllerSpec/failed_showing edit mode for albums as ipad light@2x.png"
74 | 2015-04-22 11:52:52.232 FolioDev[15845:607] /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:66 expected a matching snapshot named showing edit mode for albums as ipad light
75 | NSLocalizedDescription: Images different
76 | /Users/orta/dev/ios/energy/ArtsyFolio Tests/View Controllers/ARTopViewControllerTests.m:66: error: -[ARTopViewControllerSpec test_visuals__showing_edit_mode_for_albums_as_ipad] : expected a matching snapshot named showing edit mode for albums as ipad light
77 | NSLocalizedDescription: Images different
78 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_mode_for_albums_as_ipad]' failed (0.517 seconds).
79 | Test Case '-[ARTopViewControllerSpec test_visuals__showing_edit_mode_for_albums_as_iphone]' started.
80 | 2015-04-22 11:52:52.261 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
81 | 2015-04-22 11:52:52.290 FolioDev[15845:607] -[WYPopoverController positionPopover:] (2541) : popoverContainerView.frame = {{0, 0}, {0, 0}}
82 |
--------------------------------------------------------------------------------
/SnapshotsTests/NewSnapshotsRecorded.log:
--------------------------------------------------------------------------------
1 | (void *) $0 = 0x00007ff56360c1e0
2 | (void *) $1 = 0x0000000000000000
3 | (void *) $2 = 0x0000000000000000
4 | 2016-04-07 13:11:12.276 Artsy[48558:11314806] INFO: Reveal Server started (Protocol Version 25).
5 | 2016-04-07 13:11:12.302 Artsy[48558:11314806] iRate did not prompt for rating because the user has already rated this version
6 | 2016-04-07 13:11:12.302 Artsy[48558:11316006] iRate is checking http://itunes.apple.com/US/lookup?bundleId=net.artsy.artsy to retrieve the App Store details...
7 | 13:11:12.424 Artsy[48558:11316013] _XCT_testBundleReadyWithProtocolVersion:minimumVersion: reply received
8 | 13:11:12.424 Artsy[48558:11315788] _IDE_startExecutingTestPlanWithProtocolVersion:16
9 | Pending: looks good by default
10 | Test Suite 'Selected tests' started at 2016-04-07 13:11:12.887
11 | Test Suite 'Artsy Tests.xctest' started at 2016-04-07 13:11:12.888
12 | Test Suite 'LiveAuctionBidButtonTests' started at 2016-04-07 13:11:12.888
13 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_upcoming]' started.
14 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_upcoming]' passed (0.017 seconds).
15 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_sold]' started.
16 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_sold]' passed (0.006 seconds).
17 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_failed]' started.
18 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_failed]' passed (0.005 seconds).
19 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_closed]' started.
20 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_closed]' passed (0.005 seconds).
21 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_waiting]' started.
22 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_waiting]' passed (0.006 seconds).
23 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_trial]' started.
24 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_trial]' passed (0.009 seconds).
25 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_biddable]' started.
26 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_biddable]' passed (0.005 seconds).
27 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_max_bidder]' started.
28 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_max_bidder]' passed (0.007 seconds).
29 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_not_max_bidder]' started.
30 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_not_max_bidder]' passed (0.005 seconds).
31 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_in_progress]' started.
32 | Test Case '-[Artsy_Tests.LiveAuctionBidButtonTests has_valid_snapshot_in_progress]' passed (0.005 seconds).
33 | Test Suite 'LiveAuctionBidButtonTests' passed at 2016-04-07 13:11:12.965.
34 | Executed 10 tests, with 0 failures (0 unexpected) in 0.071 (0.077) seconds
35 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' started at 2016-04-07 13:11:12.965
36 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open]' started.
37 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open]' passed (0.021 seconds).
38 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_closed]' started.
39 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_closed]' passed (0.006 seconds).
40 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_bid]' started.
41 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_bid]' passed (0.008 seconds).
42 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_final_call]' started.
43 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_final_call]' passed (0.007 seconds).
44 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_fair_warning]' started.
45 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_fair_warning]' passed (0.009 seconds).
46 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' passed at 2016-04-07 13:11:13.020.
47 | Executed 5 tests, with 0 failures (0 unexpected) in 0.052 (0.055) seconds
48 | Test Suite 'LiveAuctionBidViewControllerSpecs' started at 2016-04-07 13:11:13.021
49 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs looks_right_on_phones]' started.
50 |
51 |
52 | 2016-04-07 13:13:00.073 Artsy[48558:11315966] CFNetwork SSLHandshake failed (-9806)
53 |
54 |
55 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs looks_right_on_phones]' passed (111.855 seconds).
56 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs updating__updates_when_new_events_come_in]' started.
57 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs updating__updates_when_new_events_come_in]' passed (0.013 seconds).
58 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs updating__ensures_the_bid_is_moved_above_the_current_max_bid]' started.
59 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs updating__ensures_the_bid_is_moved_above_the_current_max_bid]' passed (0.014 seconds).
60 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_network_issues]' started.
61 | 2016-04-07 13:13:04.945 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_network_issues@2x.png
62 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_network_issues] : , got snapshot networking__has_valid_snapshot_network_issues successfully recorded, replace recordSnapshot with a check
63 |
64 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_network_issues]' failed (0.043 seconds).
65 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_waiting]' started.
66 | 2016-04-07 13:13:04.982 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_waiting@2x.png
67 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_waiting] : , got snapshot networking__has_valid_snapshot_waiting successfully recorded, replace recordSnapshot with a check
68 |
69 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_waiting]' failed (0.038 seconds).
70 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_sold]' started.
71 | 2016-04-07 13:13:05.019 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_sold@2x.png
72 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_sold] : , got snapshot networking__has_valid_snapshot_sold successfully recorded, replace recordSnapshot with a check
73 |
74 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_sold]' failed (0.050 seconds).
75 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_not_max_bidder]' started.
76 | 2016-04-07 13:13:05.065 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_not_max_bidder@2x.png
77 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_not_max_bidder] : , got snapshot networking__has_valid_snapshot_not_max_bidder successfully recorded, replace recordSnapshot with a check
78 |
79 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_not_max_bidder]' failed (0.036 seconds).
80 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_in_progress]' started.
81 | 2016-04-07 13:13:05.101 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_in_progress@2x.png
82 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_in_progress] : , got snapshot networking__has_valid_snapshot_in_progress successfully recorded, replace recordSnapshot with a check
83 |
84 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_in_progress]' failed (0.030 seconds).
85 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_is_max_bidder]' started.
86 | 2016-04-07 13:13:05.131 Artsy[48558:11314806] Reference image save at: /Users/orta/dev/ios/apps/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidViewControllerTests/networking__has_valid_snapshot_is_max_bidder@2x.png
87 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidViewControllerTests.swift:82: error: -[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_is_max_bidder] : , got snapshot networking__has_valid_snapshot_is_max_bidder successfully recorded, replace recordSnapshot with a check
88 |
89 | Test Case '-[Artsy_Tests.LiveAuctionBidViewControllerSpecs networking__has_valid_snapshot_is_max_bidder]' failed (0.034 seconds).
90 | Test Suite 'LiveAuctionBidViewControllerSpecs' failed at 2016-04-07 13:13:05.139.
91 | Executed 9 tests, with 6 failures (0 unexpected) in 112.112 (112.118) seconds
92 | Test Suite 'LiveAuctionLotViewControllerTests' started at 2016-04-07 13:13:05.139
93 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_closed_lots]' started.
94 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_closed_lots]' passed (0.061 seconds).
95 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_live_lots]' started.
96 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_live_lots]' passed (0.062 seconds).
97 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_upcoming_lots]' started.
98 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_upcoming_lots]' passed (0.068 seconds).
99 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__doesnt_show_a_live_auction_call_to_action_when_auction_is_closed]' started.
100 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__doesnt_show_a_live_auction_call_to_action_when_auction_is_closed]' passed (0.066 seconds).
101 | Test Suite 'LiveAuctionLotViewControllerTests' passed at 2016-04-07 13:13:05.402.
102 | Executed 4 tests, with 0 failures (0 unexpected) in 0.258 (0.263) seconds
103 | Test Suite 'LiveAuctionSocketCommunicatorSpec' started at 2016-04-07 13:13:05.402
104 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec configures_the_socket_with_the_correct_host]' started.
105 | Connected: []
106 | Authenticated: []
107 | Joining sale
108 | Listening for socket events.
109 | Updated auction state: []
110 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec configures_the_socket_with_the_correct_host]' passed (0.002 seconds).
111 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec connects_the_socket_on_initialization]' started.
112 | Connected: []
113 | Authenticated: []
114 | Joining sale
115 | Listening for socket events.
116 | Updated auction state: []
117 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec connects_the_socket_on_initialization]' passed (0.939 seconds).
118 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec disconnects_the_socket_when_deallocated]' started.
119 | Connected: []
120 | Authenticated: []
121 | Joining sale
122 | Listening for socket events.
123 | Updated auction state: []
124 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec disconnects_the_socket_when_deallocated]' passed (0.002 seconds).
125 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticates_the_socket_connection]' started.
126 | Connected: []
127 | Authenticated: []
128 | Joining sale
129 | Listening for socket events.
130 | Updated auction state: []
131 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticates_the_socket_connection]' passed (0.004 seconds).
132 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__joins_the_auction]' started.
133 | Connected: []
134 | Authenticated: []
135 | Joining sale
136 | Listening for socket events.
137 | Updated auction state: []
138 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__joins_the_auction]' passed (0.015 seconds).
139 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__listens_for_updated_auction_state]' started.
140 | Connected: []
141 | Authenticated: []
142 | Joining sale
143 | Listening for socket events.
144 | Updated auction state: []
145 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__listens_for_updated_auction_state]' passed (0.002 seconds).
146 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__sends_its_delegate_its_updated_auction_state]' started.
147 | Connected: []
148 | Authenticated: []
149 | Joining sale
150 | Listening for socket events.
151 | Updated auction state: []
152 | Updated auction state: [state!]
153 | Test Case '-[Artsy_Tests.LiveAuctionSocketCommunicatorSpec authenticated__sends_its_delegate_its_updated_auction_state]' passed (0.002 seconds).
154 | Test Suite 'LiveAuctionSocketCommunicatorSpec' passed at 2016-04-07 13:13:06.450.
155 | Executed 7 tests, with 0 failures (0 unexpected) in 0.965 (1.048) seconds
156 | Test Suite 'LiveAuctionStateFetcherSpec' started at 2016-04-07 13:13:06.450
157 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec configures_its_sale_ID_correctly]' started.
158 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec configures_its_sale_ID_correctly]' passed (0.002 seconds).
159 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec configures_its_host_correctly]' started.
160 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec configures_its_host_correctly]' passed (0.002 seconds).
161 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec fetches_the_sale_state]' started.
162 | Test Case '-[Artsy_Tests.LiveAuctionStateFetcherSpec fetches_the_sale_state]' passed (0.002 seconds).
163 | Test Suite 'LiveAuctionStateFetcherSpec' passed at 2016-04-07 13:13:06.459.
164 | Executed 3 tests, with 0 failures (0 unexpected) in 0.006 (0.008) seconds
165 | Test Suite 'LiveAuctionStateManagerSpec' started at 2016-04-07 13:13:06.459
166 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec sets_its_saleID_upon_initialization]' started.
167 |
168 |
169 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec sets_its_saleID_upon_initialization]' passed (0.024 seconds).
170 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec creates_an_appropriate_socket_communicator]' started.
171 |
172 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec creates_an_appropriate_socket_communicator]' passed (0.031 seconds).
173 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec sets_itself_as_the_socket_communicator_delegate]' started.
174 |
175 |
176 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec sets_itself_as_the_socket_communicator_delegate]' passed (2.607 seconds).
177 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec invokes_the_state_reconciler_when_new_snapshot_data_avaialble]' started.
178 |
179 |
180 |
181 | Test Case '-[Artsy_Tests.LiveAuctionStateManagerSpec invokes_the_state_reconciler_when_new_snapshot_data_avaialble]' passed (0.006 seconds).
182 | Test Suite 'LiveAuctionStateManagerSpec' passed at 2016-04-07 13:13:09.130.
183 | Executed 4 tests, with 0 failures (0 unexpected) in 2.668 (2.671) seconds
184 | Test Suite 'LiveAuctionStateReconcilerSpec' started at 2016-04-07 13:13:09.131
185 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_lots]' started.
186 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_lots]' passed (0.002 seconds).
187 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_is_no_sale]' started.
188 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_is_no_sale]' passed (0.002 seconds).
189 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_sale_s_lots]' started.
190 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_sale_s_lots]' passed (0.002 seconds).
191 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_is_no_current_lot_id]' started.
192 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_is_no_current_lot_id]' passed (0.002 seconds).
193 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_lot_events__list_is_empty_]' started.
194 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec doesn_t_do_anything_if_there_are_no_lot_events__list_is_empty_]' passed (0.003 seconds).
195 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec sends_fresh_lots_on_first_update]' started.
196 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec sends_fresh_lots_on_first_update]' passed (0.002 seconds).
197 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec sends_current_lot]' started.
198 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec sends_current_lot]' passed (0.003 seconds).
199 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec orders_lots_correctly]' started.
200 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec orders_lots_correctly]' passed (0.003 seconds).
201 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_lots]' started.
202 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_lots]' passed (0.003 seconds).
203 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_sale]' started.
204 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_sale]' passed (0.006 seconds).
205 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_current_lot_if_it_has_not_changed]' started.
206 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__does_not_send_current_lot_if_it_has_not_changed]' passed (0.006 seconds).
207 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_new_current_lot_when_the_lot_changes]' started.
208 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_new_current_lot_when_the_lot_changes]' passed (0.007 seconds).
209 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_new_events]' started.
210 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_new_events]' passed (0.004 seconds).
211 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__doesn_t_update_lot_view_model_with_events_that_aren_t_new]' started.
212 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__doesn_t_update_lot_view_model_with_events_that_aren_t_new]' passed (0.004 seconds).
213 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_online_asking_price]' started.
214 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_online_asking_price]' passed (0.004 seconds).
215 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_reserve_status]' started.
216 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__updates_lot_view_model_with_reserve_status]' passed (0.003 seconds).
217 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_lots_when_number_of_lots_change]' started.
218 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_lots_when_number_of_lots_change]' passed (0.005 seconds).
219 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_updated_sale_availability_if_changed]' started.
220 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__sends_updated_sale_availability_if_changed]' passed (0.006 seconds).
221 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__doesn_t_send_updated_sale_availability_if_not_changed]' started.
222 | Test Case '-[Artsy_Tests.LiveAuctionStateReconcilerSpec on_subsequent_state_update__doesn_t_send_updated_sale_availability_if_not_changed]' passed (0.006 seconds).
223 | Test Suite 'LiveAuctionStateReconcilerSpec' passed at 2016-04-07 13:13:09.356.
224 | Executed 19 tests, with 0 failures (0 unexpected) in 0.074 (0.225) seconds
225 | Test Suite 'LiveAuctionStaticDataFetcherSpec' started at 2016-04-07 13:13:09.356
226 | Test Case '-[Artsy_Tests.LiveAuctionStaticDataFetcherSpec configures_its_sale_ID_correctly]' started.
227 | Test Case '-[Artsy_Tests.LiveAuctionStaticDataFetcherSpec configures_its_sale_ID_correctly]' passed (0.002 seconds).
228 | Test Case '-[Artsy_Tests.LiveAuctionStaticDataFetcherSpec fetches_the_static_data]' started.
229 |
230 |
231 | /Users/orta/dev/ios/apps/eigen/Artsy_Tests/Networking_Tests/Live_Auctions/LiveAuctionStaticDataFetcherSpec.swift:34: error: -[Artsy_Tests.LiveAuctionStaticDataFetcherSpec fetches_the_static_data] : expected to equal <{id = "sale_id";}>, got (use beNil() to match nils)
232 |
233 | Test Case '-[Artsy_Tests.LiveAuctionStaticDataFetcherSpec fetches_the_static_data]' failed (0.037 seconds).
234 | Test Suite 'LiveAuctionStaticDataFetcherSpec' failed at 2016-04-07 13:13:09.396.
235 | Executed 2 tests, with 1 failure (0 unexpected) in 0.038 (0.040) seconds
236 | Test Suite 'Artsy Tests.xctest' failed at 2016-04-07 13:13:09.397.
237 | Executed 63 tests, with 7 failures (0 unexpected) in 116.244 (116.509) seconds
238 | Test Suite 'Quick.framework' started at 2016-04-07 13:13:09.398
239 | Test Suite 'Quick.framework' passed at 2016-04-07 13:13:09.398.
240 | Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds
241 | Test Suite 'Specta.framework' started at 2016-04-07 13:13:09.399
242 | Test Suite 'Specta.framework' passed at 2016-04-07 13:13:09.399.
243 | Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds
244 | Test Suite 'FBSnapshotTestCase.framework' started at 2016-04-07 13:13:09.400
245 | Test Suite 'FBSnapshotTestCase.framework' passed at 2016-04-07 13:13:09.456.
246 | Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.056) seconds
247 | Test Suite 'Selected tests' failed at 2016-04-07 13:13:09.456.
248 | Executed 63 tests, with 7 failures (0 unexpected) in 116.244 (116.570) seconds
249 |
250 |
251 | Test session log:
252 | /Users/orta/Library/Developer/Xcode/DerivedData/Artsy-exhciswyomputsenvihzexoyuznk/Logs/Test/74FDAD03-6F93-498B-83D5-6CA91F36DF6E/Session-2016-04-07_13:09:10-pJRMDc.log
253 |
254 |
--------------------------------------------------------------------------------
/SnapshotsTests/QuickJustNewSnapshot.log:
--------------------------------------------------------------------------------
1 |
2 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' started at 2016-03-09 21:44:01.331
3 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21]' started.
4 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
5 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
6 | Mar 9 21:44:01 Artsy[9174] : CGContextSetBlendMode: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
7 | Mar 9 21:44:01 Artsy[9174] : CGContextSetAlpha: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
8 | Mar 9 21:44:01 Artsy[9174] : CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
9 | Mar 9 21:44:01 Artsy[9174] : CGContextScaleCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
10 | Mar 9 21:44:01 Artsy[9174] : CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
11 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
12 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
13 | 2016-03-09 21:44:01.347 Artsy[9174:24386969] Reference image save at: /Users/orta/dev/ios/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidHistoryViewControllerTests/cells__looks_right_for_open@2x.png
14 | /Users/orta/dev/ios/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidHistoryViewControllerTests.swift:28: error: -[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21] : failed - , got snapshot nil successfully recorded, replace recordSnapshot with a check
15 |
16 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21]' failed (0.025 seconds).
17 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' failed at 2016-03-09 21:44:01.357.
18 | Executed 1 test, with 1 failure (0 unexpected) in 0.025 (0.026) seconds
19 |
--------------------------------------------------------------------------------
/SnapshotsTests/QuickNewSnapshot.log:
--------------------------------------------------------------------------------
1 | Test Suite 'LiveAuctionLotViewControllerTests' started at 2016-03-09 21:44:01.358
2 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_closed_lots_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionLotViewControllerTestsswift_21]' started.
3 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
4 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
5 | Mar 9 21:44:01 Artsy[9174] : CGContextSetBlendMode: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
6 | Mar 9 21:44:01 Artsy[9174] : CGContextSetAlpha: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
7 | Mar 9 21:44:01 Artsy[9174] : CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
8 | Mar 9 21:44:01 Artsy[9174] : CGContextScaleCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
9 | Mar 9 21:44:01 Artsy[9174] : CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
10 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
11 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
12 | 2016-03-09 21:44:01.471 Artsy[9174:24386969] If you have Kaleidoscope installed you can run this command to see an image diff:
13 | ksdiff "/Users/orta/Library/Developer/CoreSimulator/Devices/D86744A5-08C8-459F-B77A-8EFC7E4DF3ED/data/Containers/Data/Application/4F5FFF12-C55E-4C7E-8EDE-0E65713AE95F/tmp/LiveAuctionLotViewControllerTests/reference_snapshots__looks_good_for_closed_lots@2x.png" "/Users/orta/Library/Developer/CoreSimulator/Devices/D86744A5-08C8-459F-B77A-8EFC7E4DF3ED/data/Containers/Data/Application/4F5FFF12-C55E-4C7E-8EDE-0E65713AE95F/tmp/LiveAuctionLotViewControllerTests/failed_snapshots__looks_good_for_closed_lots@2x.png"
14 | /Users/orta/dev/ios/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionLotViewControllerTests.swift:25: error: -[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_closed_lots_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionLotViewControllerTestsswift_21] : failed - , got expected a matching snapshot
15 |
16 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_closed_lots_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionLotViewControllerTestsswift_21]' failed (0.116 seconds).
17 | Test Case '-[Artsy_Tests.LiveAuctionLotViewControllerTests snapshots__looks_good_for_live_lots_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionLotViewControllerTestsswift_28]' started.
18 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
19 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
20 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' started at 2016-03-09 21:44:01.331
21 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21]' started.
22 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
23 | Mar 9 21:44:01 Artsy[9174] : CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
24 | Mar 9 21:44:01 Artsy[9174] : CGContextSetBlendMode: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
25 | Mar 9 21:44:01 Artsy[9174] : CGContextSetAlpha: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
26 | Mar 9 21:44:01 Artsy[9174] : CGContextTranslateCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
27 | Mar 9 21:44:01 Artsy[9174] : CGContextScaleCTM: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
28 | Mar 9 21:44:01 Artsy[9174] : CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
29 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
30 | Mar 9 21:44:01 Artsy[9174] : CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
31 | 2016-03-09 21:44:01.347 Artsy[9174:24386969] Reference image save at: /Users/orta/dev/ios/eigen/Artsy_Tests/ReferenceImages/LiveAuctionBidHistoryViewControllerTests/cells__looks_right_for_open@2x.png
32 | /Users/orta/dev/ios/eigen/Artsy_Tests/View_Controller_Tests/Live_Auction/LiveAuctionBidHistoryViewControllerTests.swift:28: error: -[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21] : failed - , got snapshot nil successfully recorded, replace recordSnapshot with a check
33 |
34 | Test Case '-[Artsy_Tests.LiveAuctionBidHistoryViewControllerTests cells__looks_right_for_open_UsersortadevioseigenArtsyTestsViewControllerTestsLiveAuctionLiveAuctionBidHistoryViewControllerTestsswift_21]' failed (0.025 seconds).
35 | Test Suite 'LiveAuctionBidHistoryViewControllerTests' failed at 2016-03-09 21:44:01.357.
36 | Executed 1 test, with 1 failure (0 unexpected) in 0.025 (0.026) seconds
37 |
--------------------------------------------------------------------------------
/design/Browse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orta/Snapshots-app/e09a2353ec44f9999d814a45d47c210222fdd51b/design/Browse.png
--------------------------------------------------------------------------------
/design/Run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orta/Snapshots-app/e09a2353ec44f9999d814a45d47c210222fdd51b/design/Run.png
--------------------------------------------------------------------------------
/design/snapshots-app-design.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orta/Snapshots-app/e09a2353ec44f9999d814a45d47c210222fdd51b/design/snapshots-app-design.sketch
--------------------------------------------------------------------------------