Introduce SnapshotView which wraps Renderable content and will verify the snapshot

Reviewed By: @javache

Differential Revision: D2493722
This commit is contained in:
Dave Miller 2015-10-02 12:13:48 -07:00 committed by facebook-github-bot-3
parent de736227fa
commit b8c42f7f6f
6 changed files with 128 additions and 11 deletions

View File

@ -19,11 +19,10 @@ var React = require('react-native');
var { var {
AppRegistry, AppRegistry,
Settings, Settings,
SnapshotView,
StyleSheet, StyleSheet,
} = React; } = React;
var { TestModule } = React.addons;
import type { NavigationContext } from 'NavigationContext'; import type { NavigationContext } from 'NavigationContext';
var UIExplorerListBase = require('./UIExplorerListBase'); var UIExplorerListBase = require('./UIExplorerListBase');
@ -83,17 +82,13 @@ var APIS = [
COMPONENTS.concat(APIS).forEach((Example) => { COMPONENTS.concat(APIS).forEach((Example) => {
if (Example.displayName) { if (Example.displayName) {
var Snapshotter = React.createClass({ var Snapshotter = React.createClass({
componentDidMount: function() {
// View is still blank after first RAF :\
global.requestAnimationFrame(() =>
global.requestAnimationFrame(() => TestModule.verifySnapshot(
TestModule.markTestPassed
)
));
},
render: function() { render: function() {
var Renderable = UIExplorerListBase.makeRenderable(Example); var Renderable = UIExplorerListBase.makeRenderable(Example);
return <Renderable />; return (
<SnapshotView>
<Renderable />
</SnapshotView>
);
}, },
}); });
AppRegistry.registerComponent(Example.displayName, () => Snapshotter); AppRegistry.registerComponent(Example.displayName, () => Snapshotter);

View File

@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-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 "RCTViewManager.h"
@interface RCTSnapshotManager : RCTViewManager
@end

View File

@ -0,0 +1,47 @@
/**
* Copyright (c) 2015-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 "RCTSnapshotManager.h"
@interface RCTSnapshotView : UIView
@property (nonatomic, copy) RCTDirectEventBlock onSnapshotReady;
@property (nonatomic, copy) NSString *testIdentifier;
@end
@implementation RCTSnapshotView
- (void)setTestIdentifier:(NSString *)testIdentifier
{
if (![_testIdentifier isEqualToString:testIdentifier]) {
_testIdentifier = [testIdentifier copy];
dispatch_async(dispatch_get_main_queue(), ^{
if (self.onSnapshotReady) {
self.onSnapshotReady(@{@"testIdentifier" : self.testIdentifier});
}
});
}
}
@end
@implementation RCTSnapshotManager
RCT_EXPORT_MODULE()
- (UIView *)view {
return [RCTSnapshotView new];
}
RCT_EXPORT_VIEW_PROPERTY(testIdentifier, NSString)
RCT_EXPORT_VIEW_PROPERTY(onSnapshotReady, RCTDirectEventBlock)
@end

View File

@ -13,6 +13,7 @@
58E64FED1AB964CD007446E2 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE71AB964CD007446E2 /* FBSnapshotTestController.m */; }; 58E64FED1AB964CD007446E2 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE71AB964CD007446E2 /* FBSnapshotTestController.m */; };
58E64FEE1AB964CD007446E2 /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE91AB964CD007446E2 /* UIImage+Compare.m */; }; 58E64FEE1AB964CD007446E2 /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FE91AB964CD007446E2 /* UIImage+Compare.m */; };
58E64FEF1AB964CD007446E2 /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FEB1AB964CD007446E2 /* UIImage+Diff.m */; }; 58E64FEF1AB964CD007446E2 /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 58E64FEB1AB964CD007446E2 /* UIImage+Diff.m */; };
9913A84B1BBE833400D70E66 /* RCTSnapshotManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9913A84A1BBE833400D70E66 /* RCTSnapshotManager.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -42,6 +43,8 @@
58E64FE91AB964CD007446E2 /* UIImage+Compare.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Compare.m"; sourceTree = "<group>"; }; 58E64FE91AB964CD007446E2 /* UIImage+Compare.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Compare.m"; sourceTree = "<group>"; };
58E64FEA1AB964CD007446E2 /* UIImage+Diff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Diff.h"; sourceTree = "<group>"; }; 58E64FEA1AB964CD007446E2 /* UIImage+Diff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Diff.h"; sourceTree = "<group>"; };
58E64FEB1AB964CD007446E2 /* UIImage+Diff.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Diff.m"; sourceTree = "<group>"; }; 58E64FEB1AB964CD007446E2 /* UIImage+Diff.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Diff.m"; sourceTree = "<group>"; };
9913A8491BBE833400D70E66 /* RCTSnapshotManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSnapshotManager.h; sourceTree = "<group>"; };
9913A84A1BBE833400D70E66 /* RCTSnapshotManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSnapshotManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -59,6 +62,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
58E64FE31AB964CD007446E2 /* FBSnapshotTestCase */, 58E64FE31AB964CD007446E2 /* FBSnapshotTestCase */,
9913A8491BBE833400D70E66 /* RCTSnapshotManager.h */,
9913A84A1BBE833400D70E66 /* RCTSnapshotManager.m */,
585135331AB3C56F00882537 /* RCTTestModule.h */, 585135331AB3C56F00882537 /* RCTTestModule.h */,
585135341AB3C56F00882537 /* RCTTestModule.m */, 585135341AB3C56F00882537 /* RCTTestModule.m */,
585135351AB3C56F00882537 /* RCTTestRunner.h */, 585135351AB3C56F00882537 /* RCTTestRunner.h */,
@ -149,6 +154,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
58E64FEE1AB964CD007446E2 /* UIImage+Compare.m in Sources */, 58E64FEE1AB964CD007446E2 /* UIImage+Compare.m in Sources */,
9913A84B1BBE833400D70E66 /* RCTSnapshotManager.m in Sources */,
585135371AB3C56F00882537 /* RCTTestModule.m in Sources */, 585135371AB3C56F00882537 /* RCTTestModule.m in Sources */,
58E64FEF1AB964CD007446E2 /* UIImage+Diff.m in Sources */, 58E64FEF1AB964CD007446E2 /* UIImage+Diff.m in Sources */,
58E64FED1AB964CD007446E2 /* FBSnapshotTestController.m in Sources */, 58E64FED1AB964CD007446E2 /* FBSnapshotTestController.m in Sources */,

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) 2015-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.
*
* @providesModule SnapshotView
* @flow
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var { TestModule } = require('NativeModules');
var requireNativeComponent = require('requireNativeComponent');
var SnapshotView = React.createClass({
onDefaultAction: function(event: Object) {
TestModule.verifySnapshot(TestModule.markTestPassed);
},
render: function() {
var testIdentifier = this.props.testIdentifier || 'test';
var onSnapshotReady = this.props.onSnapshotReady || this.onDefaultAction;
return (
<RCTSnapshot
style={style.snapshot}
{...this.props}
onSnapshotReady={onSnapshotReady}
testIdentifier={testIdentifier}
/>
);
},
propTypes: {
// A callback when the Snapshot view is ready to be compared
onSnapshotReady : React.PropTypes.func,
// A name to identify the individual instance to the SnapshotView
testIdentifier : React.PropTypes.string,
}
});
var style = StyleSheet.create({
snapshot: {
flex: 1,
},
});
var RCTSnapshot = requireNativeComponent('RCTSnapshot', SnapshotView);
module.exports = SnapshotView;

View File

@ -34,6 +34,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
ScrollView: require('ScrollView'), ScrollView: require('ScrollView'),
SegmentedControlIOS: require('SegmentedControlIOS'), SegmentedControlIOS: require('SegmentedControlIOS'),
SliderIOS: require('SliderIOS'), SliderIOS: require('SliderIOS'),
SnapshotView: require('SnapshotView'),
SwitchAndroid: require('SwitchAndroid'), SwitchAndroid: require('SwitchAndroid'),
SwitchIOS: require('SwitchIOS'), SwitchIOS: require('SwitchIOS'),
TabBarIOS: require('TabBarIOS'), TabBarIOS: require('TabBarIOS'),