diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index c0e7fd0173..021f2aaf63 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 055F1A3919ABD413004DAFF1 /* ASRangeController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */; }; 055F1A3C19ABD43F004DAFF1 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 055F1A3D19ABD43F004DAFF1 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */; }; + 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */; }; 0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 0574D5E119C110610097DC25 /* ASTableViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0587F9BD1A7309ED00AFF0BA /* ASEditableTextNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0587F9BE1A7309ED00AFF0BA /* ASEditableTextNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */; }; @@ -135,6 +136,7 @@ 058D0A84195D060300B7D73C /* ASDisplayNodeExtraIvars.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A45195D058D00B7D73C /* ASDisplayNodeExtraIvars.h */; settings = {ATTRIBUTES = (Public, ); }; }; 05A6D05A19D0EB64002DD95E /* ASDealloc2MainObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 05A6D05B19D0EB64002DD95E /* ASDealloc2MainObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */; }; 05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; }; 2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; }; @@ -210,6 +212,8 @@ 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeController.mm; sourceTree = ""; }; 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCellNode.h; sourceTree = ""; }; 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCellNode.m; sourceTree = ""; }; + 056D21501ABCEDA1001107EF /* ASSnapshotTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSnapshotTestCase.h; sourceTree = ""; }; + 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageNodeSnapshotTests.m; sourceTree = ""; }; 0574D5E119C110610097DC25 /* ASTableViewProtocols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTableViewProtocols.h; sourceTree = ""; }; 0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEditableTextNode.h; sourceTree = ""; }; 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEditableTextNode.mm; sourceTree = ""; }; @@ -295,6 +299,7 @@ 058D0A45195D058D00B7D73C /* ASDisplayNodeExtraIvars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeExtraIvars.h; sourceTree = ""; }; 05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASDealloc2MainObject.h; path = ../Details/ASDealloc2MainObject.h; sourceTree = ""; }; 05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASDealloc2MainObject.m; path = ../Details/ASDealloc2MainObject.m; sourceTree = ""; }; + 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASSnapshotTestCase.mm; sourceTree = ""; }; 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = ""; }; 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = ""; }; 2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = ""; }; @@ -443,6 +448,9 @@ 058D09C5195D04C000B7D73C /* AsyncDisplayKitTests */ = { isa = PBXGroup; children = ( + 056D21501ABCEDA1001107EF /* ASSnapshotTestCase.h */, + 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.mm */, + 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */, 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m */, 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */, 2911485B1A77147A005D0878 /* ASControlNodeTests.m */, @@ -865,6 +873,8 @@ 058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */, 058D0A3F195D057000B7D73C /* ASTextNodeShadowerTests.m in Sources */, 29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */, + 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */, + 05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.mm in Sources */, 058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */, 058D0A3A195D057000B7D73C /* ASDisplayNodeTests.m in Sources */, 052EE0661A159FEF002C6279 /* ASMultiplexImageNodeTests.m in Sources */, @@ -1014,6 +1024,8 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", + "COCOAPODS=1", + "FB_REFERENCE_IMAGE_DIR=\"\\\"$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages\\\"\"", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; @@ -1034,6 +1046,11 @@ ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AsyncDisplayKit/AsyncDisplayKit-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "FB_REFERENCE_IMAGE_DIR=\"\\\"$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages\\\"\"", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; INFOPLIST_FILE = "AsyncDisplayKitTests/AsyncDisplayKitTests-Info.plist"; diff --git a/AsyncDisplayKitTests/ASImageNodeSnapshotTests.m b/AsyncDisplayKitTests/ASImageNodeSnapshotTests.m new file mode 100644 index 0000000000..e5a48b5e5c --- /dev/null +++ b/AsyncDisplayKitTests/ASImageNodeSnapshotTests.m @@ -0,0 +1,35 @@ +/* Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "ASSnapshotTestCase.h" + +#import + +@interface ASImageNodeSnapshotTests : ASSnapshotTestCase +@end + +@implementation ASImageNodeSnapshotTests + +- (UIImage *)testImage +{ + NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"logo-square" + ofType:@"png" inDirectory:@"TestResources"]; + return [UIImage imageWithContentsOfFile:path]; +} + +- (void)testRenderLogoSquare +{ + // trivial test case to ensure ASSnapshotTestCase works + ASImageNode *imageNode = [[ASImageNode alloc] init]; + imageNode.image = [self testImage]; + imageNode.frame = CGRectMake(0, 0, 100, 100); + + ASSnapshotVerifyNode(imageNode, nil); +} + +@end diff --git a/AsyncDisplayKitTests/ASSnapshotTestCase.h b/AsyncDisplayKitTests/ASSnapshotTestCase.h new file mode 100644 index 0000000000..a523f57e03 --- /dev/null +++ b/AsyncDisplayKitTests/ASSnapshotTestCase.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "FBSnapshotTestCase.h" + +#import + +#define ASSnapshotVerifyNode(node__, identifier__) \ +{ \ + [ASSnapshotTestCase hackilySynchronouslyRecursivelyRenderNode:node__]; \ + FBSnapshotVerifyLayer(node__.layer, identifier__); \ +} + +@interface ASSnapshotTestCase : FBSnapshotTestCase + +/** + * Hack for testing. ASDisplayNode lacks an explicit -render method, so we manually hit its layout & display codepaths. + */ ++ (void)hackilySynchronouslyRecursivelyRenderNode:(ASDisplayNode *)node; + +@end diff --git a/AsyncDisplayKitTests/ASSnapshotTestCase.mm b/AsyncDisplayKitTests/ASSnapshotTestCase.mm new file mode 100644 index 0000000000..cce364ab34 --- /dev/null +++ b/AsyncDisplayKitTests/ASSnapshotTestCase.mm @@ -0,0 +1,54 @@ +/* Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "ASSnapshotTestCase.h" + +#import + +@implementation ASSnapshotTestCase + ++ (void)_layoutAndDisplayNode:(ASDisplayNode *)node +{ + if (![node __shouldLoadViewOrLayer]) { + return; + } + + CALayer *layer = node.layer; + + [layer setNeedsLayout]; + [layer layoutIfNeeded]; + + [layer setNeedsDisplay]; + [layer displayIfNeeded]; +} + ++ (void)_recursivelyLayoutAndDisplayNode:(ASDisplayNode *)node +{ + for (ASDisplayNode *subnode in node.subnodes) { + [self _recursivelyLayoutAndDisplayNode:subnode]; + } + + [self _layoutAndDisplayNode:node]; +} + ++ (void)_recursivelySetDisplaysAsynchronously:(BOOL)flag forNode:(ASDisplayNode *)node +{ + node.displaysAsynchronously = flag; + + for (ASDisplayNode *subnode in node.subnodes) { + subnode.displaysAsynchronously = flag; + } +} + ++ (void)hackilySynchronouslyRecursivelyRenderNode:(ASDisplayNode *)node +{ + [self _recursivelySetDisplaysAsynchronously:NO forNode:node]; + [self _recursivelyLayoutAndDisplayNode:node]; +} + +@end diff --git a/AsyncDisplayKitTests/ReferenceImages/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png b/AsyncDisplayKitTests/ReferenceImages/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png new file mode 100644 index 0000000000..896dc7abf0 Binary files /dev/null and b/AsyncDisplayKitTests/ReferenceImages/ASImageNodeSnapshotTests/testRenderLogoSquare@2x.png differ diff --git a/Podfile b/Podfile index cb95bcd97b..eb7cb4bb47 100644 --- a/Podfile +++ b/Podfile @@ -4,4 +4,5 @@ platform :ios, '7.0' target :'AsyncDisplayKitTests', :exclusive => true do pod 'OCMock', '~> 2.2' + pod 'FBSnapshotTestCase' end diff --git a/Podfile.lock b/Podfile.lock index acabe8b1c3..14f152df04 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,10 +1,13 @@ PODS: + - FBSnapshotTestCase (1.5) - OCMock (2.2.4) DEPENDENCIES: + - FBSnapshotTestCase - OCMock (~> 2.2) SPEC CHECKSUMS: + FBSnapshotTestCase: e2914fbaabccea1dcc773d6a16b1c24540642488 OCMock: 6db79185520e24f9f299548f2b8b07e41d881bd5 COCOAPODS: 0.35.0