Skip to content

Commit

Permalink
Port CatalystLoggingTestCase to iOS
Browse files Browse the repository at this point in the history
Reviewed By: nicklockwood

Differential Revision: D2658485

fb-gh-sync-id: e6803aefee69ee058651fc4c8c202619543f0cd2
  • Loading branch information
javache authored and facebook-github-bot-7 committed Nov 20, 2015
1 parent 7cd7591 commit 1a1c3f7
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 7 deletions.
109 changes: 109 additions & 0 deletions Examples/UIExplorer/UIExplorerIntegrationTests/RCTLoggingTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#import <XCTest/XCTest.h>

#import "RCTAssert.h"
#import "RCTLog.h"
#import "RCTBridge.h"

@interface RCTLoggingTests : XCTestCase

@end

@implementation RCTLoggingTests
{
RCTBridge *_bridge;

dispatch_semaphore_t _logSem;
RCTLogLevel _lastLogLevel;
RCTLogSource _lastLogSource;
NSString *_lastLogMessage;
}

- (void)setUp
{
#if RUNNING_ON_CI
NSURL *scriptURL = [[NSBundle bundleForClass:[RCTBridge class]] URLForResource:@"main" withExtension:@"jsbundle"];
RCTAssert(scriptURL != nil, @"Could not locate main.jsBundle");
#else
NSString *app = @"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp";
NSURL *scriptURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:8081/%@.bundle?platform=ios&dev=true", app]];
#endif

_bridge = [[RCTBridge alloc] initWithBundleURL:scriptURL moduleProvider:NULL launchOptions:nil];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:5];
while (date.timeIntervalSinceNow > 0 && _bridge.loading) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
XCTAssertFalse(_bridge.loading);

_logSem = dispatch_semaphore_create(0);
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (source == RCTLogSourceJavaScript) {
_lastLogLevel = level;
_lastLogSource = source;
_lastLogMessage = message;
dispatch_semaphore_signal(_logSem);
}
});
}

- (void)tearDown
{
[_bridge invalidate];
_bridge = nil;

RCTSetLogFunction(RCTDefaultLogFunction);
}

- (void)testLogging
{
[_bridge enqueueJSCall:@"LoggingTestModule.logToConsole" args:@[@"Invoking console.log"]];
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);

XCTAssertEqual(_lastLogLevel, RCTLogLevelInfo);
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
XCTAssertEqualObjects(_lastLogMessage, @"Invoking console.log");

[_bridge enqueueJSCall:@"LoggingTestModule.warning" args:@[@"Generating warning"]];
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);

XCTAssertEqual(_lastLogLevel, RCTLogLevelWarning);
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
XCTAssertEqualObjects(_lastLogMessage, @"Warning: Generating warning");

[_bridge enqueueJSCall:@"LoggingTestModule.invariant" args:@[@"Invariant failed"]];
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);

XCTAssertEqual(_lastLogLevel, RCTLogLevelError);
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
XCTAssertEqualObjects(_lastLogMessage, @"Invariant Violation: Invariant failed");

[_bridge enqueueJSCall:@"LoggingTestModule.logErrorToConsole" args:@[@"Invoking console.error"]];
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);

XCTAssertEqual(_lastLogLevel, RCTLogLevelError);
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
XCTAssertEqualObjects(_lastLogMessage, @"Invoking console.error");

[_bridge enqueueJSCall:@"LoggingTestModule.throwError" args:@[@"Throwing an error"]];
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);

XCTAssertEqual(_lastLogLevel, RCTLogLevelError);
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
XCTAssertEqualObjects(_lastLogMessage, @"Throwing an error");
}

@end
3 changes: 3 additions & 0 deletions IntegrationTests/IntegrationTestsApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ TESTS.forEach(
(test) => AppRegistry.registerComponent(test.displayName, () => test)
);

// Modules required for integration tests
require('LoggingTestModule');

var IntegrationTestsApp = React.createClass({
getInitialState: function() {
return {
Expand Down
32 changes: 32 additions & 0 deletions IntegrationTests/LoggingTestModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* 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 LoggingTestModule
*/
'use strict';

var warning = require('warning');
var invariant = require('invariant');

module.exports = {
logToConsole: function(str) {
console.log(str);
},
warning: function(str) {
warning(false, str);
},
invariant: function(str) {
invariant(false, str);
},
logErrorToConsole: function(str) {
console.error(str);
},
throwError: function(str) {
throw new Error(str);
}
};
20 changes: 13 additions & 7 deletions packager/react-packager/src/Resolver/polyfills/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@
};

function setupConsole(global) {

var originalConsole = global.console;

if (!global.nativeLoggingHook) {
Expand All @@ -375,16 +374,23 @@

function getNativeLogFunction(level) {
return function() {
var str = Array.prototype.map.call(arguments, function(arg) {
return inspect(arg, {depth: 10});
}).join(', ');
if (str.slice(0, 10) === "'Warning: " && level >= LOG_LEVELS.error) {
var str;
if (arguments.length === 1 && typeof arguments[0] === 'string') {
str = arguments[0];
} else {
str = Array.prototype.map.call(arguments, function(arg) {
return inspect(arg, {depth: 10});
}).join(', ');
}

var logLevel = level;
if (str.slice(0, 9) === 'Warning: ' && logLevel >= LOG_LEVELS.error) {
// React warnings use console.error so that a stack trace is shown,
// but we don't (currently) want these to show a redbox
// (Note: Logic duplicated in ExceptionsManager.js.)
level = LOG_LEVELS.warn;
logLevel = LOG_LEVELS.warn;
}
global.nativeLoggingHook(str, level);
global.nativeLoggingHook(str, logLevel);
};
}

Expand Down

0 comments on commit 1a1c3f7

Please sign in to comment.