From 5f77c835a8cb30f41b6ce23587b094cd5c0ddbfe Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Fri, 10 Nov 2017 11:08:45 +0100 Subject: [PATCH 01/17] Set up node environment so version macthes user's shell --- src/RealmJS.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index 95b39927..bdc01843 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -888,7 +888,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "node ../scripts/download-realm.js ios --sync"; + shellScript = "if [[ -s \"$HOME/.nvm/nvm.sh\" ]]; then\n . \"$HOME/.nvm/nvm.sh\"\n NVM_DIR=\"$HOME/.nvm\"\nelif [[ -x \"$(command -v brew)\" && -s \"$(brew --prefix nvm)/nvm.sh\" ]]; then\n . \"$(brew --prefix nvm)/nvm.sh\"\n NVM_DIR=\"$(brew --prefix)\"\nfi\nnode ../scripts/download-realm.js ios --sync"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ From c4e17844967f1eae6ea159dd8754f6ec5ef56d28 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Mon, 13 Nov 2017 12:44:08 +0100 Subject: [PATCH 02/17] Better handling of local environment --- src/RealmJS.xcodeproj/project.pbxproj | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index bdc01843..d29df039 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -887,9 +887,8 @@ outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [[ -s \"$HOME/.nvm/nvm.sh\" ]]; then\n . \"$HOME/.nvm/nvm.sh\"\n NVM_DIR=\"$HOME/.nvm\"\nelif [[ -x \"$(command -v brew)\" && -s \"$(brew --prefix nvm)/nvm.sh\" ]]; then\n . \"$(brew --prefix nvm)/nvm.sh\"\n NVM_DIR=\"$(brew --prefix)\"\nfi\nnode ../scripts/download-realm.js ios --sync"; - showEnvVarsInLog = 0; + shellPath = "/bin/sh"; + shellScript = "[ -z \"$NVM_DIR\" ] && export NVM_DIR=\"$HOME/.nvm\"\n\nif [[ -s \"$HOME/.nvm/nvm.sh\" ]]; then\n . \"$HOME/.nvm/nvm.sh\"\nelif [[ -x \"$(command -v brew)\" && -s \"$(brew --prefix nvm)/nvm.sh\" ]]; then\n . \"$(brew --prefix nvm)/nvm.sh\"\nfi\nnode ../scripts/download-realm.js ios --sync"; }; /* End PBXShellScriptBuildPhase section */ From cc515a6a6059126e389982163555b70b3ac1e6f6 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Wed, 15 Nov 2017 11:59:13 +0100 Subject: [PATCH 03/17] Updating to RN 0.50.3. --- scripts/test.sh | 4 ++-- tests/js/admin-user-helper.js | 3 ++- tests/js/index.js | 3 ++- tests/js/session-tests.js | 3 ++- .../react-test-app/ios/ReactTests.xcodeproj/project.pbxproj | 2 +- tests/react-test-app/package.json | 5 +++-- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index 0eea3e7d..766ed8bb 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -109,10 +109,10 @@ open_chrome() { start_packager() { watchman watch-del-all || true - ./node_modules/react-native/packager/packager.sh | tee "$PACKAGER_OUT" & + ./node_modules/react-native/scripts/packager.sh | tee "$PACKAGER_OUT" & while :; do - if grep -Fxq "React packager ready." "$PACKAGER_OUT"; then + if grep -Fxq "Metro Bundler ready." "$PACKAGER_OUT"; then break else echo "Waiting for packager." diff --git a/tests/js/admin-user-helper.js b/tests/js/admin-user-helper.js index e9eaa813..aadce944 100644 --- a/tests/js/admin-user-helper.js +++ b/tests/js/admin-user-helper.js @@ -1,6 +1,7 @@ 'use strict'; +const require_method = require; function node_require(module) { - return require(module); + return require_method(module); } const Realm = node_require('realm'); diff --git a/tests/js/index.js b/tests/js/index.js index 9b9514da..20fa6b5d 100644 --- a/tests/js/index.js +++ b/tests/js/index.js @@ -27,7 +27,8 @@ if( typeof Realm.Sync !== 'undefined' && Realm.Sync !== null ) { } const isNodeProcess = typeof process === 'object' && process + '' === '[object process]'; -function node_require(module) { return require(module); } +const require_method = require; +function node_require(module) { return require_method(module); } if (isNodeProcess && process.platform === 'win32') { global.enableSyncTests = false; diff --git a/tests/js/session-tests.js b/tests/js/session-tests.js index aab58bfb..c7859074 100644 --- a/tests/js/session-tests.js +++ b/tests/js/session-tests.js @@ -27,8 +27,9 @@ const TestCase = require('./asserts'); const isNodeProccess = (typeof process === 'object' && process + '' === '[object process]'); +const require_method = require; function node_require(module) { - return require(module); + return require_method(module); } let tmp; diff --git a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj index 774f755b..332547ce 100644 --- a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj +++ b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj @@ -829,7 +829,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/tests/react-test-app/package.json b/tests/react-test-app/package.json index 79c063fd..94d3533e 100644 --- a/tests/react-test-app/package.json +++ b/tests/react-test-app/package.json @@ -6,13 +6,14 @@ "start": "react-native start" }, "dependencies": { - "react": "~15.4.0-rc.4", - "react-native": "0.40.0", + "react": "~16.0.0-beta.5", + "react-native": "0.50.3", "react-native-fs": "^1.1.0", "realm": "file:../..", "realm-tests": "file:../js", "xmlbuilder": "^4.2.1" }, + "resolutions": { "moment": "2.19.1" }, "devDependencies": { "babel-preset-react-native": "1.9.1", "invariant": "^2.2.2" From 906a9dc34ef0cd9bf109a01fadeb08b1789971e3 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Thu, 16 Nov 2017 13:24:30 +0100 Subject: [PATCH 04/17] Download core/sync when testing --- scripts/test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/test.sh b/scripts/test.sh index 766ed8bb..d4e864a6 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -292,6 +292,7 @@ case "$TARGET" in npm run check-environment download_server start_server + node ./scripts/download-realm.js ios --sync pushd tests/react-test-app npm install open_chrome @@ -303,6 +304,7 @@ case "$TARGET" in ;; "react-example") npm run check-environment + node ./scripts/download-realm.js ios --sync pushd examples/ReactExample npm install From 66d02b3e4e1d11b8312643e885a26622a4d9278f Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Thu, 16 Nov 2017 20:47:23 +0100 Subject: [PATCH 05/17] Don't download of sync during testing --- scripts/test.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index d4e864a6..766ed8bb 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -292,7 +292,6 @@ case "$TARGET" in npm run check-environment download_server start_server - node ./scripts/download-realm.js ios --sync pushd tests/react-test-app npm install open_chrome @@ -304,7 +303,6 @@ case "$TARGET" in ;; "react-example") npm run check-environment - node ./scripts/download-realm.js ios --sync pushd examples/ReactExample npm install From 92ab314ba5e40567f55d809ff602452305fb3f1e Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Fri, 17 Nov 2017 13:49:39 +0100 Subject: [PATCH 06/17] Updating packages in ReactExample --- .../ReactExample.xcodeproj/project.pbxproj | 2 +- examples/ReactExample/package.json | 47 ++++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj b/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj index e16e57b5..ffc6720b 100644 --- a/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj +++ b/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj @@ -832,7 +832,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/examples/ReactExample/package.json b/examples/ReactExample/package.json index f9ec62e1..01fde7ba 100644 --- a/examples/ReactExample/package.json +++ b/examples/ReactExample/package.json @@ -1,24 +1,25 @@ { - "name": "ReactExample", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node node_modules/react-native/local-cli/cli.js start", - "test": "jest" - }, - "dependencies": { - "react": "~15.4.0-rc.4", - "react-native": "0.40.0", - "realm": "file:../.." - }, - "devDependencies": { - "babel-jest": "18.0.0", - "babel-preset-react-native": "1.9.1", - "jest": "18.1.0", - "react-test-renderer": "~15.4.0-rc.4", - "invariant": "^2.2.2" - }, - "jest": { - "preset": "react-native" - } -} \ No newline at end of file + "name": "ReactExample", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "node node_modules/react-native/local-cli/cli.js start", + "test": "jest" + }, + "dependencies": { + "react": "~16.0.0-beta.5", + "react-native": "0.50.3", + "react-navigation": "^1.0.0-beta.19", + "realm": "file:../.." + }, + "devDependencies": { + "babel-jest": "18.0.0", + "babel-preset-react-native": "1.9.1", + "invariant": "^2.2.2", + "jest": "18.1.0", + "react-test-renderer": "^16.1.1" + }, + "jest": { + "preset": "react-native" + } +} From 7e8b7d7bab92bd475988d4a23dbe886ca0340912 Mon Sep 17 00:00:00 2001 From: blagoev Date: Mon, 4 Dec 2017 15:56:42 +0200 Subject: [PATCH 07/17] upgrade RN in test app + fix simulators handling + fix test app to run tests immediatelly and exit afterwards --- scripts/find-ios-runtime.rb | 9 + scripts/test.sh | 146 +++-------- tests/index.js | 4 +- tests/js/asserts.js | 7 +- tests/js/index.js | 2 +- tests/js/list-tests.js | 4 +- tests/js/results-tests.js | 48 ++-- tests/react-test-app/android/app/build.gradle | 2 + .../realm/react/testapp/MainApplication.java | 4 + tests/react-test-app/android/settings.gradle | 5 + tests/react-test-app/index.ios.js | 94 ++++++- .../ios/ReactTests.xcodeproj/project.pbxproj | 240 +++++++++++++++++- tests/react-test-app/package.json | 16 +- tests/react-test-app/tests/index.js | 8 +- 14 files changed, 436 insertions(+), 153 deletions(-) create mode 100644 scripts/find-ios-runtime.rb diff --git a/scripts/find-ios-runtime.rb b/scripts/find-ios-runtime.rb new file mode 100644 index 00000000..e2b8cfa1 --- /dev/null +++ b/scripts/find-ios-runtime.rb @@ -0,0 +1,9 @@ +#!/usr/bin/ruby + +require 'json' + +runtime = JSON.parse(%x{xcrun simctl list devices --json})['runtimes'] + .select{|x| (x['identifier'].include? 'com.apple.CoreSimulator.SimRuntime.iOS') && + (x['availability'] == "(available)")}[0]["identifier"] + +puts runtime diff --git a/scripts/test.sh b/scripts/test.sh index 766ed8bb..67286673 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -23,6 +23,8 @@ if [ -n "${JENKINS_HOME}" ]; then CI_RUN=true fi +SIM_DEVICE_NAME=realm-js-test + # Start current working directory at the root of the project. cd "$SRCROOT" @@ -97,7 +99,11 @@ cleanup() { fi } -open_chrome() { +open_chrome() { + if [ $CONFIGURATION == 'Release' ]; then + break + fi + local dir for dir in "$HOME/Applications" "/Applications"; do if [ -d "$dir/Google Chrome.app" ]; then @@ -124,122 +130,52 @@ start_packager() { xctest() { setup_ios_simulator - # - Wait until the simulator is fully booted by waiting for it to launch SpringBoard - printf "Waiting for springboard to ensure device is ready..." - xcrun simctl launch "$IOS_SIM_DEVICE" com.apple.springboard 1>/dev/null 2>/dev/null || true - echo " done" - # - Run the build and test - xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="$IOS_SIM_DEVICE" build || { + echo "Building application" + xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="${IOS_SIM_DEVICE_ID}" -derivedDataPath ./build build || { EXITCODE=$? echo "*** Failure (exit code $EXITCODE). ***" exit $EXITCODE } - if [ -n "$XCPRETTY" ]; then - log_temp=$(mktemp build.log.XXXXXX) - if [ -e "$log_temp" ]; then - rm "$log_temp" - fi - xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination name="iPhone 5s" test 2>&1 | tee "$log_temp" | "$XCPRETTY" -c --no-utf --report junit --output build/reports/junit.xml || { - EXITCODE=$? - printf "*** Xcode Failure (exit code %s). The full xcode log follows: ***\n\n" "$EXITCODE" - cat "$log_temp" - printf "\n\n*** End Xcode Failure ***\n" - exit $EXITCODE - } - rm "$log_temp" + + echo "Installing application on ${SIM_DEVICE_NAME}" + echo "Application Path" $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/ReactTests.app + xcrun simctl install ${SIM_DEVICE_NAME} $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/ReactTests.app + + + echo "Launching application" + xcrun simctl launch --console ${SIM_DEVICE_NAME} io.realm.ReactTests | tee out.txt + + echo "Shuttting down ${SIM_DEVICE_NAME} simulator. (device is not deleted. you can use it to debug the app)" + xcrun simctl shutdown ${SIM_DEVICE_NAME} || true + + echo "Checking tests results" + if grep -q "REALM_FAILING_TESTS" out.txt; then + echo "*** REALM JS TESTS FAILED. See tests results above ***" + exit 20 else - xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="$IOS_SIM_DEVICE" test || { - EXITCODE=$? - echo "*** Failure (exit code $EXITCODE). ***" - exit $EXITCODE - } + echo "*** REALM JS TESTS SUCCESS ***" fi } -setup_ios_simulator() { - # - Ensure one version of xcode is chosen by all tools - if [[ -z "$DEVELOPER_DIR" ]]; then - DEV_DIR="$(xcode-select -p)" - export DEVELOPER_DIR=$DEV_DIR - fi +setup_ios_simulator() { + shutdown_ios_simulator - # -- Ensure that the simulator is ready + #parse devices + IOS_RUNTIME=$(xcrun simctl list runtimes | grep -m1 -o '(com.apple.CoreSimulator.SimRuntime.iOS.*)' | sed 's/[()]//g') + echo using iOS Runtime ${IOS_RUNTIME} to create new simulator ${SIM_DEVICE_NAME} - if [ $CI_RUN == true ]; then - # - Kill the Simulator to ensure we are running the correct one, only when running in CI - echo "Resetting simulator using toolchain from: $DEVELOPER_DIR" + #create new test simulator + IOS_SIM_DEVICE_ID=$(xcrun simctl create ${SIM_DEVICE_NAME} com.apple.CoreSimulator.SimDeviceType.iPhone-SE ${IOS_RUNTIME}) + #boot new test simulator + xcrun simctl boot ${SIM_DEVICE_NAME} +} - # Quit Simulator.app to give it a chance to go down gracefully - local deadline=$((SECONDS+5)) - while pgrep -qx Simulator && [ $SECONDS -lt $deadline ]; do - osascript -e 'tell app "Simulator" to quit without saving' || true - sleep 0.25 # otherwise the pkill following will get it too early - done - - # stop CoreSimulatorService - launchctl remove com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true - sleep 0.25 # launchtl can take a small moment to kill services - - # kill them with fire - while pgrep -qx Simulator com.apple.CoreSimulator.CoreSimulatorService; do - pkill -9 -x Simulator com.apple.CoreSimulator.CoreSimulatorService || true - sleep 0.05 - done - - # - Prod `simctl` a few times as sometimes it fails the first couple of times after switching XCode vesions - local deadline=$((SECONDS+5)) - while [ -z "$(xcrun simctl list devices 2>/dev/null)" ] && [ $SECONDS -lt $deadline ]; do - : # nothing to see here, will stop cycling on the first successful run - done - - # - Choose a device, if it has not already been chosen - local deadline=$((SECONDS+5)) - IOS_DEVICE="" - while [ -z "$IOS_DEVICE" ] && [ $SECONDS -lt $deadline ]; do - IOS_DEVICE="$(ruby $SRCROOT/scripts/find-ios-device.rb best)" - done - if [ -z "$IOS_DEVICE" ]; then - echo "*** Failed to determine the iOS Simulator device to use ***" - exit 1 - fi - export IOS_SIM_DEVICE=$IOS_DEVICE - - # - Reset the device we will be using if running in CI - xcrun simctl shutdown "$IOS_SIM_DEVICE" 1>/dev/null 2>/dev/null || true # sometimes simctl gets confused - xcrun simctl erase "$IOS_SIM_DEVICE" - - # - Start the target in Simulator.app - # Note: as of Xcode 7.3.1 `simctl` can not completely boot a simulator, specifically it can not bring up backboard, so GUI apps can not run. - # This is fixed in version 8 of Xcode, but we still need the compatibility - - "$DEVELOPER_DIR/Applications/Simulator.app/Contents/MacOS/Simulator" -CurrentDeviceUDID "$IOS_SIM_DEVICE" & # will get killed with all other children at exit - startedSimulator=true - - else - # - ensure that the simulator is running on a developer's workstation - open "$DEVELOPER_DIR/Applications/Simulator.app" - - # - Select the first device booted in the simulator, since it will boot something for us - local deadline=$((SECONDS+10)) - IOS_DEVICE="" - while [ -z "$IOS_DEVICE" ] && [ $SECONDS -lt $deadline ]; do - IOS_DEVICE="$(ruby $SRCROOT/scripts/find-ios-device.rb booted)" - done - if [ -z "$IOS_DEVICE" ]; then - echo "*** Failed to determine the iOS Simulator device in use ***" - exit 1 - fi - export IOS_SIM_DEVICE=$IOS_DEVICE - fi - - # Wait until the boot completes - printf " waiting for simulator (%s) to boot..." "$IOS_SIM_DEVICE" - until ruby -rjson -e "exit JSON.parse(%x{xcrun simctl list devices --json})['devices'].flat_map { |d| d[1] }.any? { |d| d['availability'] == '(available)' && d['state'] == 'Booted' }"; do - sleep 0.25 - done - echo " done" - echo "It will take some time before the simulator is fully ready, continuing on to other work" +shutdown_ios_simulator() { + #shutdown test simulator + xcrun simctl shutdown ${SIM_DEVICE_NAME} || true + #delete test simulator + xcrun simctl delete ${SIM_DEVICE_NAME} || true } # Cleanup now and also cleanup when this script exits. diff --git a/tests/index.js b/tests/index.js index 09fd9a9d..9db10452 100644 --- a/tests/index.js +++ b/tests/index.js @@ -56,7 +56,7 @@ function runTests() { return Object.keys(testNames).reduce((suitePromiseChain, suiteName) => { return suitePromiseChain.then(() => { - console.log('Starting ' + suiteName); + console.warn('Starting ' + suiteName); return testNames[suiteName].reduce((testPromiseChain, testName) => { return testPromiseChain.then(() => { @@ -64,7 +64,7 @@ function runTests() { }).then(() => { return RealmTests.runTest(suiteName, testName); }).then(() => { - console.log('+ ' + testName); + console.warn('+ ' + testName); }, (err) => { console.warn('- ' + testName); console.warn(err.message || err); diff --git a/tests/js/asserts.js b/tests/js/asserts.js index 1be734bc..ff01df46 100644 --- a/tests/js/asserts.js +++ b/tests/js/asserts.js @@ -203,7 +203,12 @@ module.exports = { }, assertType: function(value, type, depth) { - this.assertEqual(typeof value, type, `Value ${value} expected to be of type ${type}`, 1 + depth || 0); + try { + this.assertEqual(typeof value, type, "", 1 + depth || 0); + } + catch (e) { + throw new Error(`Value ${value} expected to be of type ${type}`) + } }, assertDefined: function(value, errorMessage, depth) { diff --git a/tests/js/index.js b/tests/js/index.js index 20fa6b5d..7aab4946 100644 --- a/tests/js/index.js +++ b/tests/js/index.js @@ -114,7 +114,7 @@ exports.runTest = function(suiteName, testName) { if (testMethod) { // Start fresh in case of a crash in a previous run. Realm.clearTestState(); - console.log("Starting test " + testName); + console.warn("Starting test " + testName); var promise; try { promise = testMethod.call(testSuite); diff --git a/tests/js/list-tests.js b/tests/js/list-tests.js index 145bc9ed..17d978d6 100644 --- a/tests/js/list-tests.js +++ b/tests/js/list-tests.js @@ -32,15 +32,13 @@ const DATE3 = new Date(3); module.exports = { testListConstructor: function() { const realm = new Realm({schema: [schemas.PersonObject, schemas.PersonList]}); - realm.write(() => { let obj = realm.create('PersonList', {list: []}); TestCase.assertInstanceOf(obj.list, Realm.List); TestCase.assertInstanceOf(obj.list, Realm.Collection); }); - + TestCase.assertThrowsContaining(() => new Realm.List(), 'constructor'); - TestCase.assertType(Realm.List, 'function'); TestCase.assertInstanceOf(Realm.List, Function); }, diff --git a/tests/js/results-tests.js b/tests/js/results-tests.js index 9c238622..b6a74033 100644 --- a/tests/js/results-tests.js +++ b/tests/js/results-tests.js @@ -386,35 +386,36 @@ module.exports = { testResultsFindIndexOfObject: function() { var realm = new Realm({schema: [schemas.TestObject]}); - + var object1, object2, object3; realm.write(function() { object1 = realm.create('TestObject', {doubleCol: 1}); object2 = realm.create('TestObject', {doubleCol: 2}); object3 = realm.create('TestObject', {doubleCol: 2}); }); - + // Search in base table const objects = realm.objects('TestObject'); TestCase.assertEqual(objects.indexOf(object1), 0); TestCase.assertEqual(objects.indexOf(object2), 1); TestCase.assertEqual(objects.indexOf(object3), 2); - + // Search in filtered query const results = objects.filtered("doubleCol == 2"); TestCase.assertEqual(results.indexOf(object1), -1); TestCase.assertEqual(results.indexOf(object2), 0); TestCase.assertEqual(results.indexOf(object3), 1); - + const nonRealmObject = {test: "this is an object"}; TestCase.assertEqual(objects.indexOf(nonRealmObject), -1); - + // Searching for object from the wrong realm var realm2 = new Realm({path: '2.realm', schema: realm.schema}); var object4; realm2.write(function() { object4 = realm2.create('TestObject', {doubleCol: 1}); }); + TestCase.assertThrows(function() { objects.indexOf(object4); }); @@ -423,7 +424,7 @@ module.exports = { testAddListener: function() { if (typeof navigator !== 'undefined' && /Chrome/.test(navigator.userAgent)) { // eslint-disable-line no-undef // FIXME: async callbacks do not work correctly in Chrome debugging mode - return; + return Promise.resolve(); } const realm = new Realm({ schema: [schemas.TestObject] }); @@ -433,29 +434,28 @@ module.exports = { realm.create('TestObject', { doubleCol: 3 }); }); - let resolve, first = true; + let resolve = () => {}; + let first = true; + + realm.objects('TestObject').addListener((testObjects, changes) => { + if (first) { + TestCase.assertEqual(testObjects.length, 3); + TestCase.assertEqual(changes.insertions.length, 0); + } + else { + TestCase.assertEqual(testObjects.length, 4); + TestCase.assertEqual(changes.insertions.length, 1); + } + first = false; + resolve(); + }); + return new Promise((r, _reject) => { - resolve = r; - realm.objects('TestObject').addListener((testObjects, changes) => { - if (first) { - TestCase.assertEqual(testObjects.length, 3); - TestCase.assertEqual(changes.insertions.length, 0); - } - else { - TestCase.assertEqual(testObjects.length, 4); - TestCase.assertEqual(changes.insertions.length, 1); - } - first = false; - resolve(); - }); - }).then(() => { - return new Promise((r, _reject) => { + resolve = r; realm.write(() => { realm.create('TestObject', { doubleCol: 1 }); }); - resolve = r; }); - }) }, testResultsAggregateFunctions: function() { diff --git a/tests/react-test-app/android/app/build.gradle b/tests/react-test-app/android/app/build.gradle index f060fc60..bec27402 100644 --- a/tests/react-test-app/android/app/build.gradle +++ b/tests/react-test-app/android/app/build.gradle @@ -137,6 +137,8 @@ android { } dependencies { + compile project(':react-native-exception-handler') + compile project(':react-native-exit-app-no-history') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules diff --git a/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java b/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java index fc8092c2..977b654f 100644 --- a/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java +++ b/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java @@ -4,6 +4,8 @@ import android.app.Application; import android.util.Log; import com.facebook.react.ReactApplication; +import com.masteratul.exceptionhandler.ReactNativeExceptionHandlerPackage; +import com.github.wumke.RNExitApp.RNExitAppPackage; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; @@ -28,6 +30,8 @@ public class MainApplication extends Application implements ReactApplication { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new ReactNativeExceptionHandlerPackage(), + new RNExitAppPackage(), new RNFSPackage(), new RealmReactPackage() ); diff --git a/tests/react-test-app/android/settings.gradle b/tests/react-test-app/android/settings.gradle index 3157a0c9..98eee976 100644 --- a/tests/react-test-app/android/settings.gradle +++ b/tests/react-test-app/android/settings.gradle @@ -7,3 +7,8 @@ project(':realm').projectDir = new File(settingsDir, '../node_modules/realm/andr include ':react-native-fs' project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android') + +include ':react-native-exception-handler' +project(':react-native-exception-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exception-handler/android') +include ':react-native-exit-app-no-history' +project(':react-native-exit-app-no-history').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exit-app-no-history/android') diff --git a/tests/react-test-app/index.ios.js b/tests/react-test-app/index.ios.js index d1aaaa7b..f12ced2b 100644 --- a/tests/react-test-app/index.ios.js +++ b/tests/react-test-app/index.ios.js @@ -19,23 +19,109 @@ 'use strict'; import { + Alert, AppRegistry, StyleSheet, Text, View, } from 'react-native'; +import builder from 'xmlbuilder'; import React from 'react'; -import { runTests } from './tests'; +import { getTestNames, runTest } from './tests'; +import RNFS from 'react-native-fs'; +import RNExitApp from 'react-native-exit-app-no-history'; + +// import {setJSExceptionHandler} from 'react-native-exception-handler'; +// import {setNativeExceptionHandler} from 'react-native-exception-handler/index'; + +// setNativeExceptionHandler((exceptionString) => { +// console.error("\nRealm Tests App FAILED. NATIVE ERROR\n"); +// console.error(`\n${exceptionString}\n`); +// RNExitApp.exitApp(); +// }); + +// //unhandled JS exceptions handler +// setJSExceptionHandler((error, isFatal) => { +// console.error("\nRealm Tests App FAILED. JS ERROR\n"); +// console.error(`\n${error}\n`); +// RNExitApp.exitApp(); +// }); + + + + +async function runTests() { + try { + let testNames = getTestNames(); + let rootXml = builder.create('testsuites'); + let failingTests = []; + for (let suiteName in testNames) { + let itemTestsuite = rootXml.ele('testsuite'); + let nbrTests = 0; + let nbrFailures = 0; + + console.error('Starting ' + suiteName); + + for (let testName of testNames[suiteName]) { + nbrTests++; + + let itemTest = itemTestsuite.ele('testcase'); + itemTest.att('name', testName); + + try { + await runTest(suiteName, testName); + } + catch (e) { + failingTests.push(`${suiteName}: ${testName} : Error ${e.message}`); + itemTest.ele('error', {'message': e.message, 'stacktrace': e.stack}, e.toString()); + nbrFailures++; + } + } + + // update Junit XML report + itemTestsuite.att('name', suiteName); + itemTestsuite.att('tests', nbrTests); + itemTestsuite.att('failures', nbrFailures); + itemTestsuite.att('timestamp', "2016-01-22T14:40:44.874443-05:00");//TODO use real timestamp + + } + // export unit tests results + let xmlString = rootXml.end({ + pretty: true, + indent: ' ', + newline: '\n', + }); + + // write the unit tests reports + const path = RNFS.MainBundlePath + "/tests.xml"; + await RNFS.writeFile(path, xmlString, 'utf8'); + + //using console.log output is not shown in Release builds. using console.warn + console.warn(xmlString); + console.warn('__REALM_REACT_IOS_TESTS_COMPLETED__'); + if (failingTests.length !== 0) { + console.error('\n\nREALM_FAILING_TESTS\n'); + console.error(failingTests); + } + } + catch (e) { + console.error(e); + } + finally { + console.warn("Realm iOS Tests App finished. Exiting. Disable this to debug the app locally"); + RNExitApp.exitApp(); + } +} class ReactTests extends React.Component { render() { + runTests(); return ( - - Tap to Run Tests - + {'\n'}REALM-JS TESTS{'\n'} + Press Cmd+R to reload,{'\n'} Cmd+D or shake for dev menu diff --git a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj index 332547ce..91b30d61 100644 --- a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj +++ b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj @@ -21,7 +21,9 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; + 1A31425AAD0B4731BDD7361C /* libReactNativeExceptionHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BDA39DE0BF646F2AF670F18 /* libReactNativeExceptionHandler.a */; }; 1A9D2B80E7D649D2B5D8FE09 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E45185577984C00AA740BFE /* libz.tbd */; }; + 1C2471A6B2544BF3BD9D9C10 /* libRNExitApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DAA9FCB85294F77873D2769 /* libRNExitApp.a */; }; 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 66DA50ADC4F24D88856B9051 /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 629FEF95D64747E9A56D4D0C /* libRealmReact.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; @@ -31,6 +33,7 @@ 855301D31E2006F700FF108E /* RealmReactTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 855301D11E2006F400FF108E /* RealmReactTests.m */; }; A4CEF4BB1F7F862D00BA3B26 /* sync-v1.realm in Resources */ = {isa = PBXBuildFile; fileRef = A4CEF4BA1F7F862D00BA3B26 /* sync-v1.realm */; }; E2050A7A5BE14CEA9A9E0722 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B37A7097A134D5CBB4C462A /* libc++.tbd */; }; + FD7EF00801C34983A6188E6E /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EBE9BC51D4A4EF79B40A51A /* libRNFS.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -223,6 +226,90 @@ remoteGlobalIDString = F60690131CA2766F0003FB26; remoteInfo = RealmReact; }; + A474395F1FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; + remoteInfo = fishhook; + }; + A47439611FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; + remoteInfo = "fishhook-tvOS"; + }; + A47439711FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; + remoteInfo = "third-party"; + }; + A47439731FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; + remoteInfo = "third-party-tvOS"; + }; + A47439751FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 139D7E881E25C6D100323FB7; + remoteInfo = "double-conversion"; + }; + A47439771FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D383D621EBD27B9005632C8; + remoteInfo = "double-conversion-tvOS"; + }; + A47439791FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9936F3131F5F2E4B0010BF04; + remoteInfo = privatedata; + }; + A474397B1FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04; + remoteInfo = "privatedata-tvOS"; + }; + A47439801FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FC81504B0B8B47808E93B553 /* RNFS.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = F12AFB9B1ADAF8F800E0535D; + remoteInfo = RNFS; + }; + A47439821FCF49A00034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FC81504B0B8B47808E93B553 /* RNFS.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 6456441F1EB8DA9100672408; + remoteInfo = "RNFS-tvOS"; + }; + A47439BA1FCF55E80034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5E54C8D078F84427A9DEE242 /* RNExitApp.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 15209BEF1D250F63000D0F44; + remoteInfo = RNExitApp; + }; + A47439F11FCF586E0034D32F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E65B8206DCD647B896F86688 /* ReactNativeExceptionHandler.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = ReactNativeExceptionHandler; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -245,8 +332,10 @@ 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 193A0C4F1D2C485DBE5ACC72 /* RealmReact.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RealmReact.xcodeproj; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = ""; }; 4E45185577984C00AA740BFE /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + 5E54C8D078F84427A9DEE242 /* RNExitApp.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNExitApp.xcodeproj; path = "../node_modules/react-native-exit-app-no-history/ios/RNExitApp.xcodeproj"; sourceTree = ""; }; 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 629FEF95D64747E9A56D4D0C /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = ""; }; + 6EBE9BC51D4A4EF79B40A51A /* libRNFS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFS.a; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 8553016A1E1FF6D500FF108E /* RealmJSTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmJSTests.mm; path = ../../ios/RealmJSTests.mm; sourceTree = ""; }; @@ -254,7 +343,11 @@ 855301CE1E20069D00FF108E /* dates-v5.realm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "dates-v5.realm"; sourceTree = ""; }; 855301D11E2006F400FF108E /* RealmReactTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RealmReactTests.m; path = ReactTests/RealmReactTests.m; sourceTree = ""; }; 8B37A7097A134D5CBB4C462A /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + 9BDA39DE0BF646F2AF670F18 /* libReactNativeExceptionHandler.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativeExceptionHandler.a; sourceTree = ""; }; + 9DAA9FCB85294F77873D2769 /* libRNExitApp.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNExitApp.a; sourceTree = ""; }; A4CEF4BA1F7F862D00BA3B26 /* sync-v1.realm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "sync-v1.realm"; sourceTree = ""; }; + E65B8206DCD647B896F86688 /* ReactNativeExceptionHandler.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativeExceptionHandler.xcodeproj; path = "../node_modules/react-native-exception-handler/ios/ReactNativeExceptionHandler.xcodeproj"; sourceTree = ""; }; + FC81504B0B8B47808E93B553 /* RNFS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFS.xcodeproj; path = "../node_modules/react-native-fs/RNFS.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -284,6 +377,9 @@ 66DA50ADC4F24D88856B9051 /* libRealmReact.a in Frameworks */, E2050A7A5BE14CEA9A9E0722 /* libc++.tbd in Frameworks */, 1A9D2B80E7D649D2B5D8FE09 /* libz.tbd in Frameworks */, + FD7EF00801C34983A6188E6E /* libRNFS.a in Frameworks */, + 1C2471A6B2544BF3BD9D9C10 /* libRNExitApp.a in Frameworks */, + 1A31425AAD0B4731BDD7361C /* libReactNativeExceptionHandler.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -346,6 +442,8 @@ children = ( 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, + A47439601FCF49A00034D32F /* libfishhook.a */, + A47439621FCF49A00034D32F /* libfishhook-tvOS.a */, ); name = Products; sourceTree = ""; @@ -375,6 +473,12 @@ 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */, 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */, + A47439721FCF49A00034D32F /* libthird-party.a */, + A47439741FCF49A00034D32F /* libthird-party.a */, + A47439761FCF49A00034D32F /* libdouble-conversion.a */, + A47439781FCF49A00034D32F /* libdouble-conversion.a */, + A474397A1FCF49A00034D32F /* libprivatedata.a */, + A474397C1FCF49A00034D32F /* libprivatedata-tvOS.a */, ); name = Products; sourceTree = ""; @@ -400,7 +504,7 @@ isa = PBXGroup; children = ( 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */, + 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */, ); name = Products; sourceTree = ""; @@ -429,6 +533,9 @@ 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 193A0C4F1D2C485DBE5ACC72 /* RealmReact.xcodeproj */, + FC81504B0B8B47808E93B553 /* RNFS.xcodeproj */, + 5E54C8D078F84427A9DEE242 /* RNExitApp.xcodeproj */, + E65B8206DCD647B896F86688 /* ReactNativeExceptionHandler.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -486,6 +593,31 @@ path = ../../data; sourceTree = ""; }; + A474394A1FCF49A00034D32F /* Products */ = { + isa = PBXGroup; + children = ( + A47439811FCF49A00034D32F /* libRNFS.a */, + A47439831FCF49A00034D32F /* libRNFS.a */, + ); + name = Products; + sourceTree = ""; + }; + A47439951FCF55E80034D32F /* Products */ = { + isa = PBXGroup; + children = ( + A47439BB1FCF55E80034D32F /* libRNExitApp.a */, + ); + name = Products; + sourceTree = ""; + }; + A47439CD1FCF586E0034D32F /* Products */ = { + isa = PBXGroup; + children = ( + A47439F21FCF586E0034D32F /* libReactNativeExceptionHandler.a */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -596,10 +728,22 @@ ProductGroup = 146834001AC3E56700842450 /* Products */; ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; }, + { + ProductGroup = A47439CD1FCF586E0034D32F /* Products */; + ProjectRef = E65B8206DCD647B896F86688 /* ReactNativeExceptionHandler.xcodeproj */; + }, { ProductGroup = 855301781E1FF78600FF108E /* Products */; ProjectRef = 193A0C4F1D2C485DBE5ACC72 /* RealmReact.xcodeproj */; }, + { + ProductGroup = A47439951FCF55E80034D32F /* Products */; + ProjectRef = 5E54C8D078F84427A9DEE242 /* RNExitApp.xcodeproj */; + }, + { + ProductGroup = A474394A1FCF49A00034D32F /* Products */; + ProjectRef = FC81504B0B8B47808E93B553 /* RNFS.xcodeproj */; + }, ); projectRoot = ""; targets = ( @@ -764,10 +908,10 @@ remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = { + 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = "libRCTAnimation-tvOS.a"; + path = libRCTAnimation.a; remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -792,6 +936,90 @@ remoteRef = 855301941E1FF78600FF108E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + A47439601FCF49A00034D32F /* libfishhook.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libfishhook.a; + remoteRef = A474395F1FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439621FCF49A00034D32F /* libfishhook-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libfishhook-tvOS.a"; + remoteRef = A47439611FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439721FCF49A00034D32F /* libthird-party.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libthird-party.a"; + remoteRef = A47439711FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439741FCF49A00034D32F /* libthird-party.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libthird-party.a"; + remoteRef = A47439731FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439761FCF49A00034D32F /* libdouble-conversion.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libdouble-conversion.a"; + remoteRef = A47439751FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439781FCF49A00034D32F /* libdouble-conversion.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libdouble-conversion.a"; + remoteRef = A47439771FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A474397A1FCF49A00034D32F /* libprivatedata.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libprivatedata.a; + remoteRef = A47439791FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A474397C1FCF49A00034D32F /* libprivatedata-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libprivatedata-tvOS.a"; + remoteRef = A474397B1FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439811FCF49A00034D32F /* libRNFS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNFS.a; + remoteRef = A47439801FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439831FCF49A00034D32F /* libRNFS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNFS.a; + remoteRef = A47439821FCF49A00034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439BB1FCF55E80034D32F /* libRNExitApp.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNExitApp.a; + remoteRef = A47439BA1FCF55E80034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + A47439F21FCF586E0034D32F /* libReactNativeExceptionHandler.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libReactNativeExceptionHandler.a; + remoteRef = A47439F11FCF586E0034D32F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -889,6 +1117,9 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests"; @@ -907,6 +1138,9 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests"; diff --git a/tests/react-test-app/package.json b/tests/react-test-app/package.json index 94d3533e..9bfbd4a8 100644 --- a/tests/react-test-app/package.json +++ b/tests/react-test-app/package.json @@ -3,19 +3,23 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "react-native start" + "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { - "react": "~16.0.0-beta.5", - "react-native": "0.50.3", - "react-native-fs": "^1.1.0", + "react": "16.0.0", + "react-native": "0.50.4", + "react-native-exception-handler": "^2.4.3", + "react-native-exit-app-no-history": "^1.0.2", + "react-native-fs": "^2.8.5", "realm": "file:../..", "realm-tests": "file:../js", "xmlbuilder": "^4.2.1" }, - "resolutions": { "moment": "2.19.1" }, + "resolutions": { + "moment": "2.19.1" + }, "devDependencies": { - "babel-preset-react-native": "1.9.1", + "babel-preset-react-native": "4.0.0", "invariant": "^2.2.2" } } diff --git a/tests/react-test-app/tests/index.js b/tests/react-test-app/tests/index.js index ebaabcba..9e3d1673 100644 --- a/tests/react-test-app/tests/index.js +++ b/tests/react-test-app/tests/index.js @@ -52,7 +52,7 @@ export async function runTests() { let passed = true; for (let suiteName in testNames) { - console.log('Starting ' + suiteName); + console.warn('Starting ' + suiteName); for (let testName of testNames[suiteName]) { try { @@ -72,11 +72,11 @@ export async function runTest(suiteName, testName) { try { await RealmTests.runTest(suiteName, testName); - console.log('+ ' + testName); + console.warn('+ ' + testName); } catch (e) { - console.warn('- ' + testName); - console.warn(e.message || e); + console.error('- ' + testName); + console.error(e.message || e); throw e; } finally { From b842d07726c88010403b56e1d50ceedd2dc6049d Mon Sep 17 00:00:00 2001 From: blagoev Date: Tue, 5 Dec 2017 14:46:41 +0200 Subject: [PATCH 08/17] remove explict ROS uninstall --- scripts/download-object-server.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/download-object-server.sh b/scripts/download-object-server.sh index bca57c0a..b96b495c 100755 --- a/scripts/download-object-server.sh +++ b/scripts/download-object-server.sh @@ -9,15 +9,11 @@ set -eo pipefail #use existing server if same version if [ -f node_modules/realm-object-server/package.json ]; then if grep -q "\"version\": \"$REALM_OBJECT_SERVER_VERSION\"" node_modules/realm-object-server/package.json; then - # echo -e "yes\n" | object-server-for-testing/reset-server-realms.command rm -rf realm-object-server-data rm -rf realm-object-server exit fi fi -echo "Uninstalling old version of realm-object-server" -npm uninstall realm-object-server - echo "Installing realm-object-server version: " $REALM_OBJECT_SERVER_VERSION npm install realm-object-server@$REALM_OBJECT_SERVER_VERSION \ No newline at end of file From 36a6f44bbdba289613b5ee39f6e02ed7e2468378 Mon Sep 17 00:00:00 2001 From: blagoev Date: Tue, 5 Dec 2017 14:47:08 +0200 Subject: [PATCH 09/17] ignore test output file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6f82ef03..779d6a36 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ tests/realm-object-server/ packager_out.txt build.log.* realm-object-server/ +tests/react-test-app/ios/out.txt From 9084c2d271f4f9eac104566fd4e1a9c611d5f26a Mon Sep 17 00:00:00 2001 From: blagoev Date: Tue, 5 Dec 2017 14:47:44 +0200 Subject: [PATCH 10/17] depend on lzma-native to fix lzma-native native module not found --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f024f896..c2ed7ef1 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,8 @@ "request": "^2.78.0", "stream-counter": "^1.0.0", "sync-request": "^3.0.1", - "url-parse": "^1.1.7" + "url-parse": "^1.1.7", + "lzma-native": "^3.0.4" }, "devDependencies": { "babel-eslint": "^6.0.4", From bb97ea265384c030dc282e489c0da7cf614e2120 Mon Sep 17 00:00:00 2001 From: blagoev Date: Tue, 5 Dec 2017 17:48:15 +0200 Subject: [PATCH 11/17] use consistent node version --- src/RealmJS.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index d29df039..032de015 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -888,7 +888,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = "/bin/sh"; - shellScript = "[ -z \"$NVM_DIR\" ] && export NVM_DIR=\"$HOME/.nvm\"\n\nif [[ -s \"$HOME/.nvm/nvm.sh\" ]]; then\n . \"$HOME/.nvm/nvm.sh\"\nelif [[ -x \"$(command -v brew)\" && -s \"$(brew --prefix nvm)/nvm.sh\" ]]; then\n . \"$(brew --prefix nvm)/nvm.sh\"\nfi\nnode ../scripts/download-realm.js ios --sync"; + shellScript = "[ -z \"$NVM_DIR\" ] && export NVM_DIR=\"$HOME/.nvm\"\n\nif [[ -s \"$HOME/.nvm/nvm.sh\" ]]; then\n . \"$HOME/.nvm/nvm.sh\"\nelif [[ -x \"$(command -v brew)\" && -s \"$(brew --prefix nvm)/nvm.sh\" ]]; then\n . \"$(brew --prefix nvm)/nvm.sh\"\nfi\n \nif [[ \"$(command -v nvm)\" ]]; then\n nvm install 7.10.0\nfi\n \n node ../scripts/download-realm.js ios --sync"; }; /* End PBXShellScriptBuildPhase section */ From 3000e5d11799befc56189c7ca9594885963539e9 Mon Sep 17 00:00:00 2001 From: blagoev Date: Wed, 6 Dec 2017 14:42:20 +0200 Subject: [PATCH 12/17] rename test application Xcode scheme --- tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj | 2 ++ .../xcschemes/{ReactTestApp.xcscheme => ReactTests.xcscheme} | 0 2 files changed, 2 insertions(+) rename tests/react-test-app/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/{ReactTestApp.xcscheme => ReactTests.xcscheme} (100%) diff --git a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj index 91b30d61..7ef46e59 100644 --- a/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj +++ b/tests/react-test-app/ios/ReactTests.xcodeproj/project.pbxproj @@ -1155,6 +1155,7 @@ INFOPLIST_FILE = ReactTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = io.realm.ReactTests; PRODUCT_NAME = ReactTests; }; name = Debug; @@ -1166,6 +1167,7 @@ INFOPLIST_FILE = ReactTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = io.realm.ReactTests; PRODUCT_NAME = ReactTests; }; name = Release; diff --git a/tests/react-test-app/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTestApp.xcscheme b/tests/react-test-app/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme similarity index 100% rename from tests/react-test-app/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTestApp.xcscheme rename to tests/react-test-app/ios/ReactTests.xcodeproj/xcshareddata/xcschemes/ReactTests.xcscheme From 18a63d6f79dd8f190f5f7046a77c91d21a230401 Mon Sep 17 00:00:00 2001 From: blagoev Date: Wed, 6 Dec 2017 14:43:02 +0200 Subject: [PATCH 13/17] allow multiple test applications to be run (identified by application scheme.) --- scripts/test.sh | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index 67286673..96c29ba0 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -77,6 +77,9 @@ cleanup() { # Kill started object server stop_server || true + echo "shutting down running simulators" + shutdown_ios_simulator >/dev/null 2>&1 + # Quit Simulator.app to give it a chance to go down gracefully if $startedSimulator; then osascript -e 'tell app "Simulator" to quit without saving' || true @@ -139,27 +142,29 @@ xctest() { } echo "Installing application on ${SIM_DEVICE_NAME}" - echo "Application Path" $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/ReactTests.app - xcrun simctl install ${SIM_DEVICE_NAME} $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/ReactTests.app + echo "Application Path" $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/$1.app + xcrun simctl install ${SIM_DEVICE_NAME} $(pwd)/build/Build/Products/$CONFIGURATION-iphonesimulator/$1.app - echo "Launching application" - xcrun simctl launch --console ${SIM_DEVICE_NAME} io.realm.ReactTests | tee out.txt + echo "Launching application. (output is in $(pwd)/build/out.txt)" + xcrun simctl launch --console ${SIM_DEVICE_NAME} io.realm.$1 | tee $(pwd)/build/out.txt echo "Shuttting down ${SIM_DEVICE_NAME} simulator. (device is not deleted. you can use it to debug the app)" - xcrun simctl shutdown ${SIM_DEVICE_NAME} || true + shutdown_ios_simulator echo "Checking tests results" - if grep -q "REALM_FAILING_TESTS" out.txt; then + if grep -q "REALM_FAILING_TESTS" $(pwd)/build/out.txt; then echo "*** REALM JS TESTS FAILED. See tests results above ***" exit 20 else - echo "*** REALM JS TESTS SUCCESS ***" + echo "*** $1 SUCCESS ***" fi } setup_ios_simulator() { - shutdown_ios_simulator + #try deleting old simulator with same name. + echo "Preparing to create a new simulator" + delete_ios_simulator >/dev/null 2>&1 #parse devices IOS_RUNTIME=$(xcrun simctl list runtimes | grep -m1 -o '(com.apple.CoreSimulator.SimRuntime.iOS.*)' | sed 's/[()]//g') @@ -174,12 +179,17 @@ setup_ios_simulator() { shutdown_ios_simulator() { #shutdown test simulator xcrun simctl shutdown ${SIM_DEVICE_NAME} || true +} + +delete_ios_simulator() { + shutdown_ios_simulator + #delete test simulator xcrun simctl delete ${SIM_DEVICE_NAME} || true } # Cleanup now and also cleanup when this script exits. -cleanup +cleanup >/dev/null 2>&1 trap cleanup EXIT # Use a consistent version of Node if possible. @@ -234,7 +244,7 @@ case "$TARGET" in start_packager pushd ios - xctest ReactTestApp + xctest ReactTests stop_server ;; "react-example") From 9f41664309e9cad934a0d6a9a1ecfc093d9f46dc Mon Sep 17 00:00:00 2001 From: blagoev Date: Wed, 6 Dec 2017 14:44:00 +0200 Subject: [PATCH 14/17] try fix ReactExample test app --- examples/ReactExample/components/styles.js | 5 +++-- examples/ReactExample/components/todo-app.js | 8 +++++--- examples/ReactExample/package.json | 9 +++++---- .../Images.xcassets/AppIcon.appiconset/Contents.json | 10 ++++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/examples/ReactExample/components/styles.js b/examples/ReactExample/components/styles.js index 05c01a87..67c5d11b 100644 --- a/examples/ReactExample/components/styles.js +++ b/examples/ReactExample/components/styles.js @@ -19,14 +19,15 @@ 'use strict'; import { - Navigator, Platform, StyleSheet } from 'react-native'; +import NavigationExperimental from 'react-native-deprecated-custom-components'; -const { NavBarHeight, TotalNavHeight } = Navigator.NavigationBar.Styles.General; +const { NavBarHeight, TotalNavHeight } = NavigationExperimental.Navigator.NavigationBar.Styles.General; const iOS = (Platform.OS == 'ios'); + export default StyleSheet.create({ container: { flex: 1, diff --git a/examples/ReactExample/components/todo-app.js b/examples/ReactExample/components/todo-app.js index d2ff4fe4..e51b62e9 100644 --- a/examples/ReactExample/components/todo-app.js +++ b/examples/ReactExample/components/todo-app.js @@ -21,7 +21,6 @@ import React from 'react'; import { - Navigator, Platform, StatusBar, Text, @@ -34,6 +33,9 @@ import TodoListView from './todo-listview'; import realm from './realm'; import styles from './styles'; +import NavigationExperimental from 'react-native-deprecated-custom-components'; + + export default class TodoApp extends React.Component { constructor(props) { super(props); @@ -91,11 +93,11 @@ export default class TodoApp extends React.Component { }; let navigationBar = ( - + ); return ( - Date: Wed, 13 Dec 2017 18:36:10 +0200 Subject: [PATCH 15/17] fix RealmExample app to use the new RN navigation --- .../ReactExample/android/app/build.gradle | 1 + .../realm/react/example/MainApplication.java | 2 + examples/ReactExample/android/settings.gradle | 2 + .../ReactExample/components/items-screen.js | 104 +++++++++++ examples/ReactExample/components/params.json | 1 + examples/ReactExample/components/styles.js | 8 +- examples/ReactExample/components/todo-app.js | 133 ++++---------- .../ReactExample/components/todo-itemsview.js | 172 ++++++++++++++++++ .../ReactExample/components/todo-list-item.js | 7 +- .../ReactExample/components/todo-listview.js | 2 +- .../ReactExample.xcodeproj/project.pbxproj | 8 +- examples/ReactExample/package.json | 4 +- scripts/test.sh | 3 + 13 files changed, 340 insertions(+), 107 deletions(-) create mode 100644 examples/ReactExample/components/items-screen.js create mode 100644 examples/ReactExample/components/params.json create mode 100644 examples/ReactExample/components/todo-itemsview.js diff --git a/examples/ReactExample/android/app/build.gradle b/examples/ReactExample/android/app/build.gradle index 9ecce5be..a9b4e033 100644 --- a/examples/ReactExample/android/app/build.gradle +++ b/examples/ReactExample/android/app/build.gradle @@ -126,6 +126,7 @@ android { } dependencies { + compile project(':react-native-exit-app-no-history') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules diff --git a/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainApplication.java b/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainApplication.java index fd45f4fc..b220a0d8 100644 --- a/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainApplication.java +++ b/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainApplication.java @@ -4,6 +4,7 @@ import android.app.Application; import android.util.Log; import com.facebook.react.ReactApplication; +import com.github.wumke.RNExitApp.RNExitAppPackage; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; @@ -27,6 +28,7 @@ public class MainApplication extends Application implements ReactApplication { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new RNExitAppPackage(), new RealmReactPackage() ); } diff --git a/examples/ReactExample/android/settings.gradle b/examples/ReactExample/android/settings.gradle index 96ce9242..28f31ada 100644 --- a/examples/ReactExample/android/settings.gradle +++ b/examples/ReactExample/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'ReactExample' +include ':react-native-exit-app-no-history' +project(':react-native-exit-app-no-history').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exit-app-no-history/android') include ':app' diff --git a/examples/ReactExample/components/items-screen.js b/examples/ReactExample/components/items-screen.js new file mode 100644 index 00000000..02d2f095 --- /dev/null +++ b/examples/ReactExample/components/items-screen.js @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +'use strict'; + +import React from 'react'; + +import { + Platform, + StatusBar, + Text, + TouchableOpacity, + View, +} from 'react-native'; + +import TodoItem from './todo-item'; +import TodoListView from './todo-listview'; +import TodoItemsView from './todo-itemsview'; +import TodoListItem from './todo-list-item'; +import realm from './realm'; +import styles from './styles'; + +import { StackNavigator } from 'react-navigation'; + +export default class ItemsScreen extends React.Component { + static navigationOptions = { + title: 'Current list', + }; + + constructor(props) { + super(props); + this.state = {}; + } + + componentWillMount() { + if (Platform.OS == 'ios') { + StatusBar.setBarStyle('light-content'); + } + } + + render() { + // let objects = realm.objects('Todo'); + // let extraItems = [ + // { name: 'Complete', items: objects.filtered('done = true') }, + // { name: 'Incomplete', items: objects.filtered('done = false') }, + // ]; + + let properties = { + // ref: 'listView', + // extraItems: extraItems, + // onPressItem: this._onPressTodoList, + } + + return ; + } + + // renderScene(route) { + // console.log(this.todoLists); + // return + // } + + + + // _onPressTodoItem(list) { + // const { navigate } = this.props.navigation; + // let items = list.items; + + // let route = { + // title: list.name, + // component: TodoListView, + // passProps: { + // ref: 'listItemView', + // items: items, + // rowClass: TodoItem, + // }, + // }; + + // // Check if the items are mutable (i.e. List rather than Results). + // if (items.push) { + // Object.assign(route, { + // rightButtonTitle: 'Add', + // onRightButtonPress: () => this._addNewTodoItem(list), + // }); + // } + + // // this.refs.nav.push(route); + // navigate('TodoListItem', { items: items }) + // } +} \ No newline at end of file diff --git a/examples/ReactExample/components/params.json b/examples/ReactExample/components/params.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/examples/ReactExample/components/params.json @@ -0,0 +1 @@ +{} diff --git a/examples/ReactExample/components/styles.js b/examples/ReactExample/components/styles.js index 67c5d11b..32f8f00b 100644 --- a/examples/ReactExample/components/styles.js +++ b/examples/ReactExample/components/styles.js @@ -22,9 +22,9 @@ import { Platform, StyleSheet } from 'react-native'; -import NavigationExperimental from 'react-native-deprecated-custom-components'; +// import NavigationExperimental from 'react-native-deprecated-custom-components'; -const { NavBarHeight, TotalNavHeight } = NavigationExperimental.Navigator.NavigationBar.Styles.General; +// const { NavBarHeight, TotalNavHeight } = NavigationExperimental.Navigator.NavigationBar.Styles.General; const iOS = (Platform.OS == 'ios'); @@ -44,7 +44,7 @@ export default StyleSheet.create({ navBarView: { alignItems: 'center', flexDirection: 'row', - height: NavBarHeight, + height: 20, }, navBarLeftArrow: { color: '#fff', @@ -67,7 +67,7 @@ export default StyleSheet.create({ fontWeight: '500', }, navScene: { - top: TotalNavHeight, + top: 20, }, listItem: { borderColor: '#c8c7cc', diff --git a/examples/ReactExample/components/todo-app.js b/examples/ReactExample/components/todo-app.js index e51b62e9..cd8b4bd6 100644 --- a/examples/ReactExample/components/todo-app.js +++ b/examples/ReactExample/components/todo-app.js @@ -30,13 +30,22 @@ import { import TodoItem from './todo-item'; import TodoListView from './todo-listview'; +import TodoListItem from './todo-list-item'; +import ItemsScreen from './items-screen' import realm from './realm'; import styles from './styles'; -import NavigationExperimental from 'react-native-deprecated-custom-components'; +// import NavigationExperimental from 'react-native-deprecated-custom-components'; +import { StackNavigator } from 'react-navigation'; +import RNExitApp from 'react-native-exit-app-no-history'; +const params = require("./params.json"); + +class HomeScreen extends React.Component { + static navigationOptions = { + title: 'Todo Lists', + }; -export default class TodoApp extends React.Component { constructor(props) { super(props); @@ -44,17 +53,21 @@ export default class TodoApp extends React.Component { this.todoLists = realm.objects('TodoList').sorted('creationDate'); if (this.todoLists.length < 1) { realm.write(() => { - realm.create('TodoList', {name: 'Todo List', creationDate: new Date()}); + realm.create('TodoList', { name: 'Todo List', creationDate: new Date() }); }); } this.todoLists.addListener((name, changes) => { console.log("changed: " + JSON.stringify(changes)); + if (params) { + console.error("params.json indicate a test run. Exiting application"); + RNExitApp.exitApp(); + } }); console.log("registered listener"); // Bind all the methods that we will be passing as props. - this.renderScene = this.renderScene.bind(this); + // this.renderScene = this.renderScene.bind(this); this._addNewTodoList = this._addNewTodoList.bind(this); this._onPressTodoList = this._onPressTodoList.bind(this); @@ -75,37 +88,17 @@ export default class TodoApp extends React.Component { render() { let objects = realm.objects('Todo'); let extraItems = [ - {name: 'Complete', items: objects.filtered('done = true')}, - {name: 'Incomplete', items: objects.filtered('done = false')}, + { name: 'Complete', items: objects.filtered('done = true') }, + { name: 'Incomplete', items: objects.filtered('done = false') }, ]; - let route = { - title: 'My Todo Lists', - component: TodoListView, - passProps: { - ref: 'listView', - extraItems: extraItems, - onPressItem: this._onPressTodoList, - }, - backButtonTitle: 'Lists', - rightButtonTitle: 'Add', - onRightButtonPress: this._addNewTodoList, - }; + let properties = { + ref: 'listView', + extraItems: extraItems, + onPressItem: this._onPressTodoList, + } - let navigationBar = ( - - ); - - return ( - - ); + return ; } renderScene(route) { @@ -120,7 +113,7 @@ export default class TodoApp extends React.Component { } realm.write(() => { - items.push({text: ''}); + items.push({ text: '' }); }); this._setEditingRow(items.length - 1); @@ -133,34 +126,17 @@ export default class TodoApp extends React.Component { } realm.write(() => { - realm.create('TodoList', {name: '', creationDate: new Date()}); + realm.create('TodoList', { name: '', creationDate: new Date() }); }); this._setEditingRow(items.length - 1); } _onPressTodoList(list) { + const { navigate } = this.props.navigation; let items = list.items; - let route = { - title: list.name, - component: TodoListView, - passProps: { - ref: 'listItemView', - items: items, - rowClass: TodoItem, - }, - }; - - // Check if the items are mutable (i.e. List rather than Results). - if (items.push) { - Object.assign(route, { - rightButtonTitle: 'Add', - onRightButtonPress: () => this._addNewTodoItem(list), - }); - } - - this.refs.nav.push(route); + navigate('ItemsScreen', { items: items }) } _shouldAddNewItem(items) { @@ -175,53 +151,14 @@ export default class TodoApp extends React.Component { let listView = this.currentListView; // Update the state on the currently displayed TodoList to edit this new item. - listView.setState({editingRow: rowIndex}); + listView.setState({ editingRow: rowIndex }); listView.updateDataSource(); } } -const RouteMapper = { - LeftButton(route, navigator, index, navState) { - if (index == 0) { - return null; - } +const SimpleApp = StackNavigator({ + Home: { screen: HomeScreen }, + ItemsScreen: { screen: ItemsScreen } +}); - let prevRoute = navState.routeStack[index - 1]; - return ( - navigator.pop()}> - - - - {prevRoute.backButtonTitle || prevRoute.title || 'Back'} - - - - ); - }, - - RightButton(route) { - if (!route.rightButtonTitle) { - return null; - } - - return ( - - - - {route.rightButtonTitle} - - - - ); - }, - - Title(route) { - return ( - - - {route.title} - - - ); - }, -}; +export default SimpleApp; \ No newline at end of file diff --git a/examples/ReactExample/components/todo-itemsview.js b/examples/ReactExample/components/todo-itemsview.js new file mode 100644 index 00000000..404c1e0c --- /dev/null +++ b/examples/ReactExample/components/todo-itemsview.js @@ -0,0 +1,172 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +'use strict'; + +import React from 'react'; + +import { + Text, + View, +} from 'react-native'; + +import { ListView } from 'realm/react-native'; +import TodoItem from './todo-item'; +import realm from './realm'; +import styles from './styles'; + +export default class TodoItemsView extends React.Component { + constructor(props) { + super(props); + + let dataSource = new ListView.DataSource({ + rowHasChanged(a, b) { + // Always re-render TodoList items. + return a.done !== b.done || a.text !== b.text || a.items || b.items; + } + }); + + this.state = { + dataSource: this._cloneDataSource(dataSource, props), + }; + + this.renderRow = this.renderRow.bind(this); + } + + componentWillReceiveProps(props) { + this.updateDataSource(props); + } + + componentDidUpdate() { + let items = this.props.items; + let editingRow = this.state.editingRow; + + for (let i = items.length; i--;) { + if (i == editingRow) { + continue; + } + if (this._deleteItemIfEmpty(items[i]) && i < editingRow) { + editingRow--; + } + } + + if (editingRow != this.state.editingRow) { + this.setState({editingRow}); + } + } + + render() { + return ( + + + + Press Cmd+R to reload,{'\n'} + Cmd+D for dev menu + + + ); + } + + renderRow(item, sectionIndex, rowIndex) { + let RowClass; + let editing = false; + + // if (sectionIndex == 0) { + // RowClass = this.props.rowClass || TodoListItem; + // editing = this.state.editingRow == rowIndex; + // } else if (sectionIndex == 1) { + // RowClass = TodoListExtraItem; + // } + + return ( + this._onPressRow(item, sectionIndex, rowIndex)} + onPressDelete={() => this._onPressDeleteRow(item)} + onEndEditing={() => this._onEndEditingRow(item, rowIndex)} /> + ); + } + + updateDataSource(props=this.props) { + this.setState({ + dataSource: this._cloneDataSource(this.state.dataSource, props), + }); + } + + _cloneDataSource(dataSource, props) { + let items = props.items; + let extraItems = props.extraItems; + let sections = [items ? items.snapshot() : []]; + + if (extraItems && extraItems.length) { + sections.push(extraItems); + } + + return dataSource.cloneWithRowsAndSections(sections); + } + + _onPressRow(item, sectionIndex, rowIndex) { + let onPressItem = this.props.onPressItem; + if (onPressItem) { + onPressItem(item); + return; + } + + // If no handler was provided, then default to editing the row. + if (sectionIndex == 0) { + this.setState({editingRow: rowIndex}); + } + } + + _onPressDeleteRow(item) { + this._deleteItem(item); + this.updateDataSource(); + } + + _onEndEditingRow(item, rowIndex) { + if (this._deleteItemIfEmpty(item)) { + this.updateDataSource(); + } + if (this.state.editingRow == rowIndex) { + this.setState({editingRow: null}); + } + } + + _deleteItem(item) { + let items = item.items; + + realm.write(() => { + // If the item is a TodoList, then delete all of its items. + if (items && items.length) { + realm.delete(items); + } + + realm.delete(item); + }); + } + + _deleteItemIfEmpty(item) { + // The item could be a TodoList or a Todo. + if (!item.name && !item.text) { + this._deleteItem(item); + return true; + } + return false; + } +} diff --git a/examples/ReactExample/components/todo-list-item.js b/examples/ReactExample/components/todo-list-item.js index b82b823f..06137ac8 100644 --- a/examples/ReactExample/components/todo-list-item.js +++ b/examples/ReactExample/components/todo-list-item.js @@ -42,7 +42,12 @@ export default class TodoListItem extends React.Component { get done() { let items = this.props.item.items; - return items.length > 0 && items.every((item) => item.done); + if (items) { + return items.length > 0 && items.every((item) => item.done); + } + else { + return this.props.item.done; + } } get text() { diff --git a/examples/ReactExample/components/todo-listview.js b/examples/ReactExample/components/todo-listview.js index 4f94612a..f3904cc6 100644 --- a/examples/ReactExample/components/todo-listview.js +++ b/examples/ReactExample/components/todo-listview.js @@ -73,7 +73,7 @@ export default class TodoListView extends React.Component { render() { return ( - + Press Cmd+R to reload,{'\n'} Cmd+D for dev menu diff --git a/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj b/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj index ffc6720b..193e603d 100644 --- a/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj +++ b/examples/ReactExample/ios/ReactExample.xcodeproj/project.pbxproj @@ -5,7 +5,6 @@ }; objectVersion = 46; objects = { - /* Begin PBXBuildFile section */ 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; @@ -28,6 +27,7 @@ 8573DE511E23DDA700914396 /* ReactExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8573DE501E23DDA700914396 /* ReactExampleTests.m */; }; B06E5AD59A024665BD24C8C7 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C4594A7EF1647D68ADF0ED0 /* libz.tbd */; }; EF9CDEC26BA64438B1A9F856 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C202449017C94855B351AE73 /* libc++.tbd */; }; + F5A48833F58A45B2A8E9F550 /* libRNExitApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F25C98ECB41447FB9BA11E19 /* libRNExitApp.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -253,6 +253,8 @@ 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 8573DE501E23DDA700914396 /* ReactExampleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactExampleTests.m; sourceTree = ""; }; C202449017C94855B351AE73 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + A07E5AD22EFC47D594326945 /* RNExitApp.xcodeproj */ = {isa = PBXFileReference; name = "RNExitApp.xcodeproj"; path = "../node_modules/react-native-exit-app-no-history/ios/RNExitApp.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + F25C98ECB41447FB9BA11E19 /* libRNExitApp.a */ = {isa = PBXFileReference; name = "libRNExitApp.a"; path = "libRNExitApp.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -282,6 +284,7 @@ 146834051AC3E58100842450 /* libReact.a in Frameworks */, 70C063557D0D491D8F4D348F /* libRealmReact.a in Frameworks */, B06E5AD59A024665BD24C8C7 /* libz.tbd in Frameworks */, + F5A48833F58A45B2A8E9F550 /* libRNExitApp.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -447,6 +450,7 @@ 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 73AD103601A44EB291AC2117 /* RealmReact.xcodeproj */, + A07E5AD22EFC47D594326945 /* RNExitApp.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -891,6 +895,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactExample.app/ReactExample"; @@ -908,6 +913,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactExample.app/ReactExample"; diff --git a/examples/ReactExample/package.json b/examples/ReactExample/package.json index 8fa0b93b..0c61f8ce 100644 --- a/examples/ReactExample/package.json +++ b/examples/ReactExample/package.json @@ -9,8 +9,8 @@ "dependencies": { "react": "16.0.0", "react-native": "0.50.4", - "react-native-deprecated-custom-components": "^0.1.1", - "react-navigation": "^1.0.0-beta.19", + "react-navigation": "^1.0.0-beta.21", + "react-native-exit-app-no-history": "^1.0.2", "realm": "file:../.." }, "devDependencies": { diff --git a/scripts/test.sh b/scripts/test.sh index 96c29ba0..df92e5fc 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -255,8 +255,11 @@ case "$TARGET" in open_chrome start_packager + echo "{ \"test\" : true }" > $(pwd)/components/params.json pushd ios xctest ReactExample + popd + echo "{}" > $(pwd)/components/params.json ;; "react-tests-android") npm run check-environment From 106cf09c278102ceb3f559ccc5d7408e78af84bf Mon Sep 17 00:00:00 2001 From: blagoev Date: Wed, 13 Dec 2017 22:48:48 +0200 Subject: [PATCH 16/17] remove commented code --- .../ReactExample/components/items-screen.js | 43 +------------------ .../ReactExample/components/todo-itemsview.js | 7 --- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/examples/ReactExample/components/items-screen.js b/examples/ReactExample/components/items-screen.js index 02d2f095..5d7abfc9 100644 --- a/examples/ReactExample/components/items-screen.js +++ b/examples/ReactExample/components/items-screen.js @@ -54,51 +54,10 @@ export default class ItemsScreen extends React.Component { } render() { - // let objects = realm.objects('Todo'); - // let extraItems = [ - // { name: 'Complete', items: objects.filtered('done = true') }, - // { name: 'Incomplete', items: objects.filtered('done = false') }, - // ]; - + let properties = { - // ref: 'listView', - // extraItems: extraItems, - // onPressItem: this._onPressTodoList, } return ; } - - // renderScene(route) { - // console.log(this.todoLists); - // return - // } - - - - // _onPressTodoItem(list) { - // const { navigate } = this.props.navigation; - // let items = list.items; - - // let route = { - // title: list.name, - // component: TodoListView, - // passProps: { - // ref: 'listItemView', - // items: items, - // rowClass: TodoItem, - // }, - // }; - - // // Check if the items are mutable (i.e. List rather than Results). - // if (items.push) { - // Object.assign(route, { - // rightButtonTitle: 'Add', - // onRightButtonPress: () => this._addNewTodoItem(list), - // }); - // } - - // // this.refs.nav.push(route); - // navigate('TodoListItem', { items: items }) - // } } \ No newline at end of file diff --git a/examples/ReactExample/components/todo-itemsview.js b/examples/ReactExample/components/todo-itemsview.js index 404c1e0c..686e6107 100644 --- a/examples/ReactExample/components/todo-itemsview.js +++ b/examples/ReactExample/components/todo-itemsview.js @@ -86,13 +86,6 @@ export default class TodoItemsView extends React.Component { let RowClass; let editing = false; - // if (sectionIndex == 0) { - // RowClass = this.props.rowClass || TodoListItem; - // editing = this.state.editingRow == rowIndex; - // } else if (sectionIndex == 1) { - // RowClass = TodoListExtraItem; - // } - return ( Date: Thu, 14 Dec 2017 12:17:49 +0200 Subject: [PATCH 17/17] fix android test app build and the script for android tests address review comments --- .gitignore | 1 + .../ReactExample/components/items-screen.js | 2 +- examples/ReactExample/components/styles.js | 2 -- examples/ReactExample/components/todo-app.js | 4 +--- scripts/react-tests-android.js | 2 +- scripts/test.sh | 23 +++++++++++++------ tests/react-test-app/android/app/build.gradle | 4 ++-- .../realm/react/testapp/MainApplication.java | 2 +- tests/react-test-app/android/settings.gradle | 1 + tests/react-test-app/index.android.js | 15 +++++++++--- tests/react-test-app/index.ios.js | 4 ++-- 11 files changed, 38 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 779d6a36..742ae0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ packager_out.txt build.log.* realm-object-server/ tests/react-test-app/ios/out.txt +*.iml diff --git a/examples/ReactExample/components/items-screen.js b/examples/ReactExample/components/items-screen.js index 5d7abfc9..15bba8cb 100644 --- a/examples/ReactExample/components/items-screen.js +++ b/examples/ReactExample/components/items-screen.js @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////// // -// Copyright 2016 Realm Inc. +// Copyright 2017 Realm Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/examples/ReactExample/components/styles.js b/examples/ReactExample/components/styles.js index 32f8f00b..25a9eecf 100644 --- a/examples/ReactExample/components/styles.js +++ b/examples/ReactExample/components/styles.js @@ -22,9 +22,7 @@ import { Platform, StyleSheet } from 'react-native'; -// import NavigationExperimental from 'react-native-deprecated-custom-components'; -// const { NavBarHeight, TotalNavHeight } = NavigationExperimental.Navigator.NavigationBar.Styles.General; const iOS = (Platform.OS == 'ios'); diff --git a/examples/ReactExample/components/todo-app.js b/examples/ReactExample/components/todo-app.js index cd8b4bd6..30cb5dd5 100644 --- a/examples/ReactExample/components/todo-app.js +++ b/examples/ReactExample/components/todo-app.js @@ -35,7 +35,6 @@ import ItemsScreen from './items-screen' import realm from './realm'; import styles from './styles'; -// import NavigationExperimental from 'react-native-deprecated-custom-components'; import { StackNavigator } from 'react-navigation'; import RNExitApp from 'react-native-exit-app-no-history'; @@ -59,7 +58,7 @@ class HomeScreen extends React.Component { this.todoLists.addListener((name, changes) => { console.log("changed: " + JSON.stringify(changes)); if (params) { - console.error("params.json indicate a test run. Exiting application"); + console.error("params.json indicates a test run. Exiting application"); RNExitApp.exitApp(); } }); @@ -67,7 +66,6 @@ class HomeScreen extends React.Component { // Bind all the methods that we will be passing as props. - // this.renderScene = this.renderScene.bind(this); this._addNewTodoList = this._addNewTodoList.bind(this); this._onPressTodoList = this._onPressTodoList.bind(this); diff --git a/scripts/react-tests-android.js b/scripts/react-tests-android.js index 798619d0..124d5e1e 100644 --- a/scripts/react-tests-android.js +++ b/scripts/react-tests-android.js @@ -64,6 +64,6 @@ shell.exec("adb shell am start -n io.realm.react.testapp/.MainActivity"); shell.popd(); -shell.exec("adb shell \"logcat -c && logcat | grep -m 1 __REALM_REACT_ANDROID_TESTS_COMPLETED__\""); +shell.exec("adb shell \"logcat -c && logcat | grep -m 1 __REALM_JS_TESTS_COMPLETED__\""); shell.exec("adb pull /sdcard/tests.xml"); \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index df92e5fc..59c871b3 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -66,7 +66,7 @@ stop_server() { echo stopping server if [[ ${SERVER_PID} -gt 0 ]] ; then echo server is running. killing it - kill -9 ${SERVER_PID} || true + kill -9 ${SERVER_PID} >/dev/null 2>&1 || true fi } @@ -104,7 +104,7 @@ cleanup() { open_chrome() { if [ $CONFIGURATION == 'Release' ]; then - break + return; fi local dir @@ -152,6 +152,10 @@ xctest() { echo "Shuttting down ${SIM_DEVICE_NAME} simulator. (device is not deleted. you can use it to debug the app)" shutdown_ios_simulator + check_test_results $1 +} + +check_test_results() { echo "Checking tests results" if grep -q "REALM_FAILING_TESTS" $(pwd)/build/out.txt; then echo "*** REALM JS TESTS FAILED. See tests results above ***" @@ -167,7 +171,7 @@ setup_ios_simulator() { delete_ios_simulator >/dev/null 2>&1 #parse devices - IOS_RUNTIME=$(xcrun simctl list runtimes | grep -m1 -o '(com.apple.CoreSimulator.SimRuntime.iOS.*)' | sed 's/[()]//g') + IOS_RUNTIME=$(xcrun simctl list runtimes | grep -m1 -o 'com.apple.CoreSimulator.SimRuntime.iOS.*' | sed 's/[()]//g') echo using iOS Runtime ${IOS_RUNTIME} to create new simulator ${SIM_DEVICE_NAME} #create new test simulator @@ -271,21 +275,25 @@ case "$TARGET" in [[ $CONFIGURATION == 'Debug' ]] && exit 0 XCPRETTY='' - pushd tests/react-test-app + pushd react-native/android + $(pwd)/gradlew publishAndroid + popd + pushd tests/react-test-app npm install echo "Resetting logcat" # Despite the docs claiming -c to work, it doesn't, so `-T 1` alleviates that. + mkdir -p $(pwd)/build || true adb logcat -c - adb logcat -T 1 | tee "$LOGCAT_OUT" & + adb logcat -T 1 | tee "$LOGCAT_OUT" | tee $(pwd)/build/out.txt & ./run-android.sh echo "Start listening for Test completion" while :; do - if grep -q "__REALM_REACT_ANDROID_TESTS_COMPLETED__" "$LOGCAT_OUT"; then + if grep -q "__REALM_JS_TESTS_COMPLETED__" "$LOGCAT_OUT"; then break else echo "Waiting for tests." @@ -301,7 +309,8 @@ case "$TARGET" in echo "********* TESTS COMPLETED *********"; echo "********* File location: $(pwd)/tests.xml *********"; cat tests.xml - + + check_test_results ReactTests ;; "node") npm run check-environment diff --git a/tests/react-test-app/android/app/build.gradle b/tests/react-test-app/android/app/build.gradle index bec27402..02f202a0 100644 --- a/tests/react-test-app/android/app/build.gradle +++ b/tests/react-test-app/android/app/build.gradle @@ -137,13 +137,13 @@ android { } dependencies { - compile project(':react-native-exception-handler') - compile project(':react-native-exit-app-no-history') compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules compile project(":realm") compile project(":react-native-fs") + compile project(':react-native-exception-handler') + compile project(':react-native-exit-app-no-history') } // Run this once to be able to run the application with BUCK diff --git a/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java b/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java index 977b654f..5e7a2ca2 100644 --- a/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java +++ b/tests/react-test-app/android/app/src/main/java/io/realm/react/testapp/MainApplication.java @@ -22,7 +22,7 @@ public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override - protected boolean getUseDeveloperSupport() { + public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } diff --git a/tests/react-test-app/android/settings.gradle b/tests/react-test-app/android/settings.gradle index 98eee976..9c5c13ed 100644 --- a/tests/react-test-app/android/settings.gradle +++ b/tests/react-test-app/android/settings.gradle @@ -10,5 +10,6 @@ project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/ include ':react-native-exception-handler' project(':react-native-exception-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exception-handler/android') + include ':react-native-exit-app-no-history' project(':react-native-exit-app-no-history').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-exit-app-no-history/android') diff --git a/tests/react-test-app/index.android.js b/tests/react-test-app/index.android.js index 6e01d26b..3380a2f0 100644 --- a/tests/react-test-app/index.android.js +++ b/tests/react-test-app/index.android.js @@ -33,13 +33,13 @@ import { getTestNames, runTest } from './tests'; async function runTests() { let testNames = getTestNames(); let rootXml = builder.create('testsuites'); - + let failingTests = []; for (let suiteName in testNames) { let itemTestsuite = rootXml.ele('testsuite'); let nbrTests = 0; let nbrFailures = 0; - console.log('Starting ' + suiteName); + console.error('Starting ' + suiteName); for (let testName of testNames[suiteName]) { nbrTests++; @@ -51,6 +51,7 @@ async function runTests() { await runTest(suiteName, testName); } catch (e) { + failingTests.push(`${suiteName}: ${testName} : Error ${e.message}`); itemTest.ele('error', {'message': e.message, 'stacktrace': e.stack}, e.toString()); nbrFailures++; } @@ -73,11 +74,19 @@ async function runTests() { // write the unit tests reports try { await RNFS.writeFile('/sdcard/tests.xml', xmlString, 'utf8'); - console.log('__REALM_REACT_ANDROID_TESTS_COMPLETED__'); + console.log('__REALM_JS_TESTS_COMPLETED__'); + if (failingTests.length !== 0) { + console.error('\n\nREALM_FAILING_TESTS\n'); + console.error(failingTests); + } } catch (e) { console.error(e); } + finally { + console.warn("Realm Tests App finished. Exiting. Disable this to debug the app locally"); + RNExitApp.exitApp(); + } } class ReactTests extends React.Component { diff --git a/tests/react-test-app/index.ios.js b/tests/react-test-app/index.ios.js index f12ced2b..b7bc0e70 100644 --- a/tests/react-test-app/index.ios.js +++ b/tests/react-test-app/index.ios.js @@ -99,7 +99,7 @@ async function runTests() { //using console.log output is not shown in Release builds. using console.warn console.warn(xmlString); - console.warn('__REALM_REACT_IOS_TESTS_COMPLETED__'); + console.warn('__REALM_JS_TESTS_COMPLETED__'); if (failingTests.length !== 0) { console.error('\n\nREALM_FAILING_TESTS\n'); console.error(failingTests); @@ -109,7 +109,7 @@ async function runTests() { console.error(e); } finally { - console.warn("Realm iOS Tests App finished. Exiting. Disable this to debug the app locally"); + console.warn("Realm Tests App finished. Exiting. Disable this to debug the app locally"); RNExitApp.exitApp(); } }