From 94fb79c17f00a7dce76486d60252743648c78256 Mon Sep 17 00:00:00 2001 From: Joe Bowser Date: Wed, 6 Nov 2013 15:04:47 -0800 Subject: [PATCH] CB-5302: Massive movement to get tests working again --- test/.classpath | 1 + test/AndroidManifest.xml | 40 +- test/assets/www/cordova_plugins.js | 11 + test/assets/www/index.html | 34 +- .../org.apache.cordova.device/www/device.js | 78 + test/cordova/android_sdk_version | 29 + test/cordova/build | 37 + test/cordova/build.bat | 26 + test/cordova/check_reqs | 28 + test/cordova/clean | 36 + test/cordova/clean.bat | 26 + test/cordova/lib/android_sdk_version.js | 65 + test/cordova/lib/appinfo.js | 41 + test/cordova/lib/build.js | 87 + test/cordova/lib/check_reqs.js | 94 + test/cordova/lib/clean.js | 38 + test/cordova/lib/device.js | 86 + test/cordova/lib/emulator.js | 330 +++ test/cordova/lib/exec.js | 43 + test/cordova/lib/install-device | 42 + test/cordova/lib/install-device.bat | 26 + test/cordova/lib/install-emulator | 38 + test/cordova/lib/install-emulator.bat | 26 + test/cordova/lib/list-devices | 33 + test/cordova/lib/list-devices.bat | 26 + test/cordova/lib/list-emulator-images | 32 + test/cordova/lib/list-emulator-images.bat | 26 + test/cordova/lib/list-started-emulators | 32 + test/cordova/lib/list-started-emulators.bat | 26 + test/cordova/lib/log.js | 57 + test/cordova/lib/run.js | 139 + test/cordova/lib/start-emulator | 39 + test/cordova/lib/start-emulator.bat | 26 + test/cordova/log | 36 + test/cordova/log.bat | 26 + test/cordova/node_modules/.bin/shjs | 1 + test/cordova/node_modules/q/CONTRIBUTING.md | 40 + test/cordova/node_modules/q/LICENSE | 19 + test/cordova/node_modules/q/README.md | 813 ++++++ .../q/benchmark/compare-with-callbacks.js | 71 + .../node_modules/q/benchmark/scenarios.js | 36 + test/cordova/node_modules/q/package.json | 93 + test/cordova/node_modules/q/q.js | 1937 +++++++++++++ test/cordova/node_modules/q/queue.js | 35 + .../node_modules/shelljs/.documentup.json | 6 + test/cordova/node_modules/shelljs/.jshintrc | 7 + test/cordova/node_modules/shelljs/.npmignore | 2 + test/cordova/node_modules/shelljs/.travis.yml | 5 + test/cordova/node_modules/shelljs/LICENSE | 26 + test/cordova/node_modules/shelljs/README.md | 552 ++++ test/cordova/node_modules/shelljs/bin/shjs | 51 + test/cordova/node_modules/shelljs/global.js | 3 + test/cordova/node_modules/shelljs/make.js | 47 + .../cordova/node_modules/shelljs/package.json | 48 + .../shelljs/scripts/generate-docs.js | 21 + .../node_modules/shelljs/scripts/run-tests.js | 50 + test/cordova/node_modules/shelljs/shell.js | 153 + test/cordova/node_modules/shelljs/src/cat.js | 43 + test/cordova/node_modules/shelljs/src/cd.js | 19 + .../cordova/node_modules/shelljs/src/chmod.js | 208 ++ .../node_modules/shelljs/src/common.js | 189 ++ test/cordova/node_modules/shelljs/src/cp.js | 200 ++ test/cordova/node_modules/shelljs/src/dirs.js | 191 ++ test/cordova/node_modules/shelljs/src/echo.js | 20 + .../cordova/node_modules/shelljs/src/error.js | 10 + test/cordova/node_modules/shelljs/src/exec.js | 181 ++ test/cordova/node_modules/shelljs/src/find.js | 51 + test/cordova/node_modules/shelljs/src/grep.js | 52 + test/cordova/node_modules/shelljs/src/ls.js | 126 + .../cordova/node_modules/shelljs/src/mkdir.js | 68 + test/cordova/node_modules/shelljs/src/mv.js | 80 + test/cordova/node_modules/shelljs/src/popd.js | 1 + .../cordova/node_modules/shelljs/src/pushd.js | 1 + test/cordova/node_modules/shelljs/src/pwd.js | 11 + test/cordova/node_modules/shelljs/src/rm.js | 145 + test/cordova/node_modules/shelljs/src/sed.js | 43 + .../node_modules/shelljs/src/tempdir.js | 56 + test/cordova/node_modules/shelljs/src/test.js | 85 + test/cordova/node_modules/shelljs/src/to.js | 29 + .../cordova/node_modules/shelljs/src/toEnd.js | 29 + .../cordova/node_modules/shelljs/src/which.js | 79 + test/cordova/plugins/android.json | 1 + .../org.apache.cordova.device/.fetch.json | 1 + .../plugins/org.apache.cordova.device/LICENSE | 202 ++ .../org.apache.cordova.device/README.md | 5 + .../org.apache.cordova.device/RELEASENOTES.md | 40 + .../docs/device.cordova.md | 80 + .../org.apache.cordova.device/docs/device.md | 104 + .../docs/device.model.md | 106 + .../docs/device.name.md | 108 + .../docs/device.platform.md | 99 + .../docs/device.uuid.md | 115 + .../docs/device.version.md | 86 + .../org.apache.cordova.device/plugin.xml | 103 + .../src/android/Device.java | 200 ++ .../src/blackberry10/index.js | 69 + .../src/firefoxos/DeviceProxy.js | 39 + .../src/ios/CDVDevice.h | 30 + .../src/ios/CDVDevice.m | 90 + .../src/windows8/DeviceProxy.js | 50 + .../src/wp/Device.cs | 135 + .../test/autotest/html/HtmlReporter.js | 101 + .../test/autotest/html/HtmlReporterHelpers.js | 60 + .../test/autotest/html/ReporterView.js | 164 ++ .../test/autotest/html/SpecView.js | 79 + .../test/autotest/html/SuiteView.js | 22 + .../test/autotest/html/TrivialReporter.js | 192 ++ .../test/autotest/index.html | 59 + .../test/autotest/jasmine.css | 81 + .../test/autotest/jasmine.js | 2530 +++++++++++++++++ .../test/autotest/pages/device.html | 71 + .../test/autotest/test-runner.js | 62 + .../test/autotest/tests/device.tests.js | 64 + .../test/cordova-incl.js | 85 + .../org.apache.cordova.device/test/index.html | 66 + .../org.apache.cordova.device/test/main.js | 163 ++ .../org.apache.cordova.device/test/master.css | 164 ++ .../org.apache.cordova.device/www/device.js | 77 + test/cordova/run | 37 + test/cordova/run.bat | 26 + test/cordova/version | 25 + test/cordova/version.bat | 26 + test/res/xml/config.xml | 46 +- .../src/org/apache/cordova/device/Device.java | 200 ++ .../test/{actions => }/CordovaActivity.java | 2 +- .../{actions => }/CordovaDriverAction.java | 2 +- .../CordovaWebViewTestActivity.java | 2 +- .../{actions => }/backbuttonmultipage.java | 2 +- .../test/{actions => }/background.java | 2 +- .../test/{actions => }/backgroundcolor.java | 2 +- .../cordova/test/{actions => }/basicauth.java | 2 +- .../cordova/test/{actions => }/errorurl.java | 2 +- .../test/{actions => }/fullscreen.java | 2 +- .../test/{actions => }/htmlnotfound.java | 2 +- .../cordova/test/{actions => }/iframe.java | 2 +- .../{ => junit}/BackButtonMultiPageTest.java | 4 +- .../test/{ => junit}/CordovaActivityTest.java | 4 +- .../{ => junit}/CordovaResourceApiTest.java | 5 +- .../cordova/test/{ => junit}/CordovaTest.java | 5 +- .../test/{ => junit}/ErrorUrlTest.java | 4 +- .../cordova/test/{ => junit}/FixWebView.java | 2 +- .../test/{ => junit}/GapClientTest.java | 4 +- .../test/{ => junit}/HtmlNotFoundTest.java | 4 +- .../cordova/test/{ => junit}/IFrameTest.java | 4 +- .../test/{ => junit}/LifecycleTest.java | 4 +- .../cordova/test/{ => junit}/MenuTest.java | 4 +- .../test/{ => junit}/PluginManagerTest.java | 4 +- .../test/{ => junit}/SplashscreenTest.java | 4 +- .../test/{ => junit}/UserWebViewTest.java | 4 +- .../cordova/test/{ => junit}/XhrTest.java | 4 +- .../cordova/test/{actions => }/lifecycle.java | 2 +- .../cordova/test/{actions => }/loading.java | 2 +- .../cordova/test/{actions => }/menus.java | 2 +- .../test/{actions => }/splashscreen.java | 2 +- .../cordova/test/{actions => }/tests.java | 2 +- .../cordova/test/{actions => }/timeout.java | 2 +- .../test/{actions => }/userwebview.java | 2 +- .../cordova/test/{actions => }/whitelist.java | 2 +- .../cordova/test/{actions => }/xhr.java | 2 +- 159 files changed, 13733 insertions(+), 123 deletions(-) create mode 100644 test/assets/www/cordova_plugins.js create mode 100644 test/assets/www/plugins/org.apache.cordova.device/www/device.js create mode 100755 test/cordova/android_sdk_version create mode 100755 test/cordova/build create mode 100644 test/cordova/build.bat create mode 100755 test/cordova/check_reqs create mode 100755 test/cordova/clean create mode 100644 test/cordova/clean.bat create mode 100755 test/cordova/lib/android_sdk_version.js create mode 100644 test/cordova/lib/appinfo.js create mode 100644 test/cordova/lib/build.js create mode 100644 test/cordova/lib/check_reqs.js create mode 100644 test/cordova/lib/clean.js create mode 100644 test/cordova/lib/device.js create mode 100644 test/cordova/lib/emulator.js create mode 100644 test/cordova/lib/exec.js create mode 100755 test/cordova/lib/install-device create mode 100644 test/cordova/lib/install-device.bat create mode 100755 test/cordova/lib/install-emulator create mode 100644 test/cordova/lib/install-emulator.bat create mode 100755 test/cordova/lib/list-devices create mode 100644 test/cordova/lib/list-devices.bat create mode 100755 test/cordova/lib/list-emulator-images create mode 100644 test/cordova/lib/list-emulator-images.bat create mode 100755 test/cordova/lib/list-started-emulators create mode 100644 test/cordova/lib/list-started-emulators.bat create mode 100644 test/cordova/lib/log.js create mode 100644 test/cordova/lib/run.js create mode 100755 test/cordova/lib/start-emulator create mode 100644 test/cordova/lib/start-emulator.bat create mode 100755 test/cordova/log create mode 100644 test/cordova/log.bat create mode 120000 test/cordova/node_modules/.bin/shjs create mode 100644 test/cordova/node_modules/q/CONTRIBUTING.md create mode 100644 test/cordova/node_modules/q/LICENSE create mode 100644 test/cordova/node_modules/q/README.md create mode 100644 test/cordova/node_modules/q/benchmark/compare-with-callbacks.js create mode 100644 test/cordova/node_modules/q/benchmark/scenarios.js create mode 100644 test/cordova/node_modules/q/package.json create mode 100644 test/cordova/node_modules/q/q.js create mode 100644 test/cordova/node_modules/q/queue.js create mode 100644 test/cordova/node_modules/shelljs/.documentup.json create mode 100644 test/cordova/node_modules/shelljs/.jshintrc create mode 100644 test/cordova/node_modules/shelljs/.npmignore create mode 100644 test/cordova/node_modules/shelljs/.travis.yml create mode 100644 test/cordova/node_modules/shelljs/LICENSE create mode 100644 test/cordova/node_modules/shelljs/README.md create mode 100755 test/cordova/node_modules/shelljs/bin/shjs create mode 100644 test/cordova/node_modules/shelljs/global.js create mode 100644 test/cordova/node_modules/shelljs/make.js create mode 100644 test/cordova/node_modules/shelljs/package.json create mode 100755 test/cordova/node_modules/shelljs/scripts/generate-docs.js create mode 100755 test/cordova/node_modules/shelljs/scripts/run-tests.js create mode 100644 test/cordova/node_modules/shelljs/shell.js create mode 100644 test/cordova/node_modules/shelljs/src/cat.js create mode 100644 test/cordova/node_modules/shelljs/src/cd.js create mode 100644 test/cordova/node_modules/shelljs/src/chmod.js create mode 100644 test/cordova/node_modules/shelljs/src/common.js create mode 100644 test/cordova/node_modules/shelljs/src/cp.js create mode 100644 test/cordova/node_modules/shelljs/src/dirs.js create mode 100644 test/cordova/node_modules/shelljs/src/echo.js create mode 100644 test/cordova/node_modules/shelljs/src/error.js create mode 100644 test/cordova/node_modules/shelljs/src/exec.js create mode 100644 test/cordova/node_modules/shelljs/src/find.js create mode 100644 test/cordova/node_modules/shelljs/src/grep.js create mode 100644 test/cordova/node_modules/shelljs/src/ls.js create mode 100644 test/cordova/node_modules/shelljs/src/mkdir.js create mode 100644 test/cordova/node_modules/shelljs/src/mv.js create mode 100644 test/cordova/node_modules/shelljs/src/popd.js create mode 100644 test/cordova/node_modules/shelljs/src/pushd.js create mode 100644 test/cordova/node_modules/shelljs/src/pwd.js create mode 100644 test/cordova/node_modules/shelljs/src/rm.js create mode 100644 test/cordova/node_modules/shelljs/src/sed.js create mode 100644 test/cordova/node_modules/shelljs/src/tempdir.js create mode 100644 test/cordova/node_modules/shelljs/src/test.js create mode 100644 test/cordova/node_modules/shelljs/src/to.js create mode 100644 test/cordova/node_modules/shelljs/src/toEnd.js create mode 100644 test/cordova/node_modules/shelljs/src/which.js create mode 100644 test/cordova/plugins/android.json create mode 100644 test/cordova/plugins/org.apache.cordova.device/.fetch.json create mode 100644 test/cordova/plugins/org.apache.cordova.device/LICENSE create mode 100644 test/cordova/plugins/org.apache.cordova.device/README.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/RELEASENOTES.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.cordova.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.model.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.name.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.platform.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.uuid.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/docs/device.version.md create mode 100644 test/cordova/plugins/org.apache.cordova.device/plugin.xml create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/android/Device.java create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/blackberry10/index.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.h create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.m create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/src/wp/Device.cs create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporter.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporterHelpers.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/ReporterView.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SpecView.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SuiteView.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/html/TrivialReporter.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/index.html create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.css create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/pages/device.html create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/test-runner.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/autotest/tests/device.tests.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/cordova-incl.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/index.html create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/main.js create mode 100644 test/cordova/plugins/org.apache.cordova.device/test/master.css create mode 100644 test/cordova/plugins/org.apache.cordova.device/www/device.js create mode 100755 test/cordova/run create mode 100644 test/cordova/run.bat create mode 100755 test/cordova/version create mode 100644 test/cordova/version.bat create mode 100644 test/src/org/apache/cordova/device/Device.java rename test/src/org/apache/cordova/test/{actions => }/CordovaActivity.java (96%) rename test/src/org/apache/cordova/test/{actions => }/CordovaDriverAction.java (98%) rename test/src/org/apache/cordova/test/{actions => }/CordovaWebViewTestActivity.java (98%) rename test/src/org/apache/cordova/test/{actions => }/backbuttonmultipage.java (96%) rename test/src/org/apache/cordova/test/{actions => }/background.java (96%) rename test/src/org/apache/cordova/test/{actions => }/backgroundcolor.java (97%) rename test/src/org/apache/cordova/test/{actions => }/basicauth.java (97%) rename test/src/org/apache/cordova/test/{actions => }/errorurl.java (96%) rename test/src/org/apache/cordova/test/{actions => }/fullscreen.java (97%) rename test/src/org/apache/cordova/test/{actions => }/htmlnotfound.java (96%) rename test/src/org/apache/cordova/test/{actions => }/iframe.java (96%) rename test/src/org/apache/cordova/test/{ => junit}/BackButtonMultiPageTest.java (98%) rename test/src/org/apache/cordova/test/{ => junit}/CordovaActivityTest.java (97%) rename test/src/org/apache/cordova/test/{ => junit}/CordovaResourceApiTest.java (98%) rename test/src/org/apache/cordova/test/{ => junit}/CordovaTest.java (96%) rename test/src/org/apache/cordova/test/{ => junit}/ErrorUrlTest.java (96%) rename test/src/org/apache/cordova/test/{ => junit}/FixWebView.java (97%) rename test/src/org/apache/cordova/test/{ => junit}/GapClientTest.java (95%) rename test/src/org/apache/cordova/test/{ => junit}/HtmlNotFoundTest.java (96%) rename test/src/org/apache/cordova/test/{ => junit}/IFrameTest.java (97%) rename test/src/org/apache/cordova/test/{ => junit}/LifecycleTest.java (92%) rename test/src/org/apache/cordova/test/{ => junit}/MenuTest.java (93%) rename test/src/org/apache/cordova/test/{ => junit}/PluginManagerTest.java (95%) rename test/src/org/apache/cordova/test/{ => junit}/SplashscreenTest.java (94%) rename test/src/org/apache/cordova/test/{ => junit}/UserWebViewTest.java (96%) rename test/src/org/apache/cordova/test/{ => junit}/XhrTest.java (92%) rename test/src/org/apache/cordova/test/{actions => }/lifecycle.java (96%) rename test/src/org/apache/cordova/test/{actions => }/loading.java (96%) rename test/src/org/apache/cordova/test/{actions => }/menus.java (98%) rename test/src/org/apache/cordova/test/{actions => }/splashscreen.java (97%) rename test/src/org/apache/cordova/test/{actions => }/tests.java (96%) rename test/src/org/apache/cordova/test/{actions => }/timeout.java (96%) rename test/src/org/apache/cordova/test/{actions => }/userwebview.java (98%) rename test/src/org/apache/cordova/test/{actions => }/whitelist.java (97%) rename test/src/org/apache/cordova/test/{actions => }/xhr.java (96%) diff --git a/test/.classpath b/test/.classpath index a4763d1e..bb0c7597 100644 --- a/test/.classpath +++ b/test/.classpath @@ -4,5 +4,6 @@ + diff --git a/test/AndroidManifest.xml b/test/AndroidManifest.xml index 878dd256..50ad03c4 100755 --- a/test/AndroidManifest.xml +++ b/test/AndroidManifest.xml @@ -59,7 +59,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.CordovaWebViewTestActivity" > + android:name="org.apache.cordova.test.CordovaWebViewTestActivity" > @@ -69,7 +69,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.background" > + android:name="org.apache.cordova.test.background" > @@ -79,7 +79,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.backgroundcolor" > + android:name="org.apache.cordova.test.backgroundcolor" > @@ -89,7 +89,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.basicauth" > + android:name="org.apache.cordova.test.basicauth" > @@ -99,7 +99,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.CordovaActivity" > + android:name="org.apache.cordova.test.CordovaActivity" > @@ -109,7 +109,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.CordovaDriverAction" > + android:name="org.apache.cordova.test.CordovaDriverAction" > @@ -119,7 +119,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.errorurl" > + android:name="org.apache.cordova.test.errorurl" > @@ -129,7 +129,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.fullscreen" > + android:name="org.apache.cordova.test.fullscreen" > @@ -139,7 +139,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.htmlnotfound" > + android:name="org.apache.cordova.test.htmlnotfound" > @@ -149,7 +149,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.iframe" > + android:name="org.apache.cordova.test.iframe" > @@ -159,7 +159,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.lifecycle" > + android:name="org.apache.cordova.test.lifecycle" > @@ -169,7 +169,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.loading" > + android:name="org.apache.cordova.test.loading" > @@ -179,7 +179,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.menus" > + android:name="org.apache.cordova.test.menus" > @@ -189,7 +189,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.splashscreen" > + android:name="org.apache.cordova.test.splashscreen" > @@ -199,7 +199,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.tests" > + android:name="org.apache.cordova.test.tests" > @@ -209,7 +209,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.timeout" > + android:name="org.apache.cordova.test.timeout" > @@ -219,7 +219,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.userwebview" > + android:name="org.apache.cordova.test.userwebview" > @@ -229,7 +229,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.whitelist" > + android:name="org.apache.cordova.test.whitelist" > @@ -239,7 +239,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.xhr" > + android:name="org.apache.cordova.test.xhr" > @@ -249,7 +249,7 @@ android:windowSoftInputMode="adjustPan" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" - android:name=".actions.backbuttonmultipage" > + android:name="org.apache.cordova.test.backbuttonmultipage" > diff --git a/test/assets/www/cordova_plugins.js b/test/assets/www/cordova_plugins.js new file mode 100644 index 00000000..f23dd64d --- /dev/null +++ b/test/assets/www/cordova_plugins.js @@ -0,0 +1,11 @@ +cordova.define('cordova/plugin_list', function(require, exports, module) { +module.exports = [ + { + "file": "plugins/org.apache.cordova.device/www/device.js", + "id": "org.apache.cordova.device.device", + "clobbers": [ + "device" + ] + } +] +}); \ No newline at end of file diff --git a/test/assets/www/index.html b/test/assets/www/index.html index 13f08251..590b5939 100755 --- a/test/assets/www/index.html +++ b/test/assets/www/index.html @@ -47,22 +47,22 @@

Run each of the test activities below:

- - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/test/assets/www/plugins/org.apache.cordova.device/www/device.js b/test/assets/www/plugins/org.apache.cordova.device/www/device.js new file mode 100644 index 00000000..c0697f60 --- /dev/null +++ b/test/assets/www/plugins/org.apache.cordova.device/www/device.js @@ -0,0 +1,78 @@ +cordova.define("org.apache.cordova.device.device", function(require, exports, module) {/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +var argscheck = require('cordova/argscheck'), + channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'), + cordova = require('cordova'); + +channel.createSticky('onCordovaInfoReady'); +// Tell cordova channel to wait on the CordovaInfoReady event +channel.waitForInitialization('onCordovaInfoReady'); + +/** + * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = false; + this.platform = null; + this.version = null; + this.uuid = null; + this.cordova = null; + this.model = null; + + var me = this; + + channel.onCordovaReady.subscribe(function() { + me.getInfo(function(info) { + //ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js + //TODO: CB-5105 native implementations should not return info.cordova + var buildLabel = cordova.version; + me.available = true; + me.platform = info.platform; + me.version = info.version; + me.uuid = info.uuid; + me.cordova = buildLabel; + me.model = info.model; + channel.onCordovaInfoReady.fire(); + },function(e) { + me.available = false; + utils.alert("[ERROR] Error initializing Cordova: " + e); + }); + }); +} + +/** + * Get device info + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) + */ +Device.prototype.getInfo = function(successCallback, errorCallback) { + argscheck.checkArgs('fF', 'Device.getInfo', arguments); + exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); +}; + +module.exports = new Device(); +}); diff --git a/test/cordova/android_sdk_version b/test/cordova/android_sdk_version new file mode 100755 index 00000000..547f41bd --- /dev/null +++ b/test/cordova/android_sdk_version @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var android_sdk_version = require('./lib/android_sdk_version'); + +android_sdk_version.run().done(null, function(err) { + console.log(err); + process.exit(2); +}); + + diff --git a/test/cordova/build b/test/cordova/build new file mode 100755 index 00000000..a38f3b63 --- /dev/null +++ b/test/cordova/build @@ -0,0 +1,37 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var build = require('./lib/build'), + reqs = require('./lib/check_reqs'), + args = process.argv; + +// Support basic help commands +if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' || + args[2] == 'help' || args[2] == '-help' || args[2] == '/help') { + build.help(); +} else { + reqs.run().then(function() { + return build.run(args[2]); + }).done(null, function(err) { + console.error(err); + process.exit(2); + }); +} diff --git a/test/cordova/build.bat b/test/cordova/build.bat new file mode 100644 index 00000000..2f317e3b --- /dev/null +++ b/test/cordova/build.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0build" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'build' script in 'cordova' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/check_reqs b/test/cordova/check_reqs new file mode 100755 index 00000000..2ac87521 --- /dev/null +++ b/test/cordova/check_reqs @@ -0,0 +1,28 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var check_reqs = require('./lib/check_reqs'); + +check_reqs.run().done(null, function(err) { + console.log(err); + process.exit(2); +}); + diff --git a/test/cordova/clean b/test/cordova/clean new file mode 100755 index 00000000..4e0808bf --- /dev/null +++ b/test/cordova/clean @@ -0,0 +1,36 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var clean = require('./lib/clean'), + reqs = require('./lib/check_reqs'), + args = process.argv; + +// Usage support for when args are given +if(args.length > 2) { + clean.help(); +} else { + reqs.run().done(function() { + return clean.run(); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +} diff --git a/test/cordova/clean.bat b/test/cordova/clean.bat new file mode 100644 index 00000000..fa1f669a --- /dev/null +++ b/test/cordova/clean.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0clean" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'clean' script in 'cordova' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/lib/android_sdk_version.js b/test/cordova/lib/android_sdk_version.js new file mode 100755 index 00000000..d03e1e7d --- /dev/null +++ b/test/cordova/lib/android_sdk_version.js @@ -0,0 +1,65 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var shell = require('shelljs'), + child_process = require('child_process'), + Q = require('q'); + +get_highest_sdk = function(results){ + var reg = /\d+/; + var apiLevels = []; + for(var i=0;i/.exec(manifestData); + if (!activityTag) throw new Error('Could not find within ' + manifestPath); + var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag); + if (!activityName) throw new Error('Could not find android:name within ' + manifestPath); + + return packageName[1] + '/.' + activityName[1]; +} + +exports.getActivityName = function() { + return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest(); +}; diff --git a/test/cordova/lib/build.js b/test/cordova/lib/build.js new file mode 100644 index 00000000..e57e26b8 --- /dev/null +++ b/test/cordova/lib/build.js @@ -0,0 +1,87 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var shell = require('shelljs'), + exec = require('./exec'), + Q = require('q'), + clean = require('./clean'), + path = require('path'), + fs = require('fs'), + ROOT = path.join(__dirname, '..', '..'); + +/* + * Builds the project with ant. + * Returns a promise. + */ +module.exports.run = function(build_type) { + //default build type + build_type = typeof build_type !== 'undefined' ? build_type : "--debug"; + var cmd; + switch(build_type) { + case '--debug' : + cmd = 'ant debug -f ' + path.join(ROOT, 'build.xml'); + break; + case '--release' : + cmd = 'ant release -f ' + path.join(ROOT, 'build.xml'); + break; + case '--nobuild' : + console.log('Skipping build...'); + return Q(); + default : + return Q.reject('Build option \'' + build_type + '\' not recognized.'); + } + if(cmd) { + return clean.run() // TODO: Can we stop cleaning every time and let ant build incrementally? + .then(function() { + return exec(cmd); + }); + } + return Q(); +} + +/* + * Gets the path to the apk file, if not such file exists then + * the script will error out. (should we error or just return undefined?) + */ +module.exports.get_apk = function() { + if(fs.existsSync(path.join(ROOT, 'bin'))) { + var bin_files = fs.readdirSync(path.join(ROOT, 'bin')); + for (file in bin_files) { + if(path.extname(bin_files[file]) == '.apk') { + return path.join(ROOT, 'bin', bin_files[file]); + } + } + console.error('ERROR : No .apk found in \'bin\' folder'); + process.exit(2); + } else { + console.error('ERROR : unable to find project bin folder, could not locate .apk'); + process.exit(2); + } +} + +module.exports.help = function() { + console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'build')) + ' [build_type]'); + console.log('Build Types : '); + console.log(' \'--debug\': Default build, will build project in using ant debug'); + console.log(' \'--release\': will build project using ant release'); + console.log(' \'--nobuild\': will skip build process (can be used with run command)'); + process.exit(0); +} diff --git a/test/cordova/lib/check_reqs.js b/test/cordova/lib/check_reqs.js new file mode 100644 index 00000000..f4def798 --- /dev/null +++ b/test/cordova/lib/check_reqs.js @@ -0,0 +1,94 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var shell = require('shelljs'), + child_process = require('child_process'), + Q = require('q'), + path = require('path'), + fs = require('fs'), + ROOT = path.join(__dirname, '..', '..'); + +// Get valid target from framework/project.properties +module.exports.get_target = function() { + if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) { + var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties')); + return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', ''); + } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) { + // if no target found, we're probably in a project and project.properties is in ROOT. + var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties')); + return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', ''); + } +} + +// Returns a promise. +module.exports.check_ant = function() { + var d = Q.defer(); + child_process.exec('ant -version', function(err, stdout, stderr) { + if (err) d.reject(new Error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.')); + else d.resolve(); + }); + return d.promise; +} + +// Returns a promise. +module.exports.check_java = function() { + if(process.env.JAVA_HOME) { + var d = Q.defer(); + child_process.exec('java -version', function(err, stdout, stderr) { + if(err) d.reject(new Error('ERROR : executing command \'java\', make sure you java environment is set up. Including your JDK and JRE.' + err)); + else d.resolve(); + }); + return d.promise; + } else { + return Q.reject(new Error('ERROR : Make sure JAVA_HOME is set, as well as paths to your JDK and JRE for java.')); + } +} + +// Returns a promise. +module.exports.check_android = function() { + var valid_target = this.get_target(); + var d = Q.defer(); + child_process.exec('android list targets', function(err, stdout, stderr) { + if (err) d.reject(stderr); + else d.resolve(stdout); + }); + + return d.promise.then(function(output) { + if (!output.match(valid_target)) { + return Q.reject(new Error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.')); + } + return Q(); + }, function(stderr) { + if (stderr.match(/command\snot\sfound/)) { + return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.')); + } else { + return Q.reject(new Error('An error occurred while listing Android targets')); + } + }); +} + +// Returns a promise. +module.exports.run = function() { + return Q.all([this.check_ant(), this.check_java(), this.check_android()]).then(function() { + console.log('Looks like your environment fully supports cordova-android development!'); + }); +} + diff --git a/test/cordova/lib/clean.js b/test/cordova/lib/clean.js new file mode 100644 index 00000000..0f955f6a --- /dev/null +++ b/test/cordova/lib/clean.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var exec = require('./exec'), + path = require('path'), + ROOT = path.join(__dirname, '..', '..'); + +/* + * Cleans the project using ant + * Returns a promise. + */ +module.exports.run = function() { + return exec('ant clean -f ' + path.join(ROOT, 'build.xml')); +} + +module.exports.help = function() { + console.log('Usage: ' + path.relative(process.cwd(), process.argv[1])); + console.log('Cleans the project directory.'); + process.exit(0); +} diff --git a/test/cordova/lib/device.js b/test/cordova/lib/device.js new file mode 100644 index 00000000..df2a33cf --- /dev/null +++ b/test/cordova/lib/device.js @@ -0,0 +1,86 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var exec = require('./exec'), + Q = require('q'), + path = require('path'), + build = require('./build'), + appinfo = require('./appinfo'), + ROOT = path.join(__dirname, '..', '..'); + +/** + * Returns a promise for the list of the device ID's found + */ +module.exports.list = function() { + return exec('adb devices') + .then(function(output) { + var response = output.split('\n'); + var device_list = []; + for (var i = 1; i < response.length; i++) { + if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) { + device_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); + } + } + return device_list; + }); +} + +/* + * Installs a previously built application on the device + * and launches it. + * Returns a promise. + */ +module.exports.install = function(target) { + var launchName; + return this.list() + .then(function(device_list) { + if (!device_list || !device_list.length) + return Q.reject('ERROR: Failed to deploy to device, no devices found.'); + + // default device + target = typeof target !== 'undefined' ? target : device_list[0]; + + if (device_list.indexOf(target) < 0) + return Q.reject('ERROR: Unable to find target \'' + target + '\'.'); + + var apk_path = build.get_apk(); + launchName = appinfo.getActivityName(); + console.log('Installing app on device...'); + var cmd = 'adb -s ' + target + ' install -r ' + apk_path; + return exec(cmd); + }).then(function(output) { + if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output); + + //unlock screen + var cmd = 'adb -s ' + target + ' shell input keyevent 82'; + return exec(cmd); + }, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); }) + .then(function() { + // launch the application + console.log('Launching application...'); + var cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName; + return exec(cmd); + }).then(function() { + console.log('LANCH SUCCESS'); + }, function(err) { + return Q.reject('ERROR: Failed to launch application on device: ' + err); + }); +} diff --git a/test/cordova/lib/emulator.js b/test/cordova/lib/emulator.js new file mode 100644 index 00000000..367cd94a --- /dev/null +++ b/test/cordova/lib/emulator.js @@ -0,0 +1,330 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var shell = require('shelljs'), + exec = require('./exec'), + Q = require('q'), + path = require('path'), + appinfo = require('./appinfo'), + build = require('./build'), + ROOT = path.join(__dirname, '..', '..'), + child_process = require('child_process'), + new_emulator = 'cordova_emulator'; + +/** + * Returns a Promise for a list of emulator images in the form of objects + * { + name : , + path : , + target : , + abi : , + skin : + } + */ +module.exports.list_images = function() { + return exec('android list avds') + .then(function(output) { + var response = output.split('\n'); + var emulator_list = []; + for (var i = 1; i < response.length; i++) { + // To return more detailed information use img_obj + var img_obj = {}; + if (response[i].match(/Name:\s/)) { + img_obj['name'] = response[i].split('Name: ')[1].replace('\r', ''); + if (response[i + 1].match(/Path:\s/)) { + i++; + img_obj['path'] = response[i].split('Path: ')[1].replace('\r', ''); + } + if (response[i + 1].match(/\(API\slevel\s/)) { + i++; + img_obj['target'] = response[i].replace('\r', ''); + } + if (response[i + 1].match(/ABI:\s/)) { + i++; + img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', ''); + } + if (response[i + 1].match(/Skin:\s/)) { + i++; + img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', ''); + } + + emulator_list.push(img_obj); + } + /* To just return a list of names use this + if (response[i].match(/Name:\s/)) { + emulator_list.push(response[i].split('Name: ')[1].replace('\r', ''); + }*/ + + } + return emulator_list; + }); +} + +/** + * Will return the closest avd to the projects target + * or undefined if no avds exist. + * Returns a promise. + */ +module.exports.best_image = function() { + var project_target = this.get_target().replace('android-', ''); + return this.list_images() + .then(function(images) { + var closest = 9999; + var best = images[0]; + for (i in images) { + var target = images[i].target; + if(target) { + var num = target.split('(API level ')[1].replace(')', ''); + if (num == project_target) { + return images[i]; + } else if (project_target - num < closest && project_target > num) { + var closest = project_target - num; + best = images[i]; + } + } + } + return best; + }); +} + +// Returns a promise. +module.exports.list_started = function() { + return exec('adb devices') + .then(function(output) { + var response = output.split('\n'); + var started_emulator_list = []; + for (var i = 1; i < response.length; i++) { + if (response[i].match(/device/) && response[i].match(/emulator/)) { + started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); + } + } + return started_emulator_list; + }); +} + +module.exports.get_target = function() { + var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties')); + return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', ''); +} + +// Returns a promise. +module.exports.list_targets = function() { + return exec('android list targets') + .then(function(output) { + var target_out = output.split('\n'); + var targets = []; + for (var i = target_out.length; i >= 0; i--) { + if(target_out[i].match(/id:/)) { + targets.push(targets[i].split(' ')[1]); + } + } + return targets; + }); +} + +/* + * Starts an emulator with the given ID, + * and returns the started ID of that emulator. + * If no ID is given it will used the first image availible, + * if no image is availible it will error out (maybe create one?). + * + * Returns a promise. + */ +module.exports.start = function(emulator_ID) { + var self = this; + var emulator_id, num_started, started_emulators; + + return self.list_started() + .then(function(list) { + started_emulators = list; + num_started = started_emulators.length; + if (typeof emulator_ID === 'undefined') { + return self.list_images() + .then(function(emulator_list) { + if (emulator_list.length > 0) { + return self.best_image() + .then(function(best) { + emulator_ID = best.name; + console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID); + return emulator_ID; + }); + } else { + return Q.reject('ERROR : No emulator images (avds) found, if you would like to create an\n' + + ' avd follow the instructions provided here:\n' + + ' http://developer.android.com/tools/devices/index.html\n' + + ' Or run \'android create avd --name --target \'\n' + + ' in on the command line.'); + } + }); + } else { + return Q(emulator_ID); + } + }).then(function() { + var cmd, args; + if(process.platform == 'win32' || process.platform == 'win64') { + cmd = '%comspec%'; + args = ['/c', 'start', 'cmd', '/c', 'emulator', '-avd', emulator_ID]; + } else { + cmd = 'emulator'; + args = ['-avd', emulator_ID]; + } + var proc = child_process.spawn(cmd, args, { stdio: 'inherit', detached: true }); + proc.unref(); // Don't wait for it to finish, since the emulator will probably keep running for a long time. + }).then(function() { + // wait for emulator to start + console.log('Waiting for emulator...'); + return self.wait_for_emulator(num_started); + }).then(function(new_started) { + if (new_started.length > 1) { + for (i in new_started) { + if (started_emulators.indexOf(new_started[i]) < 0) { + emulator_id = new_started[i]; + } + } + } else { + emulator_id = new_started[0]; + } + if (!emulator_id) return Q.reject('ERROR : Failed to start emulator, could not find new emulator'); + + //wait for emulator to boot up + process.stdout.write('Booting up emulator (this may take a while)...'); + return self.wait_for_boot(emulator_id); + }).then(function() { + console.log('BOOT COMPLETE'); + + //unlock screen + return exec('adb -s ' + emulator_id + ' shell input keyevent 82'); + }).then(function() { + //return the new emulator id for the started emulators + return emulator_id; + }); +} + +/* + * Waits for the new emulator to apear on the started-emulator list. + * Returns a promise with a list of newly started emulators' IDs. + */ +module.exports.wait_for_emulator = function(num_running) { + var self = this; + return self.list_started() + .then(function(new_started) { + if (new_started.length > num_running) { + return new_started; + } else { + return Q.delay(1000).then(function() { + return self.wait_for_emulator(num_running); + }); + } + }); +} + +/* + * Waits for the boot animation property of the emulator to switch to 'stopped' + */ +module.exports.wait_for_boot = function(emulator_id) { + var self = this; + return exec('adb -s ' + emulator_id + ' shell getprop init.svc.bootanim') + .then(function(output) { + if (output.match(/stopped/)) { + return; + } else { + process.stdout.write('.'); + return Q.delay(3000).then(function() { + return self.wait_for_boot(emulator_id); + }); + } + }); +} + +/* + * Create avd + * TODO : Enter the stdin input required to complete the creation of an avd. + * Returns a promise. + */ +module.exports.create_image = function(name, target) { + console.log('Creating avd named ' + name); + if (target) { + return exec('android create avd --name ' + name + ' --target ' + target) + .then(null, function(error) { + console.error('ERROR : Failed to create emulator image : '); + console.error(' Do you have the latest android targets including ' + target + '?'); + console.error(create.output); + }); + } else { + console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.'); + return exec('android create avd --name ' + name + ' --target ' + this.list_targets()[0]) + .then(function() { + // TODO: This seems like another error case, even though it always happens. + console.error('ERROR : Unable to create an avd emulator, no targets found.'); + console.error('Please insure you have targets availible by runing the "android" command'); + return Q.reject(); + }, function(error) { + console.error('ERROR : Failed to create emulator image : '); + console.error(error); + }); + } +} + +/* + * Installs a previously built application on the emulator and launches it. + * If no target is specified, then it picks one. + * If no started emulators are found, error out. + * Returns a promise. + */ +module.exports.install = function(target) { + var self = this; + return this.list_started() + .then(function(emulator_list) { + if (emulator_list.length < 1) { + return Q.reject('No started emulators found, please start an emultor before deploying your project.'); + } + + // default emulator + target = typeof target !== 'undefined' ? target : emulator_list[0]; + if (emulator_list.indexOf(target) < 0) { + return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.'); + } + + console.log('Installing app on emulator...'); + var apk_path = build.get_apk(); + return exec('adb -s ' + target + ' install -r ' + apk_path); + }).then(function(output) { + if (output.match(/Failure/)) { + return Q.reject('Failed to install apk to emulator: ' + output); + } + return Q(); + }, function(err) { + return Q.reject('Failed to install apk to emulator: ' + err); + }).then(function() { + //unlock screen + return exec('adb -s ' + target + ' shell input keyevent 82'); + }).then(function() { + // launch the application + console.log('Launching application...'); + var launchName = appinfo.getActivityName(); + cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName; + return exec(cmd); + }).then(function(output) { + console.log('LAUNCH SUCCESS'); + }, function(err) { + return Q.reject('Failed to launch app on emulator: ' + err); + }); +} diff --git a/test/cordova/lib/exec.js b/test/cordova/lib/exec.js new file mode 100644 index 00000000..6afa9c0d --- /dev/null +++ b/test/cordova/lib/exec.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var child_process = require('child_process'), + Q = require('q'); + +// Takes a command and optional current working directory. +// Returns a promise that either resolves with the stdout, or +// rejects with an error message and the stderr. +module.exports = function(cmd, opt_cwd) { + var d = Q.defer(); + console.log('exec: ' + cmd); + try { + child_process.exec(cmd, {cwd: opt_cwd}, function(err, stdout, stderr) { + console.log([cmd, err, stdout, stderr]); + if (err) d.reject('Error executing "' + cmd + '": ' + stderr); + else d.resolve(stdout); + }); + } catch(e) { + console.error('error caught: ' + e); + d.reject(e); + } + return d.promise; +} + diff --git a/test/cordova/lib/install-device b/test/cordova/lib/install-device new file mode 100755 index 00000000..fc4b7841 --- /dev/null +++ b/test/cordova/lib/install-device @@ -0,0 +1,42 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var device = require('./device'), + args = process.argv; + +if(args.length > 2) { + var install_target; + if (args[2].substring(0, 9) == '--target=') { + install_target = args[2].substring(9, args[2].length); + device.install(install_target).done(null, function(err) { + console.error('ERROR: ' + err); + process.exit(2); + }); + } else { + console.error('ERROR : argument \'' + args[2] + '\' not recognized.'); + process.exit(2); + } +} else { + device.install().done(null, function(err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +} diff --git a/test/cordova/lib/install-device.bat b/test/cordova/lib/install-device.bat new file mode 100644 index 00000000..ac7214ac --- /dev/null +++ b/test/cordova/lib/install-device.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0install-device" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/lib/install-emulator b/test/cordova/lib/install-emulator new file mode 100755 index 00000000..aa2a34f6 --- /dev/null +++ b/test/cordova/lib/install-emulator @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var emulator = require('./emulator'), + args = process.argv; + +var install_target; +if(args.length > 2) { + if (args[2].substring(0, 9) == '--target=') { + install_target = args[2].substring(9, args[2].length); + } else { + console.error('ERROR : argument \'' + args[2] + '\' not recognized.'); + process.exit(2); + } +} + +emulator.install(install_target).done(null, function(err) { + console.error('ERROR: ' + err); + process.exit(2); +}); diff --git a/test/cordova/lib/install-emulator.bat b/test/cordova/lib/install-emulator.bat new file mode 100644 index 00000000..1ec67790 --- /dev/null +++ b/test/cordova/lib/install-emulator.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0install-emulator" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/lib/list-devices b/test/cordova/lib/list-devices new file mode 100755 index 00000000..e390bff6 --- /dev/null +++ b/test/cordova/lib/list-devices @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var devices = require('./device'); + +// Usage support for when args are given +devices.list().done(function(device_list) { + device_list && device_list.forEach(function(dev) { + console.log(dev); + }); +}, function(err) { + console.error('ERROR: ' + err); + process.exit(2); +}); + diff --git a/test/cordova/lib/list-devices.bat b/test/cordova/lib/list-devices.bat new file mode 100644 index 00000000..c0bcdd9a --- /dev/null +++ b/test/cordova/lib/list-devices.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0list-devices" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/lib/list-emulator-images b/test/cordova/lib/list-emulator-images new file mode 100755 index 00000000..996cf555 --- /dev/null +++ b/test/cordova/lib/list-emulator-images @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var emulators = require('./emulator'); + +// Usage support for when args are given +emulators.list_images().done(function(emulator_list) { + emulator_list && emulator_list.forEach(function(emu) { + console.log(emu.name); + }); +}, function(err) { + console.error('ERROR: ' + err); + process.exit(2); +}); diff --git a/test/cordova/lib/list-emulator-images.bat b/test/cordova/lib/list-emulator-images.bat new file mode 100644 index 00000000..661cbf95 --- /dev/null +++ b/test/cordova/lib/list-emulator-images.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0list-emulator-images" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) diff --git a/test/cordova/lib/list-started-emulators b/test/cordova/lib/list-started-emulators new file mode 100755 index 00000000..2ae8c5a8 --- /dev/null +++ b/test/cordova/lib/list-started-emulators @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var emulators = require('./emulator'); + +// Usage support for when args are given +emulators.list_started().done(function(emulator_list) { + emulator_list && emulator_list.forEach(function(emu) { + console.log(emu); + }); +}, function(err) { + console.error('ERROR: ' + err); + process.exit(2); +}); diff --git a/test/cordova/lib/list-started-emulators.bat b/test/cordova/lib/list-started-emulators.bat new file mode 100644 index 00000000..a4e88f7d --- /dev/null +++ b/test/cordova/lib/list-started-emulators.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0list-started-emulators" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/lib/log.js b/test/cordova/lib/log.js new file mode 100644 index 00000000..7339b1c2 --- /dev/null +++ b/test/cordova/lib/log.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var shell = require('shelljs'), + path = require('path'), + Q = require('q'), + child_process = require('child_process'), + ROOT = path.join(__dirname, '..', '..'); + +/* + * Starts running logcat in the shell. + * Returns a promise. + */ +module.exports.run = function() { + var cmd = 'adb logcat | grep -v nativeGetEnabledTags'; + var d = Q.defer(); + var adb = child_process.spawn('adb', ['logcat']); + + adb.stdout.on('data', function(data) { + var lines = data ? data.toString().split('\n') : []; + var out = lines.filter(function(x) { return x.indexOf('nativeGetEnabledTags') < 0; }); + console.log(out.join('\n')); + }); + + adb.stderr.on('data', console.error); + adb.on('close', function(code) { + if (code > 0) { + d.reject('Failed to run logcat command.'); + } else d.resolve(); + }); + + return d.promise; +} + +module.exports.help = function() { + console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'log'))); + console.log('Gives the logcat output on the command line.'); + process.exit(0); +} diff --git a/test/cordova/lib/run.js b/test/cordova/lib/run.js new file mode 100644 index 00000000..68060149 --- /dev/null +++ b/test/cordova/lib/run.js @@ -0,0 +1,139 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var path = require('path'), + build = require('./build'), + emulator = require('./emulator'), + device = require('./device'), + Q = require('q'); + +/* + * Runs the application on a device if availible. + * If not device is found, it will use a started emulator. + * If no started emulators are found it will attempt to start an avd. + * If no avds are found it will error out. + * Returns a promise. + */ + module.exports.run = function(args) { + var build_type; + var install_target; + + for (var i=2; i 0 ? Q() : emulator.start(); + return p.then(function() { emulator.install(); }); + }); + } else if (install_target) { + var devices, started_emulators, avds; + return device.list() + .then(function(res) { + devices = res; + return emulator.list_started(); + }).then(function(res) { + started_emulators = res; + return emulator.list_images(); + }).then(function(res) { + avds = res; + if (devices.indexOf(install_target) > -1) { + return device.install(install_target); + } else if (started_emulators.indexOf(install_target) > -1) { + return emulator.install(install_target); + } else { + // if target emulator isn't started, then start it. + var emulator_ID; + for(avd in avds) { + if(avds[avd].name == install_target) { + return emulator.start(install_target) + .then(function() { emulator.install(emulator_ID); }); + } + } + return Q.reject('Target \'' + install_target + '\' not found, unable to run project'); + } + }); + } else { + // no target given, deploy to device if availible, otherwise use the emulator. + return device.list() + .then(function(device_list) { + if (device_list.length > 0) { + console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.'); + return device.install(device_list[0]); + } else { + return emulator.list_started() + .then(function(emulator_list) { + if (emulator_list.length > 0) { + console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.'); + return emulator.install(emulator_list[0]); + } else { + console.log('WARNING : No started emulators found, starting an emulator.'); + return emulator.best_image() + .then(function(best_avd) { + if(best_avd) { + return emulator.start(best_avd.name) + .then(function(emulator_ID) { + console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.'); + return emulator.install(emulator_ID); + }); + } else { + return emulator.start(); + } + }); + } + }); + } + }); + } + }); +} + +module.exports.help = function() { + console.log('Usage: ' + path.relative(process.cwd(), args[0]) + ' [options]'); + console.log('Build options :'); + console.log(' --debug : Builds project in debug mode'); + console.log(' --release : Builds project in release mode'); + console.log(' --nobuild : Runs the currently built project without recompiling'); + console.log('Deploy options :'); + console.log(' --device : Will deploy the built project to a device'); + console.log(' --emulator : Will deploy the built project to an emulator if one exists'); + console.log(' --target= : Installs to the target with the specified id.'); + process.exit(0); +} diff --git a/test/cordova/lib/start-emulator b/test/cordova/lib/start-emulator new file mode 100755 index 00000000..f96bdc3e --- /dev/null +++ b/test/cordova/lib/start-emulator @@ -0,0 +1,39 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var emulator = require('./emulator'), + args = process.argv; + +var install_target; +if(args.length > 2) { + if (args[2].substring(0, 9) == '--target=') { + install_target = args[2].substring(9, args[2].length); + } else { + console.error('ERROR : argument \'' + args[2] + '\' not recognized.'); + process.exit(2); + } +} + +emulator.start(install_target).done(null, function(err) { + console.error('ERROR: ' + err); + process.exit(2); +}); + diff --git a/test/cordova/lib/start-emulator.bat b/test/cordova/lib/start-emulator.bat new file mode 100644 index 00000000..9329d951 --- /dev/null +++ b/test/cordova/lib/start-emulator.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0start-emulator" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/log b/test/cordova/log new file mode 100755 index 00000000..47f06050 --- /dev/null +++ b/test/cordova/log @@ -0,0 +1,36 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var log = require('./lib/log'), + reqs = require('./lib/check_reqs'), + args = process.argv; + +// Usage support for when args are given +if(args.length > 2) { + log.help(); +} else { + reqs.run().done(function() { + return log.run(); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +} diff --git a/test/cordova/log.bat b/test/cordova/log.bat new file mode 100644 index 00000000..875982f2 --- /dev/null +++ b/test/cordova/log.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0log" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'log' script in 'cordova' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/node_modules/.bin/shjs b/test/cordova/node_modules/.bin/shjs new file mode 120000 index 00000000..a0449975 --- /dev/null +++ b/test/cordova/node_modules/.bin/shjs @@ -0,0 +1 @@ +../shelljs/bin/shjs \ No newline at end of file diff --git a/test/cordova/node_modules/q/CONTRIBUTING.md b/test/cordova/node_modules/q/CONTRIBUTING.md new file mode 100644 index 00000000..500ab17b --- /dev/null +++ b/test/cordova/node_modules/q/CONTRIBUTING.md @@ -0,0 +1,40 @@ + +For pull requests: + +- Be consistent with prevalent style and design decisions. +- Add a Jasmine spec to `specs/q-spec.js`. +- Use `npm test` to avoid regressions. +- Run tests in `q-spec/run.html` in as many supported browsers as you + can find the will to deal with. +- Do not build minified versions; we do this each release. +- If you would be so kind, add a note to `CHANGES.md` in an + appropriate section: + + - `Next Major Version` if it introduces backward incompatibilities + to code in the wild using documented features. + - `Next Minor Version` if it adds a new feature. + - `Next Patch Version` if it fixes a bug. + +For releases: + +- Run `npm test`. +- Run tests in `q-spec/run.html` in a representative sample of every + browser under the sun. +- Run `npm run cover` and make sure you're happy with the results. +- Run `npm run minify` and be sure to commit the resulting `q.min.js`. +- Note the Gzipped size output by the previous command, and update + `README.md` if it has changed to 1 significant digit. +- Stash any local changes. +- Update `CHANGES.md` to reflect all changes in the differences + between `HEAD` and the previous tagged version. Give credit where + credit is due. +- Update `README.md` to address all new, non-experimental features. +- Update the API reference on the Wiki to reflect all non-experimental + features. +- Use `npm version major|minor|patch` to update `package.json`, + commit, and tag the new version. +- Use `npm publish` to send up a new release. +- Send an email to the q-continuum mailing list announcing the new + release and the notes from the change log. This helps folks + maintaining other package ecosystems. + diff --git a/test/cordova/node_modules/q/LICENSE b/test/cordova/node_modules/q/LICENSE new file mode 100644 index 00000000..76c5fe4c --- /dev/null +++ b/test/cordova/node_modules/q/LICENSE @@ -0,0 +1,19 @@ + +Copyright 2009–2012 Kristopher Michael Kowal. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/test/cordova/node_modules/q/README.md b/test/cordova/node_modules/q/README.md new file mode 100644 index 00000000..c0f513ce --- /dev/null +++ b/test/cordova/node_modules/q/README.md @@ -0,0 +1,813 @@ +[![Build Status](https://secure.travis-ci.org/kriskowal/q.png?branch=master)](http://travis-ci.org/kriskowal/q) + + + Promises/A+ logo + + +If a function cannot return a value or throw an exception without +blocking, it can return a promise instead. A promise is an object +that represents the return value or the thrown exception that the +function may eventually provide. A promise can also be used as a +proxy for a [remote object][Q-Connection] to overcome latency. + +[Q-Connection]: https://github.com/kriskowal/q-connection + +On the first pass, promises can mitigate the “[Pyramid of +Doom][POD]”: the situation where code marches to the right faster +than it marches forward. + +[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/ + +```javascript +step1(function (value1) { + step2(value1, function(value2) { + step3(value2, function(value3) { + step4(value3, function(value4) { + // Do something with value4 + }); + }); + }); +}); +``` + +With a promise library, you can flatten the pyramid. + +```javascript +Q.fcall(promisedStep1) +.then(promisedStep2) +.then(promisedStep3) +.then(promisedStep4) +.then(function (value4) { + // Do something with value4 +}) +.catch(function (error) { + // Handle any error from all above steps +}) +.done(); +``` + +With this approach, you also get implicit error propagation, just like `try`, +`catch`, and `finally`. An error in `promisedStep1` will flow all the way to +the `catch` function, where it’s caught and handled. (Here `promisedStepN` is +a version of `stepN` that returns a promise.) + +The callback approach is called an “inversion of control”. +A function that accepts a callback instead of a return value +is saying, “Don’t call me, I’ll call you.”. Promises +[un-invert][IOC] the inversion, cleanly separating the input +arguments from control flow arguments. This simplifies the +use and creation of API’s, particularly variadic, +rest and spread arguments. + +[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript + + +## Getting Started + +The Q module can be loaded as: + +- A `` + + + +

Loading device properties...

+ + + diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.md new file mode 100644 index 00000000..3748d36a --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.md @@ -0,0 +1,104 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +Device +====== + +> The `device` object describes the device's hardware and software. + +Properties +---------- + +- device.name +- device.cordova +- device.platform +- device.uuid +- device.version +- device.model + +Variable Scope +-------------- + +Since `device` is assigned to the `window` object, it is implicitly in the global scope. + + // These reference the same `device` + var phoneName = window.device.name; + var phoneName = device.name; + +Permissions +----------- + +### Android + +#### app/res/xml/config.xml + + + +#### app/AndroidManifest.xml + + + +### Bada + +#### manifest.xml + + + SYSTEM_SERVICE + + +### BlackBerry WebWorks + +#### www/plugins.xml + + + +#### www/config.xml + + + + read_device_identifying_information + + +### iOS + + No permissions are required. + +### webOS + + No permissions are required. + +### Windows Phone + +#### Properties/WPAppManifest.xml + + + + + + + +Reference: [Application Manifest for Windows Phone](http://msdn.microsoft.com/en-us/library/ff769509%28v=vs.92%29.aspx) + +### Tizen + +#### config.xml + + + +Reference: [Application Manifest for Tizen Web Application](https://developer.tizen.org/help/topic/org.tizen.help.gs/Creating%20a%20Project.html?path=0_1_1_3#8814682_CreatingaProject-EditingconfigxmlFeatures) diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.model.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.model.md new file mode 100644 index 00000000..e5238e48 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.model.md @@ -0,0 +1,106 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +device.model +=========== + +Get the device's model name. + + var string = device.model; + +Description +----------- + +The `device.model` returns the name of the device's model or +product. The value is set by the device manufacturer and may be +different across versions of the same product. + +Supported Platforms +------------------- + +- Android +- BlackBerry WebWorks (OS 5.0 and higher) +- iOS +- Windows Phone 7 and 8 +- Bada 1.2 & 2.x +- webOS +- Tizen +- Windows 8 + +Quick Example +------------- + + // Android: Nexus One returns "Passion" (Nexus One code name) + // Motorola Droid returns "voles" + // BlackBerry: Torch 9800 returns "9800" + // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models + // + var model = device.model; + +Full Example +------------ + + + + + Device Properties Example + + + + + +

Loading device properties...

+ + + +Android Quirks +-------------- + +- Gets the [product name](http://developer.android.com/reference/android/os/Build.html#PRODUCT) instead of the [model name](http://developer.android.com/reference/android/os/Build.html#MODEL), which is often the production code name. For example, the Nexus One returns `Passion`, and Motorola Droid returns `voles`. + +Windows Phone 7 and 8 Quirks +------------- + +- Returns the device model specified by the manufacturer. For example, the Samsung Focus returns `SGH-i917`. + +Bada Quirks +----------- +- Returns the manufacturer model name, for example, `Samsung Wave S8500` + +Tizen Quirks +----------- +- Returns the device model assigned by the vendor, for example, `TIZEN` diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.name.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.name.md new file mode 100644 index 00000000..a70648f3 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.name.md @@ -0,0 +1,108 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +device.name +=========== + +__WARNING:__ `device.name` is deprecated as of version 2.3.0. Use `device.model` instead. + +Get the device's model name. + + var string = device.name; + +Description +----------- + +`device.name` returns the name of the device's model or product. This +value is set by the device manufacturer and may be different across +versions of the same product. + +Supported Platforms +------------------- + +- Android +- BlackBerry WebWorks (OS 5.0 and higher) +- iOS +- Windows Phone 7 and 8 +- Bada 1.2 & 2.x +- webOS +- Tizen +- Windows 8 + +Quick Example +------------- + + // Android: Nexus One returns "Passion" (Nexus One code name) + // Motorola Droid returns "voles" + // BlackBerry: Torch 9800 returns "9800" + // iOS: All devices returns either "iPhone", "iPod Touch", "iPhone Simulator", "iPad", "iPad Simulator" + // + var name = device.name; + +Full Example +------------ + + + + + Device Properties Example + + + + + +

Loading device properties...

+ + + +Android Quirks +-------------- + +- Gets the [product name](http://developer.android.com/reference/android/os/Build.html#PRODUCT) instead of the [model name](http://developer.android.com/reference/android/os/Build.html#MODEL), which is often the production code name. For example, the Nexus One returns `Passion`, and Motorola Droid returns `voles`. + +Windows Phone 7 and 8 Quirks +------------- + +- Returns the device model specified by the manufacturer. For example, the Samsung Focus returns `SGH-i917`. + +Bada Quirks +----------- +- Returns the manufacturer model name, for example, `Samsung Wave S8500` + +Tizen Quirks +----------- +- Returns the device model assigned by the vendor, for example, `TIZEN` diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.platform.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.platform.md new file mode 100644 index 00000000..0d2cacb4 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.platform.md @@ -0,0 +1,99 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +device.platform +=============== + +Get the device's operating system name. + + var string = device.platform; + +Supported Platforms +------------------- + +- Android +- BlackBerry WebWorks (OS 5.0 and higher) +- iOS +- Windows Phone 7 and 8 +- Bada 1.2 & 2.x +- webOS +- Tizen +- Windows 8 + +Quick Example +------------- + + // Depending on the device, a few examples are: + // - "Android" + // - "BlackBerry" + // - "iOS" + // - "webOS" + // - "WinCE" + // - "Tizen" + var devicePlatform = device.platform; + +Full Example +------------ + + + + + Device Properties Example + + + + + +

Loading device properties...

+ + + +BlackBerry Quirks +----------------- + +Devices may return the device platform version number instead of the +platform name. For example, the Storm2 9550 returns a value such as +`2.13.0.95`. + +Windows Phone 7 Quirks +----------------- + +Windows Phone 7 devices report the platform as `WinCE`. + +Windows Phone 8 Quirks +----------------- + +Windows Phone 8 devices report the platform as `Win32NT`. diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.uuid.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.uuid.md new file mode 100644 index 00000000..76abf739 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.uuid.md @@ -0,0 +1,115 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +device.uuid +=========== + +Get the device's Universally Unique Identifier ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)). + + var string = device.uuid; + +Description +----------- + +The details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model. + +Supported Platforms +------------------- + +- Android +- BlackBerry WebWorks (OS 5.0 and higher) +- iOS +- Windows Phone 7 and 8 +- Bada 1.2 & 2.x +- webOS +- Tizen +- Windows 8 + +Quick Example +------------- + + // Android: Returns a random 64-bit integer (as a string, again!) + // The integer is generated on the device's first boot + // + // BlackBerry: Returns the PIN number of the device + // This is a nine-digit unique integer (as a string, though!) + // + // iPhone: (Paraphrased from the UIDevice Class documentation) + // Returns a string of hash values created from multiple hardware identifies. + // It is guaranteed to be unique for every device and cannot be tied + // to the user account. + // Windows Phone 7 : Returns a hash of device+current user, + // if the user is not defined, a guid is generated and will persist until the app is uninstalled + // + // webOS: returns the device NDUID + // + // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number + // unique to every GSM and UMTS mobile phone. + var deviceID = device.uuid; + +Full Example +------------ + + + + + Device Properties Example + + + + + +

Loading device properties...

+ + + +iOS Quirk +------------- + +The `uuid` on iOS is not unique to a device, but varies for each +application, for each installation. It changes if you delete and +re-install the app, and possibly also when you upgrade iOS, or even +upgrade your app per version (apparent in iOS 5.1). The `uuid` is not +a reliable value. + +Windows Phone 7 and 8 Quirks +------------- + +The `uuid` for Windows Phone 7 requires the permission +`ID_CAP_IDENTITY_DEVICE`. Microsoft will likely deprecate this +property soon. If the capability is not available, the application +generates a persistent guid that is maintained for the duration of the +application's installation on the device. diff --git a/test/cordova/plugins/org.apache.cordova.device/docs/device.version.md b/test/cordova/plugins/org.apache.cordova.device/docs/device.version.md new file mode 100644 index 00000000..ecd4733b --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/docs/device.version.md @@ -0,0 +1,86 @@ +--- + license: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--- + +device.version +============== + +Get the operating system version. + + var string = device.version; + +Supported Platforms +------------------- + +- Android 2.1+ +- BlackBerry WebWorks (OS 5.0 and higher) +- iOS +- Windows Phone 7 and 8 +- Bada 1.2 & 2.x +- webOS +- Tizen +- Windows 8 + +Quick Example +------------- + + // Android: Froyo OS would return "2.2" + // Eclair OS would return "2.1", "2.0.1", or "2.0" + // Version can also return update level "2.1-update1" + // + // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" + // + // iPhone: iOS 3.2 returns "3.2" + // + // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 + // webOS: webOS 2.2.4 return 2.2.4 + // Tizen: returns "TIZEN_20120425_2" + var deviceVersion = device.version; + +Full Example +------------ + + + + + Device Properties Example + + + + + +

Loading device properties...

+ + diff --git a/test/cordova/plugins/org.apache.cordova.device/plugin.xml b/test/cordova/plugins/org.apache.cordova.device/plugin.xml new file mode 100644 index 00000000..7eb03c44 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/plugin.xml @@ -0,0 +1,103 @@ + + + + Device + Cordova Device Plugin + Apache 2.0 + cordova,device + https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git + https://issues.apache.org/jira/browse/CB/component/12320648 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + read_device_identifying_information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/cordova/plugins/org.apache.cordova.device/src/android/Device.java b/test/cordova/plugins/org.apache.cordova.device/src/android/Device.java new file mode 100644 index 00000000..2ce3cc73 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/android/Device.java @@ -0,0 +1,200 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ +package org.apache.cordova.device; + +import java.util.TimeZone; + +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.LOG; +import org.apache.cordova.CordovaInterface; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.provider.Settings; +import android.telephony.TelephonyManager; + +public class Device extends CordovaPlugin { + public static final String TAG = "Device"; + + public static String cordovaVersion = "dev"; // Cordova version + public static String platform = "Android"; // Device OS + public static String uuid; // Device UUID + + BroadcastReceiver telephonyReceiver = null; + + /** + * Constructor. + */ + public Device() { + } + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param cordova The context of the main Activity. + * @param webView The CordovaWebView Cordova is running in. + */ + public void initialize(CordovaInterface cordova, CordovaWebView webView) { + super.initialize(cordova, webView); + Device.uuid = getUuid(); + this.initTelephonyReceiver(); + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackContext The callback id used when calling back into JavaScript. + * @return True if the action was valid, false if not. + */ + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + if (action.equals("getDeviceInfo")) { + JSONObject r = new JSONObject(); + r.put("uuid", Device.uuid); + r.put("version", this.getOSVersion()); + r.put("platform", Device.platform); + r.put("cordova", Device.cordovaVersion); + r.put("model", this.getModel()); + callbackContext.success(r); + } + else { + return false; + } + return true; + } + + /** + * Unregister receiver. + */ + public void onDestroy() { + this.cordova.getActivity().unregisterReceiver(this.telephonyReceiver); + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + + /** + * Listen for telephony events: RINGING, OFFHOOK and IDLE + * Send these events to all plugins using + * CordovaActivity.onMessage("telephone", "ringing" | "offhook" | "idle") + */ + private void initTelephonyReceiver() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + //final CordovaInterface mycordova = this.cordova; + this.telephonyReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + + // If state has changed + if ((intent != null) && intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { + if (intent.hasExtra(TelephonyManager.EXTRA_STATE)) { + String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE); + if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) { + LOG.i(TAG, "Telephone RINGING"); + webView.postMessage("telephone", "ringing"); + } + else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { + LOG.i(TAG, "Telephone OFFHOOK"); + webView.postMessage("telephone", "offhook"); + } + else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) { + LOG.i(TAG, "Telephone IDLE"); + webView.postMessage("telephone", "idle"); + } + } + } + } + }; + + // Register the receiver + this.cordova.getActivity().registerReceiver(this.telephonyReceiver, intentFilter); + } + + /** + * Get the OS name. + * + * @return + */ + public String getPlatform() { + return Device.platform; + } + + /** + * Get the device's Universally Unique Identifier (UUID). + * + * @return + */ + public String getUuid() { + String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); + return uuid; + } + + /** + * Get the Cordova version. + * + * @return + */ + public String getCordovaVersion() { + return Device.cordovaVersion; + } + + public String getModel() { + String model = android.os.Build.MODEL; + return model; + } + + public String getProductName() { + String productname = android.os.Build.PRODUCT; + return productname; + } + + /** + * Get the OS version. + * + * @return + */ + public String getOSVersion() { + String osversion = android.os.Build.VERSION.RELEASE; + return osversion; + } + + public String getSDKVersion() { + @SuppressWarnings("deprecation") + String sdkversion = android.os.Build.VERSION.SDK; + return sdkversion; + } + + public String getTimeZoneID() { + TimeZone tz = TimeZone.getDefault(); + return (tz.getID()); + } + +} diff --git a/test/cordova/plugins/org.apache.cordova.device/src/blackberry10/index.js b/test/cordova/plugins/org.apache.cordova.device/src/blackberry10/index.js new file mode 100644 index 00000000..639ac64b --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/blackberry10/index.js @@ -0,0 +1,69 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +function getModelName () { + var modelName = window.qnx.webplatform.device.modelName; + //Pre 10.2 (meaning Z10 or Q10) + if (typeof modelName === "undefined") { + if (window.screen.height === 720 && window.screen.width === 720) { + if ( window.matchMedia("(-blackberry-display-technology: -blackberry-display-oled)").matches) { + modelName = "Q10"; + } else { + modelName = "Q5"; + } + } else if ((window.screen.height === 1280 && window.screen.width === 768) || + (window.screen.height === 768 && window.screen.width === 1280)) { + modelName = "Z10"; + } else { + modelName = window.qnx.webplatform.deviceName; + } + } + + return modelName; +} + +function getUUID () { + var uuid = ""; + try { + //Must surround by try catch because this will throw if the app is missing permissions + uuid = window.qnx.webplatform.device.devicePin; + } catch (e) { + //DO Nothing + } + return uuid; +} + +module.exports = { + getDeviceInfo: function (success, fail, args, env) { + var result = new PluginResult(args, env), + modelName = getModelName(), + uuid = getUUID(), + info = { + platform: "blackberry10", + version: window.qnx.webplatform.device.scmBundle, + model: modelName, + uuid: uuid, + cordova: "dev" + }; + + result.ok(info); + } +}; diff --git a/test/cordova/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js b/test/cordova/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js new file mode 100644 index 00000000..f37e7617 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js @@ -0,0 +1,39 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +var firefoxos = require('cordova/platform'); +var cordova = require('cordova'); + +module.exports = { + getDeviceInfo: function(success, error) { + setTimeout(function () { + success({ + cordova: firefoxos.cordovaVersion, + platform: 'firefoxos', + model: null, + version: null, + uuid: null + }); + }, 0); + } +}; + +require("cordova/firefoxos/commandProxy").add("Device", module.exports); diff --git a/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.h b/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.h new file mode 100644 index 00000000..a146d882 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.h @@ -0,0 +1,30 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. + */ + +#import +#import + +@interface CDVDevice : CDVPlugin +{} + ++ (NSString*)cordovaVersion; + +- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command; + +@end diff --git a/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.m b/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.m new file mode 100644 index 00000000..7e18d92a --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/ios/CDVDevice.m @@ -0,0 +1,90 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. + */ + +#include +#include + +#import +#import "CDVDevice.h" + +@implementation UIDevice (ModelVersion) + +- (NSString*)modelVersion +{ + size_t size; + + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char* machine = malloc(size); + sysctlbyname("hw.machine", machine, &size, NULL, 0); + NSString* platform = [NSString stringWithUTF8String:machine]; + free(machine); + + return platform; +} + +@end + +@interface CDVDevice () {} +@end + +@implementation CDVDevice + +- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command +{ + NSDictionary* deviceProperties = [self deviceProperties]; + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:deviceProperties]; + + /* Settings.plist + * Read the optional Settings.plist file and push these user-defined settings down into the web application. + * This can be useful for supplying build-time configuration variables down to the app to change its behavior, + * such as specifying Full / Lite version, or localization (English vs German, for instance). + */ + // TODO: turn this into an iOS only plugin + NSDictionary* temp = [CDVViewController getBundlePlist:@"Settings"]; + + if ([temp respondsToSelector:@selector(JSONString)]) { + NSLog(@"Deprecation warning: window.Setting will be removed Aug 2013. Refer to https://issues.apache.org/jira/browse/CB-2433"); + NSString* js = [NSString stringWithFormat:@"window.Settings = %@;", [temp JSONString]]; + [self.commandDelegate evalJs:js]; + } + + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +} + +- (NSDictionary*)deviceProperties +{ + UIDevice* device = [UIDevice currentDevice]; + NSMutableDictionary* devProps = [NSMutableDictionary dictionaryWithCapacity:4]; + + [devProps setObject:[device modelVersion] forKey:@"model"]; + [devProps setObject:@"iOS" forKey:@"platform"]; + [devProps setObject:[device systemVersion] forKey:@"version"]; + [devProps setObject:[device uniqueAppInstanceIdentifier] forKey:@"uuid"]; + [devProps setObject:[[self class] cordovaVersion] forKey:@"cordova"]; + + NSDictionary* devReturn = [NSDictionary dictionaryWithDictionary:devProps]; + return devReturn; +} + ++ (NSString*)cordovaVersion +{ + return CDV_VERSION; +} + +@end diff --git a/test/cordova/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js b/test/cordova/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js new file mode 100644 index 00000000..16145c0b --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js @@ -0,0 +1,50 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + + +var cordova = require('cordova'); +var utils = require('cordova/utils'); + +module.exports = { + + getDeviceInfo:function(win,fail,args) { + + // deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId + var deviceId; + + var localSettings = Windows.Storage.ApplicationData.current.localSettings; + + if (localSettings.values.deviceId) { + deviceId = localSettings.values.deviceId; + } + else { + deviceId = localSettings.values.deviceId = utils.createUUID(); + } + + setTimeout(function () { + win({ platform: "windows8", version: "8", uuid: deviceId, cordova: '0.0.0', model: window.clientInformation.platform }); + }, 0); + } + +}; + +require("cordova/windows8/commandProxy").add("Device", module.exports); + diff --git a/test/cordova/plugins/org.apache.cordova.device/src/wp/Device.cs b/test/cordova/plugins/org.apache.cordova.device/src/wp/Device.cs new file mode 100644 index 00000000..0d2576d7 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/src/wp/Device.cs @@ -0,0 +1,135 @@ +/* + 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. +*/ + +using System; +using System.Net; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Ink; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Shapes; +using Microsoft.Phone.Info; +using System.IO.IsolatedStorage; +using System.Windows.Resources; +using System.IO; +using System.Diagnostics; + +namespace WPCordovaClassLib.Cordova.Commands +{ + public class Device : BaseCommand + { + public void getDeviceInfo(string notused) + { + + string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"", + this.name, + this.cordova, + this.platform, + this.uuid, + this.version, + this.model); + + + + res = "{" + res + "}"; + //Debug.WriteLine("Result::" + res); + DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res)); + } + + public string model + { + get + { + return DeviceStatus.DeviceName; + //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion); + } + } + + public string name + { + get + { + return DeviceStatus.DeviceName; + + } + } + + public string cordova + { + get + { + // TODO: should be able to dynamically read the Cordova version from somewhere... + return "3.0.0"; + } + } + + public string platform + { + get + { + return Environment.OSVersion.Platform.ToString(); + } + } + + public string uuid + { + get + { + string returnVal = ""; + object id; + UserExtendedProperties.TryGetValue("ANID", out id); + + if (id != null) + { + returnVal = id.ToString().Substring(2, 32); + } + else + { + returnVal = "???unknown???"; + + using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication()) + { + try + { + IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage); + + using (StreamReader reader = new StreamReader(fileStream)) + { + returnVal = reader.ReadLine(); + } + } + catch (Exception /*ex*/) + { + + } + } + } + + return returnVal; + } + } + + public string version + { + get + { + return Environment.OSVersion.Version.ToString(); + } + } + + } +} diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporter.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporter.js new file mode 100644 index 00000000..7d9d9240 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporter.js @@ -0,0 +1,101 @@ +jasmine.HtmlReporter = function(_doc) { + var self = this; + var doc = _doc || window.document; + + var reporterView; + + var dom = {}; + + // Jasmine Reporter Public Interface + self.logRunningSpecs = false; + + self.reportRunnerStarting = function(runner) { + var specs = runner.specs() || []; + + if (specs.length == 0) { + return; + } + + createReporterDom(runner.env.versionString()); + doc.body.appendChild(dom.reporter); + + reporterView = new jasmine.HtmlReporter.ReporterView(dom); + reporterView.addSpecs(specs, self.specFilter); + }; + + self.reportRunnerResults = function(runner) { + reporterView && reporterView.complete(); + }; + + self.reportSuiteResults = function(suite) { + reporterView.suiteComplete(suite); + }; + + self.reportSpecStarting = function(spec) { + if (self.logRunningSpecs) { + self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); + } + }; + + self.reportSpecResults = function(spec) { + reporterView.specComplete(spec); + }; + + self.log = function() { + var console = jasmine.getGlobal().console; + if (console && console.log) { + if (console.log.apply) { + console.log.apply(console, arguments); + } else { + console.log(arguments); // ie fix: console.log.apply doesn't exist on ie + } + } + }; + + self.specFilter = function(spec) { + if (!focusedSpecName()) { + return true; + } + + return spec.getFullName().indexOf(focusedSpecName()) === 0; + }; + + return self; + + function focusedSpecName() { + var specName; + + (function memoizeFocusedSpec() { + if (specName) { + return; + } + + var paramMap = []; + var params = doc.location.search.substring(1).split('&'); + + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + } + + specName = paramMap.spec; + })(); + + return specName; + } + + function createReporterDom(version) { + dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' }, + dom.banner = self.createDom('div', { className: 'banner' }, + self.createDom('span', { className: 'title' }, "Jasmine "), + self.createDom('span', { className: 'version' }, version)), + + dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), + dom.alert = self.createDom('div', {className: 'alert'}), + dom.results = self.createDom('div', {className: 'results'}, + dom.summary = self.createDom('div', { className: 'summary' }), + dom.details = self.createDom('div', { id: 'details' })) + ); + } +}; +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter); diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporterHelpers.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporterHelpers.js new file mode 100644 index 00000000..745e1e09 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/HtmlReporterHelpers.js @@ -0,0 +1,60 @@ +jasmine.HtmlReporterHelpers = {}; + +jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { + var el = document.createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(document.createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == "className") { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; +}; + +jasmine.HtmlReporterHelpers.getSpecStatus = function(child) { + var results = child.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.skipped) { + status = 'skipped'; + } + + return status; +}; + +jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) { + var parentDiv = this.dom.summary; + var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite'; + var parent = child[parentSuite]; + + if (parent) { + if (typeof this.views.suites[parent.id] == 'undefined') { + this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views); + } + parentDiv = this.views.suites[parent.id].element; + } + + parentDiv.appendChild(childElement); +}; + + +jasmine.HtmlReporterHelpers.addHelpers = function(ctor) { + for(var fn in jasmine.HtmlReporterHelpers) { + ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn]; + } +}; + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/ReporterView.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/ReporterView.js new file mode 100644 index 00000000..6a6d0056 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/ReporterView.js @@ -0,0 +1,164 @@ +jasmine.HtmlReporter.ReporterView = function(dom) { + this.startedAt = new Date(); + this.runningSpecCount = 0; + this.completeSpecCount = 0; + this.passedCount = 0; + this.failedCount = 0; + this.skippedCount = 0; + + this.createResultsMenu = function() { + this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'}, + this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'), + ' | ', + this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing')); + + this.summaryMenuItem.onclick = function() { + dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, ''); + }; + + this.detailsMenuItem.onclick = function() { + showDetails(); + }; + }; + + this.addSpecs = function(specs, specFilter) { + this.totalSpecCount = specs.length; + + this.views = { + specs: {}, + suites: {} + }; + + for (var i = 0; i < specs.length; i++) { + var spec = specs[i]; + this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); + if (specFilter(spec)) { + this.runningSpecCount++; + } + } + }; + + this.specComplete = function(spec) { + this.completeSpecCount++; + + if (isUndefined(this.views.specs[spec.id])) { + this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom); + } + + var specView = this.views.specs[spec.id]; + + switch (specView.status()) { + case 'passed': + this.passedCount++; + break; + + case 'failed': + this.failedCount++; + break; + + case 'skipped': + this.skippedCount++; + break; + } + + specView.refresh(); + this.refresh(); + }; + + this.suiteComplete = function(suite) { + var suiteView = this.views.suites[suite.id]; + if (isUndefined(suiteView)) { + return; + } + suiteView.refresh(); + }; + + this.refresh = function() { + + if (isUndefined(this.resultsMenu)) { + this.createResultsMenu(); + } + + // currently running UI + if (isUndefined(this.runningAlert)) { + this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"}); + dom.alert.appendChild(this.runningAlert); + } + this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); + + // skipped specs UI + if (isUndefined(this.skippedAlert)) { + this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"}); + } + + this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; + + if (this.skippedCount === 1 && isDefined(dom.alert)) { + dom.alert.appendChild(this.skippedAlert); + } + + // passing specs UI + if (isUndefined(this.passedAlert)) { + this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"}); + } + this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); + + // failing specs UI + if (isUndefined(this.failedAlert)) { + this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"}); + } + this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount); + + if (this.failedCount === 1 && isDefined(dom.alert)) { + dom.alert.appendChild(this.failedAlert); + dom.alert.appendChild(this.resultsMenu); + } + + // summary info + this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount); + this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing"; + }; + + this.complete = function() { + dom.alert.removeChild(this.runningAlert); + + this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; + + if (this.failedCount === 0) { + dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount))); + } else { + showDetails(); + } + + dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s")); + }; + + return this; + + function showDetails() { + if (dom.reporter.className.search(/showDetails/) === -1) { + dom.reporter.className += " showDetails"; + } + } + + function isUndefined(obj) { + return typeof obj === 'undefined'; + } + + function isDefined(obj) { + return !isUndefined(obj); + } + + function specPluralizedFor(count) { + var str = count + " spec"; + if (count > 1) { + str += "s" + } + return str; + } + +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView); + + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SpecView.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SpecView.js new file mode 100644 index 00000000..e8a3c23d --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SpecView.js @@ -0,0 +1,79 @@ +jasmine.HtmlReporter.SpecView = function(spec, dom, views) { + this.spec = spec; + this.dom = dom; + this.views = views; + + this.symbol = this.createDom('li', { className: 'pending' }); + this.dom.symbolSummary.appendChild(this.symbol); + + this.summary = this.createDom('div', { className: 'specSummary' }, + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.description) + ); + + this.detail = this.createDom('div', { className: 'specDetail' }, + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(this.spec.getFullName()), + title: this.spec.getFullName() + }, this.spec.getFullName()) + ); +}; + +jasmine.HtmlReporter.SpecView.prototype.status = function() { + return this.getSpecStatus(this.spec); +}; + +jasmine.HtmlReporter.SpecView.prototype.refresh = function() { + this.symbol.className = this.status(); + + switch (this.status()) { + case 'skipped': + break; + + case 'passed': + this.appendSummaryToSuiteDiv(); + break; + + case 'failed': + this.appendSummaryToSuiteDiv(); + this.appendFailureDetail(); + break; + } +}; + +jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() { + this.summary.className += ' ' + this.status(); + this.appendToSummary(this.spec, this.summary); +}; + +jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() { + this.detail.className += ' ' + this.status(); + + var resultItems = this.spec.results().getItems(); + var messagesDiv = this.createDom('div', { className: 'messages' }); + + for (var i = 0; i < resultItems.length; i++) { + var result = resultItems[i]; + + if (result.type == 'log') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'expect' && result.passed && !result.passed()) { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); + + if (result.trace.stack) { + messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); + } + } + } + + if (messagesDiv.childNodes.length > 0) { + this.detail.appendChild(messagesDiv); + this.dom.details.appendChild(this.detail); + } +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView); diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SuiteView.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SuiteView.js new file mode 100644 index 00000000..19a1efaf --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/SuiteView.js @@ -0,0 +1,22 @@ +jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { + this.suite = suite; + this.dom = dom; + this.views = views; + + this.element = this.createDom('div', { className: 'suite' }, + this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description) + ); + + this.appendToSummary(this.suite, this.element); +}; + +jasmine.HtmlReporter.SuiteView.prototype.status = function() { + return this.getSpecStatus(this.suite); +}; + +jasmine.HtmlReporter.SuiteView.prototype.refresh = function() { + this.element.className += " " + this.status(); +}; + +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView); + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/TrivialReporter.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/TrivialReporter.js new file mode 100644 index 00000000..167ac506 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/html/TrivialReporter.js @@ -0,0 +1,192 @@ +/* @deprecated Use jasmine.HtmlReporter instead + */ +jasmine.TrivialReporter = function(doc) { + this.document = doc || document; + this.suiteDivs = {}; + this.logRunningSpecs = false; +}; + +jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { + var el = document.createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(document.createTextNode(child)); + } else { + if (child) { el.appendChild(child); } + } + } + + for (var attr in attrs) { + if (attr == "className") { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; +}; + +jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { + var showPassed, showSkipped; + + this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' }, + this.createDom('div', { className: 'banner' }, + this.createDom('div', { className: 'logo' }, + this.createDom('span', { className: 'title' }, "Jasmine"), + this.createDom('span', { className: 'version' }, runner.env.versionString())), + this.createDom('div', { className: 'options' }, + "Show ", + showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), + showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") + ) + ), + + this.runnerDiv = this.createDom('div', { className: 'runner running' }, + this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), + this.runnerMessageSpan = this.createDom('span', {}, "Running..."), + this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) + ); + + this.document.body.appendChild(this.outerDiv); + + var suites = runner.suites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + var suiteDiv = this.createDom('div', { className: 'suite' }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), + this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); + this.suiteDivs[suite.id] = suiteDiv; + var parentDiv = this.outerDiv; + if (suite.parentSuite) { + parentDiv = this.suiteDivs[suite.parentSuite.id]; + } + parentDiv.appendChild(suiteDiv); + } + + this.startedAt = new Date(); + + var self = this; + showPassed.onclick = function(evt) { + if (showPassed.checked) { + self.outerDiv.className += ' show-passed'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); + } + }; + + showSkipped.onclick = function(evt) { + if (showSkipped.checked) { + self.outerDiv.className += ' show-skipped'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); + } + }; +}; + +jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { + var results = runner.results(); + var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; + this.runnerDiv.setAttribute("class", className); + //do it twice for IE + this.runnerDiv.setAttribute("className", className); + var specs = runner.specs(); + var specCount = 0; + for (var i = 0; i < specs.length; i++) { + if (this.specFilter(specs[i])) { + specCount++; + } + } + var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); + message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; + this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); + + this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); +}; + +jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { + var results = suite.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.totalCount === 0) { // todo: change this to check results.skipped + status = 'skipped'; + } + this.suiteDivs[suite.id].className += " " + status; +}; + +jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { + if (this.logRunningSpecs) { + this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); + } +}; + +jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { + var results = spec.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.skipped) { + status = 'skipped'; + } + var specDiv = this.createDom('div', { className: 'spec ' + status }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(spec.getFullName()), + title: spec.getFullName() + }, spec.description)); + + + var resultItems = results.getItems(); + var messagesDiv = this.createDom('div', { className: 'messages' }); + for (var i = 0; i < resultItems.length; i++) { + var result = resultItems[i]; + + if (result.type == 'log') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'expect' && result.passed && !result.passed()) { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); + + if (result.trace.stack) { + messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); + } + } + } + + if (messagesDiv.childNodes.length > 0) { + specDiv.appendChild(messagesDiv); + } + + this.suiteDivs[spec.suite.id].appendChild(specDiv); +}; + +jasmine.TrivialReporter.prototype.log = function() { + var console = jasmine.getGlobal().console; + if (console && console.log) { + if (console.log.apply) { + console.log.apply(console, arguments); + } else { + console.log(arguments); // ie fix: console.log.apply doesn't exist on ie + } + } +}; + +jasmine.TrivialReporter.prototype.getLocation = function() { + return this.document.location; +}; + +jasmine.TrivialReporter.prototype.specFilter = function(spec) { + var paramMap = {}; + var params = this.getLocation().search.substring(1).split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + } + + if (!paramMap.spec) { + return true; + } + return spec.getFullName().indexOf(paramMap.spec) === 0; +}; diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/index.html b/test/cordova/plugins/org.apache.cordova.device/test/autotest/index.html new file mode 100644 index 00000000..6ebccbd0 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/index.html @@ -0,0 +1,59 @@ + + + + + + + + + + Cordova API Specs + + + + + +

Cordova API Specs

+ + Run All Tests + Run Accelerometer Tests + Run Battery Tests + Run Camera Tests + Run Capture Tests + Run Compass Tests + Run Contacts Tests + Run Data URI Tests + Run Device Tests + Run File Tests + Run FileTransfer Tests + Run Geolocation Tests + Run Globalization Tests + Run Media Tests + Run Network Tests + Run Notification Tests + Run Platform Tests + Run Storage Tests + Run Bridge Tests + +

Back
+ + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.css b/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.css new file mode 100644 index 00000000..826e5753 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.css @@ -0,0 +1,81 @@ +body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } + +#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } +#HTMLReporter a { text-decoration: none; } +#HTMLReporter a:hover { text-decoration: underline; } +#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } +#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } +#HTMLReporter #jasmine_content { position: fixed; right: 100%; } +#HTMLReporter .version { color: #aaaaaa; } +#HTMLReporter .banner { margin-top: 14px; } +#HTMLReporter .duration { color: #aaaaaa; float: right; } +#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } +#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } +#HTMLReporter .symbolSummary li.passed { font-size: 14px; } +#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } +#HTMLReporter .symbolSummary li.failed { line-height: 9px; } +#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } +#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } +#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } +#HTMLReporter .symbolSummary li.pending { line-height: 11px; } +#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } +#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +#HTMLReporter .runningAlert { background-color: #666666; } +#HTMLReporter .skippedAlert { background-color: #aaaaaa; } +#HTMLReporter .skippedAlert:first-child { background-color: #333333; } +#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } +#HTMLReporter .passingAlert { background-color: #a6b779; } +#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } +#HTMLReporter .failingAlert { background-color: #cf867e; } +#HTMLReporter .failingAlert:first-child { background-color: #b03911; } +#HTMLReporter .results { margin-top: 14px; } +#HTMLReporter #details { display: none; } +#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } +#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } +#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } +#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } +#HTMLReporter.showDetails .summary { display: none; } +#HTMLReporter.showDetails #details { display: block; } +#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } +#HTMLReporter .summary { margin-top: 14px; } +#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } +#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } +#HTMLReporter .summary .specSummary.failed a { color: #b03911; } +#HTMLReporter .description + .suite { margin-top: 0; } +#HTMLReporter .suite { margin-top: 14px; } +#HTMLReporter .suite a { color: #333333; } +#HTMLReporter #details .specDetail { margin-bottom: 28px; } +#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } +#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } +#HTMLReporter .resultMessage span.result { display: block; } +#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } + +#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ } +#TrivialReporter a:visited, #TrivialReporter a { color: #303; } +#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; } +#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; } +#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; } +#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; } +#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; } +#TrivialReporter .runner.running { background-color: yellow; } +#TrivialReporter .options { text-align: right; font-size: .8em; } +#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; } +#TrivialReporter .suite .suite { margin: 5px; } +#TrivialReporter .suite.passed { background-color: #dfd; } +#TrivialReporter .suite.failed { background-color: #fdd; } +#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; } +#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; } +#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; } +#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; } +#TrivialReporter .spec.skipped { background-color: #bbb; } +#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; } +#TrivialReporter .passed { background-color: #cfc; display: none; } +#TrivialReporter .failed { background-color: #fbb; } +#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; } +#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; } +#TrivialReporter .resultMessage .mismatch { color: black; } +#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; } +#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; } +#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; } +#TrivialReporter #jasmine_content { position: fixed; right: 100%; } +#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; } diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.js new file mode 100644 index 00000000..bccb66c3 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/jasmine.js @@ -0,0 +1,2530 @@ +var isCommonJS = typeof window == "undefined"; + +/** + * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. + * + * @namespace + */ +var jasmine = {}; +if (isCommonJS) exports.jasmine = jasmine; +/** + * @private + */ +jasmine.unimplementedMethod_ = function() { + throw new Error("unimplemented method"); +}; + +/** + * Use jasmine.undefined instead of undefined, since undefined is just + * a plain old variable and may be redefined by somebody else. + * + * @private + */ +jasmine.undefined = jasmine.___undefined___; + +/** + * Show diagnostic messages in the console if set to true + * + */ +jasmine.VERBOSE = false; + +/** + * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. + * + */ +jasmine.DEFAULT_UPDATE_INTERVAL = 250; + +/** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +jasmine.getGlobal = function() { + function getGlobal() { + return this; + } + + return getGlobal(); +}; + +/** + * Allows for bound functions to be compared. Internal use only. + * + * @ignore + * @private + * @param base {Object} bound 'this' for the function + * @param name {Function} function to find + */ +jasmine.bindOriginal_ = function(base, name) { + var original = base[name]; + if (original.apply) { + return function() { + return original.apply(base, arguments); + }; + } else { + // IE support + return jasmine.getGlobal()[name]; + } +}; + +jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); +jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); +jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); +jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); + +jasmine.MessageResult = function(values) { + this.type = 'log'; + this.values = values; + this.trace = new Error(); // todo: test better +}; + +jasmine.MessageResult.prototype.toString = function() { + var text = ""; + for (var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; +}; + +jasmine.ExpectationResult = function(params) { + this.type = 'expect'; + this.matcherName = params.matcherName; + this.passed_ = params.passed; + this.expected = params.expected; + this.actual = params.actual; + this.message = this.passed_ ? 'Passed.' : params.message; + + var trace = (params.trace || new Error(this.message)); + this.trace = this.passed_ ? '' : trace; +}; + +jasmine.ExpectationResult.prototype.toString = function () { + return this.message; +}; + +jasmine.ExpectationResult.prototype.passed = function () { + return this.passed_; +}; + +/** + * Getter for the Jasmine environment. Ensures one gets created + */ +jasmine.getEnv = function() { + var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); + return env; +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isArray_ = function(value) { + return jasmine.isA_("Array", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isString_ = function(value) { + return jasmine.isA_("String", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isNumber_ = function(value) { + return jasmine.isA_("Number", value); +}; + +/** + * @ignore + * @private + * @param {String} typeName + * @param value + * @returns {Boolean} + */ +jasmine.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; +}; + +/** + * Pretty printer for expecations. Takes any object and turns it into a human-readable string. + * + * @param value {Object} an object to be outputted + * @returns {String} + */ +jasmine.pp = function(value) { + var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; +}; + +/** + * Returns true if the object is a DOM Node. + * + * @param {Object} obj object to check + * @returns {Boolean} + */ +jasmine.isDomNode = function(obj) { + return obj.nodeType > 0; +}; + +/** + * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. + * + * @example + * // don't care about which function is passed in, as long as it's a function + * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); + * + * @param {Class} clazz + * @returns matchable object of the type clazz + */ +jasmine.any = function(clazz) { + return new jasmine.Matchers.Any(clazz); +}; + +/** + * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the + * attributes on the object. + * + * @example + * // don't care about any other attributes than foo. + * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); + * + * @param sample {Object} sample + * @returns matchable object for the sample + */ +jasmine.objectContaining = function (sample) { + return new jasmine.Matchers.ObjectContaining(sample); +}; + +/** + * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. + * + * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine + * expectation syntax. Spies can be checked if they were called or not and what the calling params were. + * + * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). + * + * Spies are torn down at the end of every spec. + * + * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. + * + * @example + * // a stub + * var myStub = jasmine.createSpy('myStub'); // can be used anywhere + * + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // actual foo.not will not be called, execution stops + * spyOn(foo, 'not'); + + // foo.not spied upon, execution will continue to implementation + * spyOn(foo, 'not').andCallThrough(); + * + * // fake example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // foo.not(val) will return val + * spyOn(foo, 'not').andCallFake(function(value) {return value;}); + * + * // mock example + * foo.not(7 == 7); + * expect(foo.not).toHaveBeenCalled(); + * expect(foo.not).toHaveBeenCalledWith(true); + * + * @constructor + * @see spyOn, jasmine.createSpy, jasmine.createSpyObj + * @param {String} name + */ +jasmine.Spy = function(name) { + /** + * The name of the spy, if provided. + */ + this.identity = name || 'unknown'; + /** + * Is this Object a spy? + */ + this.isSpy = true; + /** + * The actual function this spy stubs. + */ + this.plan = function() { + }; + /** + * Tracking of the most recent call to the spy. + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy.mostRecentCall.args = [1, 2]; + */ + this.mostRecentCall = {}; + + /** + * Holds arguments for each call to the spy, indexed by call count + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy(7, 8); + * mySpy.mostRecentCall.args = [7, 8]; + * mySpy.argsForCall[0] = [1, 2]; + * mySpy.argsForCall[1] = [7, 8]; + */ + this.argsForCall = []; + this.calls = []; +}; + +/** + * Tells a spy to call through to the actual implemenatation. + * + * @example + * var foo = { + * bar: function() { // do some stuff } + * } + * + * // defining a spy on an existing property: foo.bar + * spyOn(foo, 'bar').andCallThrough(); + */ +jasmine.Spy.prototype.andCallThrough = function() { + this.plan = this.originalValue; + return this; +}; + +/** + * For setting the return value of a spy. + * + * @example + * // defining a spy from scratch: foo() returns 'baz' + * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); + * + * // defining a spy on an existing property: foo.bar() returns 'baz' + * spyOn(foo, 'bar').andReturn('baz'); + * + * @param {Object} value + */ +jasmine.Spy.prototype.andReturn = function(value) { + this.plan = function() { + return value; + }; + return this; +}; + +/** + * For throwing an exception when a spy is called. + * + * @example + * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' + * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); + * + * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' + * spyOn(foo, 'bar').andThrow('baz'); + * + * @param {String} exceptionMsg + */ +jasmine.Spy.prototype.andThrow = function(exceptionMsg) { + this.plan = function() { + throw exceptionMsg; + }; + return this; +}; + +/** + * Calls an alternate implementation when a spy is called. + * + * @example + * var baz = function() { + * // do some stuff, return something + * } + * // defining a spy from scratch: foo() calls the function baz + * var foo = jasmine.createSpy('spy on foo').andCall(baz); + * + * // defining a spy on an existing property: foo.bar() calls an anonymnous function + * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); + * + * @param {Function} fakeFunc + */ +jasmine.Spy.prototype.andCallFake = function(fakeFunc) { + this.plan = fakeFunc; + return this; +}; + +/** + * Resets all of a spy's the tracking variables so that it can be used again. + * + * @example + * spyOn(foo, 'bar'); + * + * foo.bar(); + * + * expect(foo.bar.callCount).toEqual(1); + * + * foo.bar.reset(); + * + * expect(foo.bar.callCount).toEqual(0); + */ +jasmine.Spy.prototype.reset = function() { + this.wasCalled = false; + this.callCount = 0; + this.argsForCall = []; + this.calls = []; + this.mostRecentCall = {}; +}; + +jasmine.createSpy = function(name) { + + var spyObj = function() { + spyObj.wasCalled = true; + spyObj.callCount++; + var args = jasmine.util.argsToArray(arguments); + spyObj.mostRecentCall.object = this; + spyObj.mostRecentCall.args = args; + spyObj.argsForCall.push(args); + spyObj.calls.push({object: this, args: args}); + return spyObj.plan.apply(this, arguments); + }; + + var spy = new jasmine.Spy(name); + + for (var prop in spy) { + spyObj[prop] = spy[prop]; + } + + spyObj.reset(); + + return spyObj; +}; + +/** + * Determines whether an object is a spy. + * + * @param {jasmine.Spy|Object} putativeSpy + * @returns {Boolean} + */ +jasmine.isSpy = function(putativeSpy) { + return putativeSpy && putativeSpy.isSpy; +}; + +/** + * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something + * large in one call. + * + * @param {String} baseName name of spy class + * @param {Array} methodNames array of names of methods to make spies + */ +jasmine.createSpyObj = function(baseName, methodNames) { + if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { + throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); + } + return obj; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the current spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); +}; + +/** + * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. + * + * @example + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops + * + * @see jasmine.createSpy + * @param obj + * @param methodName + * @returns a Jasmine spy that can be chained with all spy methods + */ +var spyOn = function(obj, methodName) { + return jasmine.getEnv().currentSpec.spyOn(obj, methodName); +}; +if (isCommonJS) exports.spyOn = spyOn; + +/** + * Creates a Jasmine spec that will be added to the current suite. + * + * // TODO: pending tests + * + * @example + * it('should be true', function() { + * expect(true).toEqual(true); + * }); + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var it = function(desc, func) { + return jasmine.getEnv().it(desc, func); +}; +if (isCommonJS) exports.it = it; + +/** + * Creates a disabled Jasmine spec. + * + * A convenience method that allows existing specs to be disabled temporarily during development. + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var xit = function(desc, func) { + return jasmine.getEnv().xit(desc, func); +}; +if (isCommonJS) exports.xit = xit; + +/** + * Starts a chain for a Jasmine expectation. + * + * It is passed an Object that is the actual value and should chain to one of the many + * jasmine.Matchers functions. + * + * @param {Object} actual Actual value to test against and expected value + */ +var expect = function(actual) { + return jasmine.getEnv().currentSpec.expect(actual); +}; +if (isCommonJS) exports.expect = expect; + +/** + * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. + * + * @param {Function} func Function that defines part of a jasmine spec. + */ +var runs = function(func) { + jasmine.getEnv().currentSpec.runs(func); +}; +if (isCommonJS) exports.runs = runs; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +var waits = function(timeout) { + jasmine.getEnv().currentSpec.waits(timeout); +}; +if (isCommonJS) exports.waits = waits; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); +}; +if (isCommonJS) exports.waitsFor = waitsFor; + +/** + * A function that is called before each spec in a suite. + * + * Used for spec setup, including validating assumptions. + * + * @param {Function} beforeEachFunction + */ +var beforeEach = function(beforeEachFunction) { + jasmine.getEnv().beforeEach(beforeEachFunction); +}; +if (isCommonJS) exports.beforeEach = beforeEach; + +/** + * A function that is called after each spec in a suite. + * + * Used for restoring any state that is hijacked during spec execution. + * + * @param {Function} afterEachFunction + */ +var afterEach = function(afterEachFunction) { + jasmine.getEnv().afterEach(afterEachFunction); +}; +if (isCommonJS) exports.afterEach = afterEach; + +/** + * Defines a suite of specifications. + * + * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared + * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization + * of setup in some tests. + * + * @example + * // TODO: a simple suite + * + * // TODO: a simple suite with a nested describe block + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var describe = function(description, specDefinitions) { + return jasmine.getEnv().describe(description, specDefinitions); +}; +if (isCommonJS) exports.describe = describe; + +/** + * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var xdescribe = function(description, specDefinitions) { + return jasmine.getEnv().xdescribe(description, specDefinitions); +}; +if (isCommonJS) exports.xdescribe = xdescribe; + + +// Provide the XMLHttpRequest class for IE 5.x-6.x: +jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { + function tryIt(f) { + try { + return f(); + } catch(e) { + } + return null; + } + + var xhr = tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.6.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP.3.0"); + }) || + tryIt(function() { + return new ActiveXObject("Msxml2.XMLHTTP"); + }) || + tryIt(function() { + return new ActiveXObject("Microsoft.XMLHTTP"); + }); + + if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); + + return xhr; +} : XMLHttpRequest; +/** + * @namespace + */ +jasmine.util = {}; + +/** + * Declare that a child class inherit it's prototype from the parent class. + * + * @private + * @param {Function} childClass + * @param {Function} parentClass + */ +jasmine.util.inherit = function(childClass, parentClass) { + /** + * @private + */ + var subclass = function() { + }; + subclass.prototype = parentClass.prototype; + childClass.prototype = new subclass(); +}; + +jasmine.util.formatException = function(e) { + var lineNumber; + if (e.line) { + lineNumber = e.line; + } + else if (e.lineNumber) { + lineNumber = e.lineNumber; + } + + var file; + + if (e.sourceURL) { + file = e.sourceURL; + } + else if (e.fileName) { + file = e.fileName; + } + + var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); + + if (file && lineNumber) { + message += ' in ' + file + ' (line ' + lineNumber + ')'; + } + + return message; +}; + +jasmine.util.htmlEscape = function(str) { + if (!str) return str; + return str.replace(/&/g, '&') + .replace(//g, '>'); +}; + +jasmine.util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); + return arrayOfArgs; +}; + +jasmine.util.extend = function(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +}; + +/** + * Environment for Jasmine + * + * @constructor + */ +jasmine.Env = function() { + this.currentSpec = null; + this.currentSuite = null; + this.currentRunner_ = new jasmine.Runner(this); + + this.reporter = new jasmine.MultiReporter(); + + this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; + this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; + this.lastUpdate = 0; + this.specFilter = function() { + return true; + }; + + this.nextSpecId_ = 0; + this.nextSuiteId_ = 0; + this.equalityTesters_ = []; + + // wrap matchers + this.matchersClass = function() { + jasmine.Matchers.apply(this, arguments); + }; + jasmine.util.inherit(this.matchersClass, jasmine.Matchers); + + jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); +}; + + +jasmine.Env.prototype.setTimeout = jasmine.setTimeout; +jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; +jasmine.Env.prototype.setInterval = jasmine.setInterval; +jasmine.Env.prototype.clearInterval = jasmine.clearInterval; + +/** + * @returns an object containing jasmine version build info, if set. + */ +jasmine.Env.prototype.version = function () { + if (jasmine.version_) { + return jasmine.version_; + } else { + throw new Error('Version not set'); + } +}; + +/** + * @returns string containing jasmine version build info, if set. + */ +jasmine.Env.prototype.versionString = function() { + if (!jasmine.version_) { + return "version unknown"; + } + + var version = this.version(); + var versionString = version.major + "." + version.minor + "." + version.build; + if (version.release_candidate) { + versionString += ".rc" + version.release_candidate; + } + versionString += " revision " + version.revision; + return versionString; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSpecId = function () { + return this.nextSpecId_++; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSuiteId = function () { + return this.nextSuiteId_++; +}; + +/** + * Register a reporter to receive status updates from Jasmine. + * @param {jasmine.Reporter} reporter An object which will receive status updates. + */ +jasmine.Env.prototype.addReporter = function(reporter) { + this.reporter.addReporter(reporter); +}; + +jasmine.Env.prototype.execute = function() { + this.currentRunner_.execute(); +}; + +jasmine.Env.prototype.describe = function(description, specDefinitions) { + var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); + + var parentSuite = this.currentSuite; + if (parentSuite) { + parentSuite.add(suite); + } else { + this.currentRunner_.add(suite); + } + + this.currentSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch(e) { + declarationError = e; + } + + if (declarationError) { + this.it("encountered a declaration exception", function() { + throw declarationError; + }); + } + + this.currentSuite = parentSuite; + + return suite; +}; + +jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { + if (this.currentSuite) { + this.currentSuite.beforeEach(beforeEachFunction); + } else { + this.currentRunner_.beforeEach(beforeEachFunction); + } +}; + +jasmine.Env.prototype.currentRunner = function () { + return this.currentRunner_; +}; + +jasmine.Env.prototype.afterEach = function(afterEachFunction) { + if (this.currentSuite) { + this.currentSuite.afterEach(afterEachFunction); + } else { + this.currentRunner_.afterEach(afterEachFunction); + } + +}; + +jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { + return { + execute: function() { + } + }; +}; + +jasmine.Env.prototype.it = function(description, func) { + var spec = new jasmine.Spec(this, this.currentSuite, description); + this.currentSuite.add(spec); + this.currentSpec = spec; + + if (func) { + spec.runs(func); + } + + return spec; +}; + +jasmine.Env.prototype.xit = function(desc, func) { + return { + id: this.nextSpecId(), + runs: function() { + } + }; +}; + +jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { + if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { + return true; + } + + a.__Jasmine_been_here_before__ = b; + b.__Jasmine_been_here_before__ = a; + + var hasKey = function(obj, keyName) { + return obj !== null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in b) { + if (!hasKey(a, property) && hasKey(b, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + } + for (property in a) { + if (!hasKey(b, property) && hasKey(a, property)) { + mismatchKeys.push("expected missing key '" + property + "', but present in actual."); + } + } + for (property in b) { + if (property == '__Jasmine_been_here_before__') continue; + if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); + } + } + + if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { + mismatchValues.push("arrays were not the same length"); + } + + delete a.__Jasmine_been_here_before__; + delete b.__Jasmine_been_here_before__; + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + for (var i = 0; i < this.equalityTesters_.length; i++) { + var equalityTester = this.equalityTesters_[i]; + var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); + if (result !== jasmine.undefined) return result; + } + + if (a === b) return true; + + if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { + return (a == jasmine.undefined && b == jasmine.undefined); + } + + if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { + return a === b; + } + + if (a instanceof Date && b instanceof Date) { + return a.getTime() == b.getTime(); + } + + if (a.jasmineMatches) { + return a.jasmineMatches(b); + } + + if (b.jasmineMatches) { + return b.jasmineMatches(a); + } + + if (a instanceof jasmine.Matchers.ObjectContaining) { + return a.matches(b); + } + + if (b instanceof jasmine.Matchers.ObjectContaining) { + return b.matches(a); + } + + if (jasmine.isString_(a) && jasmine.isString_(b)) { + return (a == b); + } + + if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { + return (a == b); + } + + if (typeof a === "object" && typeof b === "object") { + return this.compareObjects_(a, b, mismatchKeys, mismatchValues); + } + + //Straight check + return (a === b); +}; + +jasmine.Env.prototype.contains_ = function(haystack, needle) { + if (jasmine.isArray_(haystack)) { + for (var i = 0; i < haystack.length; i++) { + if (this.equals_(haystack[i], needle)) return true; + } + return false; + } + return haystack.indexOf(needle) >= 0; +}; + +jasmine.Env.prototype.addEqualityTester = function(equalityTester) { + this.equalityTesters_.push(equalityTester); +}; +/** No-op base class for Jasmine reporters. + * + * @constructor + */ +jasmine.Reporter = function() { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerResults = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecStarting = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecResults = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.log = function(str) { +}; + +/** + * Blocks are functions with executable code that make up a spec. + * + * @constructor + * @param {jasmine.Env} env + * @param {Function} func + * @param {jasmine.Spec} spec + */ +jasmine.Block = function(env, func, spec) { + this.env = env; + this.func = func; + this.spec = spec; +}; + +jasmine.Block.prototype.execute = function(onComplete) { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } + onComplete(); +}; +/** JavaScript API reporter. + * + * @constructor + */ +jasmine.JsApiReporter = function() { + this.started = false; + this.finished = false; + this.suites_ = []; + this.results_ = {}; +}; + +jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { + this.started = true; + var suites = runner.topLevelSuites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + this.suites_.push(this.summarize_(suite)); + } +}; + +jasmine.JsApiReporter.prototype.suites = function() { + return this.suites_; +}; + +jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { + var isSuite = suiteOrSpec instanceof jasmine.Suite; + var summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: isSuite ? 'suite' : 'spec', + children: [] + }; + + if (isSuite) { + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); + } + } + return summary; +}; + +jasmine.JsApiReporter.prototype.results = function() { + return this.results_; +}; + +jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { + return this.results_[specId]; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { + this.finished = true; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { + this.results_[spec.id] = { + messages: spec.results().getItems(), + result: spec.results().failedCount > 0 ? "failed" : "passed" + }; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.log = function(str) { +}; + +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + var messagesLength = result.messages.length; + for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined + } + }); + } + + return { + result : result.result, + messages : summaryMessages + }; +}; + +/** + * @constructor + * @param {jasmine.Env} env + * @param actual + * @param {jasmine.Spec} spec + */ +jasmine.Matchers = function(env, actual, spec, opt_isNot) { + this.env = env; + this.actual = actual; + this.spec = spec; + this.isNot = opt_isNot || false; + this.reportWasCalled_ = false; +}; + +// todo: @deprecated as of Jasmine 0.11, remove soon [xw] +jasmine.Matchers.pp = function(str) { + throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); +}; + +// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] +jasmine.Matchers.prototype.report = function(result, failing_message, details) { + throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); +}; + +jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { + for (var methodName in prototype) { + if (methodName == 'report') continue; + var orig = prototype[methodName]; + matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); + } +}; + +jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { + return function() { + var matcherArgs = jasmine.util.argsToArray(arguments); + var result = matcherFunction.apply(this, arguments); + + if (this.isNot) { + result = !result; + } + + if (this.reportWasCalled_) return result; + + var message; + if (!result) { + if (this.message) { + message = this.message.apply(this, arguments); + if (jasmine.isArray_(message)) { + message = message[this.isNot ? 1 : 0]; + } + } else { + var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; + if (matcherArgs.length > 0) { + for (var i = 0; i < matcherArgs.length; i++) { + if (i > 0) message += ","; + message += " " + jasmine.pp(matcherArgs[i]); + } + } + message += "."; + } + } + var expectationResult = new jasmine.ExpectationResult({ + matcherName: matcherName, + passed: result, + expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], + actual: this.actual, + message: message + }); + this.spec.addMatcherResult(expectationResult); + return jasmine.undefined; + }; +}; + + + + +/** + * toBe: compares the actual to the expected using === + * @param expected + */ +jasmine.Matchers.prototype.toBe = function(expected) { + return this.actual === expected; +}; + +/** + * toNotBe: compares the actual to the expected using !== + * @param expected + * @deprecated as of 1.0. Use not.toBe() instead. + */ +jasmine.Matchers.prototype.toNotBe = function(expected) { + return this.actual !== expected; +}; + +/** + * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. + * + * @param expected + */ +jasmine.Matchers.prototype.toEqual = function(expected) { + return this.env.equals_(this.actual, expected); +}; + +/** + * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual + * @param expected + * @deprecated as of 1.0. Use not.toEqual() instead. + */ +jasmine.Matchers.prototype.toNotEqual = function(expected) { + return !this.env.equals_(this.actual, expected); +}; + +/** + * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes + * a pattern or a String. + * + * @param expected + */ +jasmine.Matchers.prototype.toMatch = function(expected) { + return new RegExp(expected).test(this.actual); +}; + +/** + * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch + * @param expected + * @deprecated as of 1.0. Use not.toMatch() instead. + */ +jasmine.Matchers.prototype.toNotMatch = function(expected) { + return !(new RegExp(expected).test(this.actual)); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeDefined = function() { + return (this.actual !== jasmine.undefined); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeUndefined = function() { + return (this.actual === jasmine.undefined); +}; + +/** + * Matcher that compares the actual to null. + */ +jasmine.Matchers.prototype.toBeNull = function() { + return (this.actual === null); +}; + +/** + * Matcher that boolean not-nots the actual. + */ +jasmine.Matchers.prototype.toBeTruthy = function() { + return !!this.actual; +}; + + +/** + * Matcher that boolean nots the actual. + */ +jasmine.Matchers.prototype.toBeFalsy = function() { + return !this.actual; +}; + + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called. + */ +jasmine.Matchers.prototype.toHaveBeenCalled = function() { + if (arguments.length > 0) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to have been called.", + "Expected spy " + this.actual.identity + " not to have been called." + ]; + }; + + return this.actual.wasCalled; +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ +jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was not called. + * + * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead + */ +jasmine.Matchers.prototype.wasNotCalled = function() { + if (arguments.length > 0) { + throw new Error('wasNotCalled does not take arguments'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to not have been called.", + "Expected spy " + this.actual.identity + " to have been called." + ]; + }; + + return !this.actual.wasCalled; +}; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. + * + * @example + * + */ +jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + this.message = function() { + if (this.actual.callCount === 0) { + // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." + ]; + } else { + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) + ]; + } + }; + + return this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; + +/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasNotCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" + ]; + }; + + return !this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** + * Matcher that checks that the expected item is an element in the actual Array. + * + * @param {Object} expected + */ +jasmine.Matchers.prototype.toContain = function(expected) { + return this.env.contains_(this.actual, expected); +}; + +/** + * Matcher that checks that the expected item is NOT an element in the actual Array. + * + * @param {Object} expected + * @deprecated as of 1.0. Use not.toContain() instead. + */ +jasmine.Matchers.prototype.toNotContain = function(expected) { + return !this.env.contains_(this.actual, expected); +}; + +jasmine.Matchers.prototype.toBeLessThan = function(expected) { + return this.actual < expected; +}; + +jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { + return this.actual > expected; +}; + +/** + * Matcher that checks that the expected item is equal to the actual item + * up to a given level of decimal precision (default 2). + * + * @param {Number} expected + * @param {Number} precision + */ +jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { + if (!(precision === 0)) { + precision = precision || 2; + } + var multiplier = Math.pow(10, precision); + var actual = Math.round(this.actual * multiplier); + expected = Math.round(expected * multiplier); + return expected == actual; +}; + +/** + * Matcher that checks that the expected exception was thrown by the actual. + * + * @param {String} expected + */ +jasmine.Matchers.prototype.toThrow = function(expected) { + var result = false; + var exception; + if (typeof this.actual != 'function') { + throw new Error('Actual is not a function'); + } + try { + this.actual(); + } catch (e) { + exception = e; + } + if (exception) { + result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); + } + + var not = this.isNot ? "not " : ""; + + this.message = function() { + if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { + return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); + } else { + return "Expected function to throw an exception."; + } + }; + + return result; +}; + +jasmine.Matchers.Any = function(expectedClass) { + this.expectedClass = expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { + if (this.expectedClass == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedClass == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedClass == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedClass == Object) { + return typeof other == 'object'; + } + + return other instanceof this.expectedClass; +}; + +jasmine.Matchers.Any.prototype.jasmineToString = function() { + return ''; +}; + +jasmine.Matchers.ObjectContaining = function (sample) { + this.sample = sample; +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + var env = jasmine.getEnv(); + + var hasKey = function(obj, keyName) { + return obj != null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in this.sample) { + if (!hasKey(other, property) && hasKey(this.sample, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); + } + } + + return (mismatchKeys.length === 0 && mismatchValues.length === 0); +}; + +jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { + return ""; +}; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + +/** + * @namespace + */ +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + if (!jasmine.Clock.isInstalled()) { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + } + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + +/** + * @constructor + */ +jasmine.MultiReporter = function() { + this.subReporters_ = []; +}; +jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); + +jasmine.MultiReporter.prototype.addReporter = function(reporter) { + this.subReporters_.push(reporter); +}; + +(function() { + var functionNames = [ + "reportRunnerStarting", + "reportRunnerResults", + "reportSuiteResults", + "reportSpecStarting", + "reportSpecResults", + "log" + ]; + for (var i = 0; i < functionNames.length; i++) { + var functionName = functionNames[i]; + jasmine.MultiReporter.prototype[functionName] = (function(functionName) { + return function() { + for (var j = 0; j < this.subReporters_.length; j++) { + var subReporter = this.subReporters_[j]; + if (subReporter[functionName]) { + subReporter[functionName].apply(subReporter, arguments); + } + } + }; + })(functionName); + } +})(); +/** + * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults + * + * @constructor + */ +jasmine.NestedResults = function() { + /** + * The total count of results + */ + this.totalCount = 0; + /** + * Number of passed results + */ + this.passedCount = 0; + /** + * Number of failed results + */ + this.failedCount = 0; + /** + * Was this suite/spec skipped? + */ + this.skipped = false; + /** + * @ignore + */ + this.items_ = []; +}; + +/** + * Roll up the result counts. + * + * @param result + */ +jasmine.NestedResults.prototype.rollupCounts = function(result) { + this.totalCount += result.totalCount; + this.passedCount += result.passedCount; + this.failedCount += result.failedCount; +}; + +/** + * Adds a log message. + * @param values Array of message parts which will be concatenated later. + */ +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); +}; + +/** + * Getter for the results: message & results. + */ +jasmine.NestedResults.prototype.getItems = function() { + return this.items_; +}; + +/** + * Adds a result, tracking counts (total, passed, & failed) + * @param {jasmine.ExpectationResult|jasmine.NestedResults} result + */ +jasmine.NestedResults.prototype.addResult = function(result) { + if (result.type != 'log') { + if (result.items_) { + this.rollupCounts(result); + } else { + this.totalCount++; + if (result.passed()) { + this.passedCount++; + } else { + this.failedCount++; + } + } + } + this.items_.push(result); +}; + +/** + * @returns {Boolean} True if everything below passed + */ +jasmine.NestedResults.prototype.passed = function() { + return this.passedCount === this.totalCount; +}; +/** + * Base class for pretty printing for expectation results. + */ +jasmine.PrettyPrinter = function() { + this.ppNestLevel_ = 0; +}; + +/** + * Formats a value in a nice, human-readable string. + * + * @param value + */ +jasmine.PrettyPrinter.prototype.format = function(value) { + if (this.ppNestLevel_ > 40) { + throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); + } + + this.ppNestLevel_++; + try { + if (value === jasmine.undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (jasmine.isSpy(value)) { + this.emitScalar("spy on " + value.identity); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.__Jasmine_been_here_before__) { + this.emitScalar(''); + } else if (jasmine.isArray_(value) || typeof value == 'object') { + value.__Jasmine_been_here_before__ = true; + if (jasmine.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + delete value.__Jasmine_been_here_before__; + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } +}; + +jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (property == '__Jasmine_been_here_before__') continue; + fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && + obj.__lookupGetter__(property) !== null) : false); + } +}; + +jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; + +jasmine.StringPrettyPrinter = function() { + jasmine.PrettyPrinter.call(this); + + this.string = ''; +}; +jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); + +jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); +}; + +jasmine.StringPrettyPrinter.prototype.emitString = function(value) { + this.append("'" + value + "'"); +}; + +jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { + this.append('[ '); + for (var i = 0; i < array.length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + this.append(' ]'); +}; + +jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { + var self = this; + this.append('{ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(' : '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +jasmine.Queue = function(env) { + this.env = env; + this.blocks = []; + this.running = false; + this.index = 0; + this.offset = 0; + this.abort = false; +}; + +jasmine.Queue.prototype.addBefore = function(block) { + this.blocks.unshift(block); +}; + +jasmine.Queue.prototype.add = function(block) { + this.blocks.push(block); +}; + +jasmine.Queue.prototype.insertNext = function(block) { + this.blocks.splice((this.index + this.offset + 1), 0, block); + this.offset++; +}; + +jasmine.Queue.prototype.start = function(onComplete) { + this.running = true; + this.onComplete = onComplete; + this.next_(); +}; + +jasmine.Queue.prototype.isRunning = function() { + return this.running; +}; + +jasmine.Queue.LOOP_DONT_RECURSE = true; + +jasmine.Queue.prototype.next_ = function() { + var self = this; + var goAgain = true; + + while (goAgain) { + goAgain = false; + + if (self.index < self.blocks.length && !this.abort) { + var calledSynchronously = true; + var completedSynchronously = false; + + var onComplete = function () { + if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { + completedSynchronously = true; + return; + } + + if (self.blocks[self.index].abort) { + self.abort = true; + } + + self.offset = 0; + self.index++; + + var now = new Date().getTime(); + if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { + self.env.lastUpdate = now; + self.env.setTimeout(function() { + self.next_(); + }, 0); + } else { + if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { + goAgain = true; + } else { + self.next_(); + } + } + }; + self.blocks[self.index].execute(onComplete); + + calledSynchronously = false; + if (completedSynchronously) { + onComplete(); + } + + } else { + self.running = false; + if (self.onComplete) { + self.onComplete(); + } + } + } +}; + +jasmine.Queue.prototype.results = function() { + var results = new jasmine.NestedResults(); + for (var i = 0; i < this.blocks.length; i++) { + if (this.blocks[i].results) { + results.addResult(this.blocks[i].results()); + } + } + return results; +}; + + +/** + * Runner + * + * @constructor + * @param {jasmine.Env} env + */ +jasmine.Runner = function(env) { + var self = this; + self.env = env; + self.queue = new jasmine.Queue(env); + self.before_ = []; + self.after_ = []; + self.suites_ = []; +}; + +jasmine.Runner.prototype.execute = function() { + var self = this; + if (self.env.reporter.reportRunnerStarting) { + self.env.reporter.reportRunnerStarting(this); + } + self.queue.start(function () { + self.finishCallback(); + }); +}; + +jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.splice(0,0,beforeEachFunction); +}; + +jasmine.Runner.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.splice(0,0,afterEachFunction); +}; + + +jasmine.Runner.prototype.finishCallback = function() { + this.env.reporter.reportRunnerResults(this); +}; + +jasmine.Runner.prototype.addSuite = function(suite) { + this.suites_.push(suite); +}; + +jasmine.Runner.prototype.add = function(block) { + if (block instanceof jasmine.Suite) { + this.addSuite(block); + } + this.queue.add(block); +}; + +jasmine.Runner.prototype.specs = function () { + var suites = this.suites(); + var specs = []; + for (var i = 0; i < suites.length; i++) { + specs = specs.concat(suites[i].specs()); + } + return specs; +}; + +jasmine.Runner.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Runner.prototype.topLevelSuites = function() { + var topLevelSuites = []; + for (var i = 0; i < this.suites_.length; i++) { + if (!this.suites_[i].parentSuite) { + topLevelSuites.push(this.suites_[i]); + } + } + return topLevelSuites; +}; + +jasmine.Runner.prototype.results = function() { + return this.queue.results(); +}; +/** + * Internal representation of a Jasmine specification, or test. + * + * @constructor + * @param {jasmine.Env} env + * @param {jasmine.Suite} suite + * @param {String} description + */ +jasmine.Spec = function(env, suite, description) { + if (!env) { + throw new Error('jasmine.Env() required'); + } + if (!suite) { + throw new Error('jasmine.Suite() required'); + } + var spec = this; + spec.id = env.nextSpecId ? env.nextSpecId() : null; + spec.env = env; + spec.suite = suite; + spec.description = description; + spec.queue = new jasmine.Queue(env); + + spec.afterCallbacks = []; + spec.spies_ = []; + + spec.results_ = new jasmine.NestedResults(); + spec.results_.description = description; + spec.matchersClass = null; +}; + +jasmine.Spec.prototype.getFullName = function() { + return this.suite.getFullName() + ' ' + this.description + '.'; +}; + + +jasmine.Spec.prototype.results = function() { + return this.results_; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); +}; + +jasmine.Spec.prototype.runs = function (func) { + var block = new jasmine.Block(this.env, func, this); + this.addToQueue(block); + return this; +}; + +jasmine.Spec.prototype.addToQueue = function (block) { + if (this.queue.isRunning()) { + this.queue.insertNext(block); + } else { + this.queue.add(block); + } +}; + +/** + * @param {jasmine.ExpectationResult} result + */ +jasmine.Spec.prototype.addMatcherResult = function(result) { + this.results_.addResult(result); +}; + +jasmine.Spec.prototype.expect = function(actual) { + var positive = new (this.getMatchersClass_())(this.env, actual, this); + positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); + return positive; +}; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +jasmine.Spec.prototype.waits = function(timeout) { + var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); + this.addToQueue(waitsFunc); + return this; +}; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + var latchFunction_ = null; + var optional_timeoutMessage_ = null; + var optional_timeout_ = null; + + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + switch (typeof arg) { + case 'function': + latchFunction_ = arg; + break; + case 'string': + optional_timeoutMessage_ = arg; + break; + case 'number': + optional_timeout_ = arg; + break; + } + } + + var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); + this.addToQueue(waitsForFunc); + return this; +}; + +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception', + trace: { stack: e.stack } + }); + this.results_.addResult(expectationResult); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || this.env.matchersClass; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function(onComplete) { + this.removeAllSpies(); + this.finishCallback(); + if (onComplete) { + onComplete(); + } +}; + +jasmine.Spec.prototype.after = function(doAfter) { + if (this.queue.isRunning()) { + this.queue.add(new jasmine.Block(this.env, doAfter, this)); + } else { + this.afterCallbacks.unshift(doAfter); + } +}; + +jasmine.Spec.prototype.execute = function(onComplete) { + var spec = this; + if (!spec.env.specFilter(spec)) { + spec.results_.skipped = true; + spec.finish(onComplete); + return; + } + + this.env.reporter.reportSpecStarting(this); + + spec.env.currentSpec = spec; + + spec.addBeforesAndAftersToQueue(); + + spec.queue.start(function () { + spec.finish(onComplete); + }); +}; + +jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { + var runner = this.env.currentRunner(); + var i; + + for (var suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); + } + } + for (i = 0; i < runner.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); + } + for (i = 0; i < this.afterCallbacks.length; i++) { + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + } + for (suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == jasmine.undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { + throw methodName + '() method does not exist'; + } + + if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { + throw new Error(methodName + ' has already been spied upon'); + } + + var spyObj = jasmine.createSpy(methodName); + + this.spies_.push(spyObj); + spyObj.baseObj = obj; + spyObj.methodName = methodName; + spyObj.originalValue = obj[methodName]; + + obj[methodName] = spyObj; + + return spyObj; +}; + +jasmine.Spec.prototype.removeAllSpies = function() { + for (var i = 0; i < this.spies_.length; i++) { + var spy = this.spies_[i]; + spy.baseObj[spy.methodName] = spy.originalValue; + } + this.spies_ = []; +}; + +/** + * Internal representation of a Jasmine suite. + * + * @constructor + * @param {jasmine.Env} env + * @param {String} description + * @param {Function} specDefinitions + * @param {jasmine.Suite} parentSuite + */ +jasmine.Suite = function(env, description, specDefinitions, parentSuite) { + var self = this; + self.id = env.nextSuiteId ? env.nextSuiteId() : null; + self.description = description; + self.queue = new jasmine.Queue(env); + self.parentSuite = parentSuite; + self.env = env; + self.before_ = []; + self.after_ = []; + self.children_ = []; + self.suites_ = []; + self.specs_ = []; +}; + +jasmine.Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + return fullName; +}; + +jasmine.Suite.prototype.finish = function(onComplete) { + this.env.reporter.reportSuiteResults(this); + this.finished = true; + if (typeof(onComplete) == 'function') { + onComplete(); + } +}; + +jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.unshift(beforeEachFunction); +}; + +jasmine.Suite.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.unshift(afterEachFunction); +}; + +jasmine.Suite.prototype.results = function() { + return this.queue.results(); +}; + +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); + } else { + this.specs_.push(suiteOrSpec); + } + this.queue.add(suiteOrSpec); +}; + +jasmine.Suite.prototype.specs = function() { + return this.specs_; +}; + +jasmine.Suite.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Suite.prototype.children = function() { + return this.children_; +}; + +jasmine.Suite.prototype.execute = function(onComplete) { + var self = this; + this.queue.start(function () { + self.finish(onComplete); + }); +}; +jasmine.WaitsBlock = function(env, timeout, spec) { + this.timeout = timeout; + jasmine.Block.call(this, env, null, spec); +}; + +jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); + +jasmine.WaitsBlock.prototype.execute = function (onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); + } + this.env.setTimeout(function () { + onComplete(); + }, this.timeout); +}; +/** + * A block which waits for some condition to become true, with timeout. + * + * @constructor + * @extends jasmine.Block + * @param {jasmine.Env} env The Jasmine environment. + * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. + * @param {Function} latchFunction A function which returns true when the desired condition has been met. + * @param {String} message The message to display if the desired condition hasn't been met within the given time period. + * @param {jasmine.Spec} spec The Jasmine spec. + */ +jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { + this.timeout = timeout || env.defaultTimeoutInterval; + this.latchFunction = latchFunction; + this.message = message; + this.totalTimeSpentWaitingForLatch = 0; + jasmine.Block.call(this, env, null, spec); +}; +jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); + +jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; + +jasmine.WaitsForBlock.prototype.execute = function(onComplete) { + if (jasmine.VERBOSE) { + this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); + } + var latchFunctionResult; + try { + latchFunctionResult = this.latchFunction.apply(this.spec); + } catch (e) { + this.spec.fail(e); + onComplete(); + return; + } + + if (latchFunctionResult) { + onComplete(); + } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { + var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); + this.spec.fail({ + name: 'timeout', + message: message + }); + + this.abort = true; + onComplete(); + } else { + this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + var self = this; + this.env.setTimeout(function() { + self.execute(onComplete); + }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; + +jasmine.version_= { + "major": 1, + "minor": 2, + "build": 0, + "revision": 1333310630, + "release_candidate": 1 +}; diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/pages/device.html b/test/cordova/plugins/org.apache.cordova.device/test/autotest/pages/device.html new file mode 100644 index 00000000..7252e672 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/pages/device.html @@ -0,0 +1,71 @@ + + + + + + + + Cordova: Device API Specs + + + + + + + + + + + + + + + + + + + + + + + + + + Back + + + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/test-runner.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/test-runner.js new file mode 100644 index 00000000..f72b3cc5 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/test-runner.js @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +if (window.sessionStorage != null) { + window.sessionStorage.clear(); +} + +// Timeout is 2 seconds to allow physical devices enough +// time to query the response. This is important for some +// Android devices. +var Tests = function() {}; +Tests.TEST_TIMEOUT = 7500; + +// Creates a spy that will fail if called. +function createDoNotCallSpy(name, opt_extraMessage) { + return jasmine.createSpy().andCallFake(function() { + var errorMessage = name + ' should not have been called.'; + if (arguments.length) { + errorMessage += ' Got args: ' + JSON.stringify(arguments); + } + if (opt_extraMessage) { + errorMessage += '\n' + opt_extraMessage; + } + expect(false).toBe(true, errorMessage); + }); +} + +// Waits for any of the given spys to be called. +// Last param may be a custom timeout duration. +function waitsForAny() { + var spys = [].slice.call(arguments); + var timeout = Tests.TEST_TIMEOUT; + if (typeof spys[spys.length - 1] == 'number') { + timeout = spys.pop(); + } + waitsFor(function() { + for (var i = 0; i < spys.length; ++i) { + if (spys[i].wasCalled) { + return true; + } + } + return false; + }, "Expecting callbacks to be called.", timeout); +} diff --git a/test/cordova/plugins/org.apache.cordova.device/test/autotest/tests/device.tests.js b/test/cordova/plugins/org.apache.cordova.device/test/autotest/tests/device.tests.js new file mode 100644 index 00000000..0bcd0d92 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/autotest/tests/device.tests.js @@ -0,0 +1,64 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +describe('Device Information (window.device)', function () { + it("should exist", function() { + expect(window.device).toBeDefined(); + }); + + it("should contain a platform specification that is a string", function() { + expect(window.device.platform).toBeDefined(); + expect((new String(window.device.platform)).length > 0).toBe(true); + }); + + it("should contain a version specification that is a string", function() { + expect(window.device.version).toBeDefined(); + expect((new String(window.device.version)).length > 0).toBe(true); + }); + + it("should contain a UUID specification that is a string or a number", function() { + expect(window.device.uuid).toBeDefined(); + if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') { + expect((new String(window.device.uuid)).length > 0).toBe(true); + } else { + expect(window.device.uuid > 0).toBe(true); + } + }); + + it("should contain a cordova specification that is a string", function() { + expect(window.device.cordova).toBeDefined(); + expect((new String(window.device.cordova)).length > 0).toBe(true); + }); + + it("should depend on the precense of cordova.version string", function() { + expect(window.cordova.version).toBeDefined(); + expect((new String(window.cordova.version)).length > 0).toBe(true); + }); + + it("should contain device.cordova equal to cordova.version", function() { + expect(window.device.cordova).toBe(window.cordova.version); + }); + + it("should contain a model specification that is a string", function() { + expect(window.device.model).toBeDefined(); + expect((new String(window.device.model)).length > 0).toBe(true); + }); +}); diff --git a/test/cordova/plugins/org.apache.cordova.device/test/cordova-incl.js b/test/cordova/plugins/org.apache.cordova.device/test/cordova-incl.js new file mode 100644 index 00000000..a82c590f --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/cordova-incl.js @@ -0,0 +1,85 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +var PLAT; +(function getPlatform() { + var platforms = { + android: /Android/, + ios: /(iPad)|(iPhone)|(iPod)/, + blackberry10: /(BB10)/, + blackberry: /(PlayBook)|(BlackBerry)/, + windows8: /MSAppHost/, + windowsphone: /Windows Phone/ + }; + for (var key in platforms) { + if (platforms[key].exec(navigator.userAgent)) { + PLAT = key; + break; + } + } +})(); + +var scripts = document.getElementsByTagName('script'); +var currentPath = scripts[scripts.length - 1].src; +var platformCordovaPath = currentPath.replace("cordova-incl.js", "cordova." + PLAT + ".js"); +var normalCordovaPath = currentPath.replace("cordova-incl.js", "cordova.js"); +var cordovaPath = normalCordovaPath; + +if (PLAT) { + // XHR to local file is an error on some platforms, windowsphone for one + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", platformCordovaPath, false); + xhr.onreadystatechange = function() { + + if (this.readyState == this.DONE && this.responseText.length > 0) { + if(parseInt(this.status) >= 400){ + cordovaPath = normalCordovaPath; + }else{ + cordovaPath = platformCordovaPath; + } + } + }; + xhr.send(null); + } + catch(e){ + cordovaPath = normalCordovaPath; + } // access denied! +} + +if (!window._doNotWriteCordovaScript) { + if (PLAT != "windows8") { + document.write(''); + } else { + var s = document.createElement('script'); + s.src = cordovaPath; + document.head.appendChild(s); + } +} + +function backHome() { + if (window.device && device.platform && device.platform.toLowerCase() == 'android') { + navigator.app.backHistory(); + } + else { + window.history.go(-1); + } +} diff --git a/test/cordova/plugins/org.apache.cordova.device/test/index.html b/test/cordova/plugins/org.apache.cordova.device/test/index.html new file mode 100644 index 00000000..82f6d3b4 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/index.html @@ -0,0 +1,66 @@ + + + + + + + + + Cordova Mobile Spec + + + + + + +

Apache Cordova Tests

+
+

cordova.version:

+

Platform:

+

Version:

+

UUID:

+

Model:

+

Width: , Height: + , Color Depth:

+

User-Agent:

+
+ Automatic Test + Accelerometer + Audio Play/Record + Battery + Camera + Capture + Compass + Contacts + Events + Location + Lazy Loading of cordova-incl.js + Misc Content + Network + Notification + Splashscreen + Web SQL + Local Storage + Benchmarks + In App Browser + + diff --git a/test/cordova/plugins/org.apache.cordova.device/test/main.js b/test/cordova/plugins/org.apache.cordova.device/test/main.js new file mode 100644 index 00000000..9508770c --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/main.js @@ -0,0 +1,163 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +var deviceInfo = function() { + document.getElementById("cordova").innerHTML = cordova.version; + document.getElementById("platform").innerHTML = device.platform; + document.getElementById("version").innerHTML = device.version; + document.getElementById("uuid").innerHTML = device.uuid; + document.getElementById("model").innerHTML = device.model; + document.getElementById("width").innerHTML = screen.width; + document.getElementById("height").innerHTML = screen.height; + document.getElementById("colorDepth").innerHTML = screen.colorDepth; +}; + +var getLocation = function() { + var suc = function(p) { + alert(p.coords.latitude + " " + p.coords.longitude); + }; + var locFail = function() { + }; + navigator.geolocation.getCurrentPosition(suc, locFail); +}; + +var beep = function() { + navigator.notification.beep(2); +}; + +var vibrate = function() { + navigator.notification.vibrate(0); +}; + +function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; +} + +var accelerationWatch = null; + +function updateAcceleration(a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); +} + +var toggleAccel = function() { + if (accelerationWatch !== null) { + navigator.accelerometer.clearWatch(accelerationWatch); + updateAcceleration({ + x : "", + y : "", + z : "" + }); + accelerationWatch = null; + } else { + var options = {}; + options.frequency = 1000; + accelerationWatch = navigator.accelerometer.watchAcceleration( + updateAcceleration, function(ex) { + alert("accel fail (" + ex.name + ": " + ex.message + ")"); + }, options); + } +}; + +var preventBehavior = function(e) { + e.preventDefault(); +}; + +function dump_pic(data) { + var viewport = document.getElementById('viewport'); + console.log(data); + viewport.style.display = ""; + viewport.style.position = "absolute"; + viewport.style.top = "10px"; + viewport.style.left = "10px"; + document.getElementById("test_img").src = "data:image/jpeg;base64," + data; +} + +function fail(msg) { + alert(msg); +} + +function show_pic() { + navigator.camera.getPicture(dump_pic, fail, { + quality : 50 + }); +} + +function close() { + var viewport = document.getElementById('viewport'); + viewport.style.position = "relative"; + viewport.style.display = "none"; +} + +// This is just to do this. +function readFile() { + navigator.file.read('/sdcard/cordova.txt', fail, fail); +} + +function writeFile() { + navigator.file.write('foo.txt', "This is a test of writing to a file", + fail, fail); +} + +function contacts_success(contacts) { + alert(contacts.length + + ' contacts returned.' + + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted) + : '')); +} + +function get_contacts() { + var obj = new ContactFindOptions(); + obj.filter = ""; + obj.multiple = true; + obj.limit = 5; + navigator.service.contacts.find( + [ "displayName", "name" ], contacts_success, + fail, obj); +} + +var networkReachableCallback = function(reachability) { + // There is no consistency on the format of reachability + var networkState = reachability.code || reachability; + + var currentState = {}; + currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection'; + currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection'; + currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection'; + + confirm("Connection type:\n" + currentState[networkState]); +}; + +function check_network() { + navigator.network.isReachable("www.mobiledevelopersolutions.com", + networkReachableCallback, {}); +} + +function init() { + // the next line makes it impossible to see Contacts on the HTC Evo since it + // doesn't have a scroll button + // document.addEventListener("touchmove", preventBehavior, false); + document.addEventListener("deviceready", deviceInfo, true); + document.getElementById("user-agent").textContent = navigator.userAgent; +} diff --git a/test/cordova/plugins/org.apache.cordova.device/test/master.css b/test/cordova/plugins/org.apache.cordova.device/test/master.css new file mode 100644 index 00000000..e93c9376 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/test/master.css @@ -0,0 +1,164 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + + body { + background:#222 none repeat scroll 0 0; + color:#666; + font-family:Helvetica; + font-size:72%; + line-height:1.5em; + margin:0; + border-top:1px solid #393939; + } + + #info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + min-width:295px; + max-width:97%; + padding:4px 0px 2px 10px; + word-wrap:break-word; + margin-bottom:10px; + display:inline-block; + min-height: 160px; + max-height: 300px; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + #info > h4{ + font-size:.95em; + margin:5px 0; + } + + #stage.theme{ + padding-top:3px; + } + + /* Definition List */ + #stage.theme > dl{ + padding-top:10px; + clear:both; + margin:0; + list-style-type:none; + padding-left:10px; + overflow:auto; + } + + #stage.theme > dl > dt{ + font-weight:bold; + float:left; + margin-left:5px; + } + + #stage.theme > dl > dd{ + width:45px; + float:left; + color:#a87; + font-weight:bold; + } + + /* Content Styling */ + #stage.theme > h1, #stage.theme > h2, #stage.theme > p{ + margin:1em 0 .5em 13px; + } + + #stage.theme > h1{ + color:#eee; + font-size:1.6em; + text-align:center; + margin:0; + margin-top:15px; + padding:0; + } + + #stage.theme > h2{ + clear:both; + margin:0; + padding:3px; + font-size:1em; + text-align:center; + } + + /* Stage Buttons */ + #stage.theme .btn{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:inline-block; + background:#444; + width:150px; + color:#9ab; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 0px 3px 5px; + } + + #stage.theme .large{ + width:308px; + padding:1.2em 0; + } + + #stage.theme .wide{ + width:100%; + padding:1.2em 0; + } + + #stage.theme .backBtn{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:block; + float:right; + background:#666; + width:75px; + color:#9ab; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 5px 3px 5px; + } + + #stage.theme .input{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:block; + float:light; + background:#888; + color:#9cd; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 0px 3px 5px; + } + + #stage.theme .numeric{ + width:100%; + } diff --git a/test/cordova/plugins/org.apache.cordova.device/www/device.js b/test/cordova/plugins/org.apache.cordova.device/www/device.js new file mode 100644 index 00000000..05f4c474 --- /dev/null +++ b/test/cordova/plugins/org.apache.cordova.device/www/device.js @@ -0,0 +1,77 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * +*/ + +var argscheck = require('cordova/argscheck'), + channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'), + cordova = require('cordova'); + +channel.createSticky('onCordovaInfoReady'); +// Tell cordova channel to wait on the CordovaInfoReady event +channel.waitForInitialization('onCordovaInfoReady'); + +/** + * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = false; + this.platform = null; + this.version = null; + this.uuid = null; + this.cordova = null; + this.model = null; + + var me = this; + + channel.onCordovaReady.subscribe(function() { + me.getInfo(function(info) { + //ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js + //TODO: CB-5105 native implementations should not return info.cordova + var buildLabel = cordova.version; + me.available = true; + me.platform = info.platform; + me.version = info.version; + me.uuid = info.uuid; + me.cordova = buildLabel; + me.model = info.model; + channel.onCordovaInfoReady.fire(); + },function(e) { + me.available = false; + utils.alert("[ERROR] Error initializing Cordova: " + e); + }); + }); +} + +/** + * Get device info + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) + */ +Device.prototype.getInfo = function(successCallback, errorCallback) { + argscheck.checkArgs('fF', 'Device.getInfo', arguments); + exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); +}; + +module.exports = new Device(); diff --git a/test/cordova/run b/test/cordova/run new file mode 100755 index 00000000..d4e2c6cb --- /dev/null +++ b/test/cordova/run @@ -0,0 +1,37 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +var run = require('./lib/run'), + reqs = require('./lib/check_reqs'), + args = process.argv; + +// Support basic help commands +if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' || + args[2] == 'help' || args[2] == '-help' || args[2] == '/help') { + run.help(); +} else { + reqs.run().done(function() { + return run.run(args); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +} diff --git a/test/cordova/run.bat b/test/cordova/run.bat new file mode 100644 index 00000000..0aad8535 --- /dev/null +++ b/test/cordova/run.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0run" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'run' script in 'cordova' folder, aborting...>&2 + EXIT /B 1 +) \ No newline at end of file diff --git a/test/cordova/version b/test/cordova/version new file mode 100755 index 00000000..6ce5f800 --- /dev/null +++ b/test/cordova/version @@ -0,0 +1,25 @@ +#!/usr/bin/env node + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ + +// Coho updates this line: +var VERSION = "3.2.0-rc1"; + +console.log(VERSION); diff --git a/test/cordova/version.bat b/test/cordova/version.bat new file mode 100644 index 00000000..d589002d --- /dev/null +++ b/test/cordova/version.bat @@ -0,0 +1,26 @@ +:: Licensed to the Apache Software Foundation (ASF) under one +:: or more contributor license agreements. See the NOTICE file +:: distributed with this work for additional information +:: regarding copyright ownership. The ASF licenses this file +:: to you 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. + +@ECHO OFF +SET script_path="%~dp0version" +IF EXIST %script_path% ( + node "%script_path%" %* +) ELSE ( + ECHO. + ECHO ERROR: Could not find 'version' script in 'cordova' folder, aborting...>&2 + EXIT /B 1 +) diff --git a/test/res/xml/config.xml b/test/res/xml/config.xml index 60a00cde..0d900838 100644 --- a/test/res/xml/config.xml +++ b/test/res/xml/config.xml @@ -1,52 +1,24 @@ - - - + + Hello Cordova - A sample Apache Cordova application that responds to the deviceready event. - - + Apache Cordova Team - - - - + - - - - + - - + + + + - - diff --git a/test/src/org/apache/cordova/device/Device.java b/test/src/org/apache/cordova/device/Device.java new file mode 100644 index 00000000..2ce3cc73 --- /dev/null +++ b/test/src/org/apache/cordova/device/Device.java @@ -0,0 +1,200 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +*/ +package org.apache.cordova.device; + +import java.util.TimeZone; + +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.LOG; +import org.apache.cordova.CordovaInterface; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.provider.Settings; +import android.telephony.TelephonyManager; + +public class Device extends CordovaPlugin { + public static final String TAG = "Device"; + + public static String cordovaVersion = "dev"; // Cordova version + public static String platform = "Android"; // Device OS + public static String uuid; // Device UUID + + BroadcastReceiver telephonyReceiver = null; + + /** + * Constructor. + */ + public Device() { + } + + /** + * Sets the context of the Command. This can then be used to do things like + * get file paths associated with the Activity. + * + * @param cordova The context of the main Activity. + * @param webView The CordovaWebView Cordova is running in. + */ + public void initialize(CordovaInterface cordova, CordovaWebView webView) { + super.initialize(cordova, webView); + Device.uuid = getUuid(); + this.initTelephonyReceiver(); + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackContext The callback id used when calling back into JavaScript. + * @return True if the action was valid, false if not. + */ + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + if (action.equals("getDeviceInfo")) { + JSONObject r = new JSONObject(); + r.put("uuid", Device.uuid); + r.put("version", this.getOSVersion()); + r.put("platform", Device.platform); + r.put("cordova", Device.cordovaVersion); + r.put("model", this.getModel()); + callbackContext.success(r); + } + else { + return false; + } + return true; + } + + /** + * Unregister receiver. + */ + public void onDestroy() { + this.cordova.getActivity().unregisterReceiver(this.telephonyReceiver); + } + + //-------------------------------------------------------------------------- + // LOCAL METHODS + //-------------------------------------------------------------------------- + + /** + * Listen for telephony events: RINGING, OFFHOOK and IDLE + * Send these events to all plugins using + * CordovaActivity.onMessage("telephone", "ringing" | "offhook" | "idle") + */ + private void initTelephonyReceiver() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + //final CordovaInterface mycordova = this.cordova; + this.telephonyReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + + // If state has changed + if ((intent != null) && intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { + if (intent.hasExtra(TelephonyManager.EXTRA_STATE)) { + String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE); + if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) { + LOG.i(TAG, "Telephone RINGING"); + webView.postMessage("telephone", "ringing"); + } + else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { + LOG.i(TAG, "Telephone OFFHOOK"); + webView.postMessage("telephone", "offhook"); + } + else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) { + LOG.i(TAG, "Telephone IDLE"); + webView.postMessage("telephone", "idle"); + } + } + } + } + }; + + // Register the receiver + this.cordova.getActivity().registerReceiver(this.telephonyReceiver, intentFilter); + } + + /** + * Get the OS name. + * + * @return + */ + public String getPlatform() { + return Device.platform; + } + + /** + * Get the device's Universally Unique Identifier (UUID). + * + * @return + */ + public String getUuid() { + String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); + return uuid; + } + + /** + * Get the Cordova version. + * + * @return + */ + public String getCordovaVersion() { + return Device.cordovaVersion; + } + + public String getModel() { + String model = android.os.Build.MODEL; + return model; + } + + public String getProductName() { + String productname = android.os.Build.PRODUCT; + return productname; + } + + /** + * Get the OS version. + * + * @return + */ + public String getOSVersion() { + String osversion = android.os.Build.VERSION.RELEASE; + return osversion; + } + + public String getSDKVersion() { + @SuppressWarnings("deprecation") + String sdkversion = android.os.Build.VERSION.SDK; + return sdkversion; + } + + public String getTimeZoneID() { + TimeZone tz = TimeZone.getDefault(); + return (tz.getID()); + } + +} diff --git a/test/src/org/apache/cordova/test/actions/CordovaActivity.java b/test/src/org/apache/cordova/test/CordovaActivity.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/CordovaActivity.java rename to test/src/org/apache/cordova/test/CordovaActivity.java index f7097371..f3a7839c 100644 --- a/test/src/org/apache/cordova/test/actions/CordovaActivity.java +++ b/test/src/org/apache/cordova/test/CordovaActivity.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import org.apache.cordova.DroidGap; diff --git a/test/src/org/apache/cordova/test/actions/CordovaDriverAction.java b/test/src/org/apache/cordova/test/CordovaDriverAction.java similarity index 98% rename from test/src/org/apache/cordova/test/actions/CordovaDriverAction.java rename to test/src/org/apache/cordova/test/CordovaDriverAction.java index 2e5d7409..0559f5fd 100644 --- a/test/src/org/apache/cordova/test/actions/CordovaDriverAction.java +++ b/test/src/org/apache/cordova/test/CordovaDriverAction.java @@ -17,7 +17,7 @@ under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import java.util.concurrent.ExecutorService; diff --git a/test/src/org/apache/cordova/test/actions/CordovaWebViewTestActivity.java b/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java similarity index 98% rename from test/src/org/apache/cordova/test/actions/CordovaWebViewTestActivity.java rename to test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java index 02d4b8db..7ac2c3c9 100644 --- a/test/src/org/apache/cordova/test/actions/CordovaWebViewTestActivity.java +++ b/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java @@ -17,7 +17,7 @@ under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/test/src/org/apache/cordova/test/actions/backbuttonmultipage.java b/test/src/org/apache/cordova/test/backbuttonmultipage.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/backbuttonmultipage.java rename to test/src/org/apache/cordova/test/backbuttonmultipage.java index 4929831c..149501c3 100755 --- a/test/src/org/apache/cordova/test/actions/backbuttonmultipage.java +++ b/test/src/org/apache/cordova/test/backbuttonmultipage.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/background.java b/test/src/org/apache/cordova/test/background.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/background.java rename to test/src/org/apache/cordova/test/background.java index 47c6bc79..7a0ba89b 100755 --- a/test/src/org/apache/cordova/test/actions/background.java +++ b/test/src/org/apache/cordova/test/background.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; diff --git a/test/src/org/apache/cordova/test/actions/backgroundcolor.java b/test/src/org/apache/cordova/test/backgroundcolor.java similarity index 97% rename from test/src/org/apache/cordova/test/actions/backgroundcolor.java rename to test/src/org/apache/cordova/test/backgroundcolor.java index d5018246..f40a6732 100755 --- a/test/src/org/apache/cordova/test/actions/backgroundcolor.java +++ b/test/src/org/apache/cordova/test/backgroundcolor.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.graphics.Color; import android.os.Bundle; diff --git a/test/src/org/apache/cordova/test/actions/basicauth.java b/test/src/org/apache/cordova/test/basicauth.java similarity index 97% rename from test/src/org/apache/cordova/test/actions/basicauth.java rename to test/src/org/apache/cordova/test/basicauth.java index ad739c9e..1b09f3d5 100755 --- a/test/src/org/apache/cordova/test/actions/basicauth.java +++ b/test/src/org/apache/cordova/test/basicauth.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/errorurl.java b/test/src/org/apache/cordova/test/errorurl.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/errorurl.java rename to test/src/org/apache/cordova/test/errorurl.java index 10c20f7f..48e6ada0 100755 --- a/test/src/org/apache/cordova/test/actions/errorurl.java +++ b/test/src/org/apache/cordova/test/errorurl.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/fullscreen.java b/test/src/org/apache/cordova/test/fullscreen.java similarity index 97% rename from test/src/org/apache/cordova/test/actions/fullscreen.java rename to test/src/org/apache/cordova/test/fullscreen.java index 60726ad2..7fcd79b9 100755 --- a/test/src/org/apache/cordova/test/actions/fullscreen.java +++ b/test/src/org/apache/cordova/test/fullscreen.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/htmlnotfound.java b/test/src/org/apache/cordova/test/htmlnotfound.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/htmlnotfound.java rename to test/src/org/apache/cordova/test/htmlnotfound.java index da849e03..4551ca36 100755 --- a/test/src/org/apache/cordova/test/actions/htmlnotfound.java +++ b/test/src/org/apache/cordova/test/htmlnotfound.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/iframe.java b/test/src/org/apache/cordova/test/iframe.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/iframe.java rename to test/src/org/apache/cordova/test/iframe.java index 3398aa45..de854fc2 100755 --- a/test/src/org/apache/cordova/test/actions/iframe.java +++ b/test/src/org/apache/cordova/test/iframe.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/BackButtonMultiPageTest.java b/test/src/org/apache/cordova/test/junit/BackButtonMultiPageTest.java similarity index 98% rename from test/src/org/apache/cordova/test/BackButtonMultiPageTest.java rename to test/src/org/apache/cordova/test/junit/BackButtonMultiPageTest.java index 6d4a7ac8..07e35374 100644 --- a/test/src/org/apache/cordova/test/BackButtonMultiPageTest.java +++ b/test/src/org/apache/cordova/test/junit/BackButtonMultiPageTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; -import org.apache.cordova.test.actions.backbuttonmultipage; +import org.apache.cordova.test.backbuttonmultipage; import android.test.ActivityInstrumentationTestCase2; import android.view.KeyEvent; diff --git a/test/src/org/apache/cordova/test/CordovaActivityTest.java b/test/src/org/apache/cordova/test/junit/CordovaActivityTest.java similarity index 97% rename from test/src/org/apache/cordova/test/CordovaActivityTest.java rename to test/src/org/apache/cordova/test/junit/CordovaActivityTest.java index a100f0a0..4fc42dbd 100644 --- a/test/src/org/apache/cordova/test/CordovaActivityTest.java +++ b/test/src/org/apache/cordova/test/junit/CordovaActivityTest.java @@ -17,11 +17,11 @@ under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; import org.apache.cordova.CordovaWebView; import org.apache.cordova.PluginManager; -import org.apache.cordova.test.actions.CordovaActivity; +import org.apache.cordova.test.CordovaActivity; import android.app.Instrumentation; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/CordovaResourceApiTest.java b/test/src/org/apache/cordova/test/junit/CordovaResourceApiTest.java similarity index 98% rename from test/src/org/apache/cordova/test/CordovaResourceApiTest.java rename to test/src/org/apache/cordova/test/junit/CordovaResourceApiTest.java index 5aad9128..1c919220 100644 --- a/test/src/org/apache/cordova/test/CordovaResourceApiTest.java +++ b/test/src/org/apache/cordova/test/junit/CordovaResourceApiTest.java @@ -1,5 +1,5 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * @@ -35,7 +35,8 @@ import org.apache.cordova.CordovaResourceApi; import org.apache.cordova.CordovaResourceApi.OpenForReadResult; import org.apache.cordova.CordovaWebView; import org.apache.cordova.PluginEntry; -import org.apache.cordova.test.actions.CordovaWebViewTestActivity; +import org.apache.cordova.test.CordovaWebViewTestActivity; +import org.apache.cordova.test.R; import org.json.JSONArray; import org.json.JSONException; diff --git a/test/src/org/apache/cordova/test/CordovaTest.java b/test/src/org/apache/cordova/test/junit/CordovaTest.java similarity index 96% rename from test/src/org/apache/cordova/test/CordovaTest.java rename to test/src/org/apache/cordova/test/junit/CordovaTest.java index 0e11b684..02f4ee60 100644 --- a/test/src/org/apache/cordova/test/CordovaTest.java +++ b/test/src/org/apache/cordova/test/junit/CordovaTest.java @@ -16,11 +16,12 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; import org.apache.cordova.CordovaWebView; import org.apache.cordova.PluginManager; -import org.apache.cordova.test.actions.CordovaWebViewTestActivity; +import org.apache.cordova.test.CordovaWebViewTestActivity; +import org.apache.cordova.test.R; import android.app.Instrumentation; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/ErrorUrlTest.java b/test/src/org/apache/cordova/test/junit/ErrorUrlTest.java similarity index 96% rename from test/src/org/apache/cordova/test/ErrorUrlTest.java rename to test/src/org/apache/cordova/test/junit/ErrorUrlTest.java index 5a7eb9c8..2ef78579 100644 --- a/test/src/org/apache/cordova/test/ErrorUrlTest.java +++ b/test/src/org/apache/cordova/test/junit/ErrorUrlTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; -import org.apache.cordova.test.actions.errorurl; +import org.apache.cordova.test.errorurl; import android.test.ActivityInstrumentationTestCase2; import android.widget.FrameLayout; diff --git a/test/src/org/apache/cordova/test/FixWebView.java b/test/src/org/apache/cordova/test/junit/FixWebView.java similarity index 97% rename from test/src/org/apache/cordova/test/FixWebView.java rename to test/src/org/apache/cordova/test/junit/FixWebView.java index 46f155bf..3b73e29e 100755 --- a/test/src/org/apache/cordova/test/FixWebView.java +++ b/test/src/org/apache/cordova/test/junit/FixWebView.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; import android.content.Context; import android.webkit.WebView; diff --git a/test/src/org/apache/cordova/test/GapClientTest.java b/test/src/org/apache/cordova/test/junit/GapClientTest.java similarity index 95% rename from test/src/org/apache/cordova/test/GapClientTest.java rename to test/src/org/apache/cordova/test/junit/GapClientTest.java index a3c2a624..4540d92a 100644 --- a/test/src/org/apache/cordova/test/GapClientTest.java +++ b/test/src/org/apache/cordova/test/junit/GapClientTest.java @@ -17,12 +17,12 @@ under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaChromeClient; import org.apache.cordova.PluginManager; -import org.apache.cordova.test.actions.CordovaWebViewTestActivity; +import org.apache.cordova.test.CordovaWebViewTestActivity; import android.content.Context; import android.content.res.AssetManager; diff --git a/test/src/org/apache/cordova/test/HtmlNotFoundTest.java b/test/src/org/apache/cordova/test/junit/HtmlNotFoundTest.java similarity index 96% rename from test/src/org/apache/cordova/test/HtmlNotFoundTest.java rename to test/src/org/apache/cordova/test/junit/HtmlNotFoundTest.java index e47d5b8f..93f9cdb2 100644 --- a/test/src/org/apache/cordova/test/HtmlNotFoundTest.java +++ b/test/src/org/apache/cordova/test/junit/HtmlNotFoundTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; -import org.apache.cordova.test.actions.htmlnotfound; +import org.apache.cordova.test.htmlnotfound; import android.test.ActivityInstrumentationTestCase2; import android.widget.FrameLayout; diff --git a/test/src/org/apache/cordova/test/IFrameTest.java b/test/src/org/apache/cordova/test/junit/IFrameTest.java similarity index 97% rename from test/src/org/apache/cordova/test/IFrameTest.java rename to test/src/org/apache/cordova/test/junit/IFrameTest.java index 7cb87987..a272e90b 100644 --- a/test/src/org/apache/cordova/test/IFrameTest.java +++ b/test/src/org/apache/cordova/test/junit/IFrameTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -22,8 +22,8 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; +import org.apache.cordova.test.iframe; import org.apache.cordova.test.util.Purity; -import org.apache.cordova.test.actions.iframe; import android.app.Activity; import android.app.Instrumentation; diff --git a/test/src/org/apache/cordova/test/LifecycleTest.java b/test/src/org/apache/cordova/test/junit/LifecycleTest.java similarity index 92% rename from test/src/org/apache/cordova/test/LifecycleTest.java rename to test/src/org/apache/cordova/test/junit/LifecycleTest.java index 396036d7..54235757 100644 --- a/test/src/org/apache/cordova/test/LifecycleTest.java +++ b/test/src/org/apache/cordova/test/junit/LifecycleTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -21,7 +21,7 @@ package org.apache.cordova.test; */ -import org.apache.cordova.test.actions.lifecycle; +import org.apache.cordova.test.lifecycle; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/MenuTest.java b/test/src/org/apache/cordova/test/junit/MenuTest.java similarity index 93% rename from test/src/org/apache/cordova/test/MenuTest.java rename to test/src/org/apache/cordova/test/junit/MenuTest.java index 1486ccab..6c1ace6d 100644 --- a/test/src/org/apache/cordova/test/MenuTest.java +++ b/test/src/org/apache/cordova/test/junit/MenuTest.java @@ -17,9 +17,9 @@ under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; -import org.apache.cordova.test.actions.menus; +import org.apache.cordova.test.menus; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/PluginManagerTest.java b/test/src/org/apache/cordova/test/junit/PluginManagerTest.java similarity index 95% rename from test/src/org/apache/cordova/test/PluginManagerTest.java rename to test/src/org/apache/cordova/test/junit/PluginManagerTest.java index c767e7d7..bcdead69 100644 --- a/test/src/org/apache/cordova/test/PluginManagerTest.java +++ b/test/src/org/apache/cordova/test/junit/PluginManagerTest.java @@ -17,11 +17,11 @@ under the License. */ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; import org.apache.cordova.CordovaWebView; import org.apache.cordova.PluginManager; -import org.apache.cordova.test.actions.CordovaWebViewTestActivity; +import org.apache.cordova.test.CordovaWebViewTestActivity; import android.test.ActivityInstrumentationTestCase2; import android.view.View; diff --git a/test/src/org/apache/cordova/test/SplashscreenTest.java b/test/src/org/apache/cordova/test/junit/SplashscreenTest.java similarity index 94% rename from test/src/org/apache/cordova/test/SplashscreenTest.java rename to test/src/org/apache/cordova/test/junit/SplashscreenTest.java index edb87584..14da5acd 100644 --- a/test/src/org/apache/cordova/test/SplashscreenTest.java +++ b/test/src/org/apache/cordova/test/junit/SplashscreenTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; -import org.apache.cordova.test.actions.splashscreen; +import org.apache.cordova.test.splashscreen; import android.app.Dialog; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/UserWebViewTest.java b/test/src/org/apache/cordova/test/junit/UserWebViewTest.java similarity index 96% rename from test/src/org/apache/cordova/test/UserWebViewTest.java rename to test/src/org/apache/cordova/test/junit/UserWebViewTest.java index e7a240a0..62dcbe07 100644 --- a/test/src/org/apache/cordova/test/UserWebViewTest.java +++ b/test/src/org/apache/cordova/test/junit/UserWebViewTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -24,7 +24,7 @@ package org.apache.cordova.test; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaWebViewClient; import org.apache.cordova.CordovaChromeClient; -import org.apache.cordova.test.actions.userwebview; +import org.apache.cordova.test.userwebview; import android.test.ActivityInstrumentationTestCase2; import android.widget.FrameLayout; diff --git a/test/src/org/apache/cordova/test/XhrTest.java b/test/src/org/apache/cordova/test/junit/XhrTest.java similarity index 92% rename from test/src/org/apache/cordova/test/XhrTest.java rename to test/src/org/apache/cordova/test/junit/XhrTest.java index 7c3ed9ff..16c977f2 100644 --- a/test/src/org/apache/cordova/test/XhrTest.java +++ b/test/src/org/apache/cordova/test/junit/XhrTest.java @@ -1,4 +1,4 @@ -package org.apache.cordova.test; +package org.apache.cordova.test.junit; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -21,7 +21,7 @@ package org.apache.cordova.test; */ -import org.apache.cordova.test.actions.xhr; +import org.apache.cordova.test.xhr; import android.test.ActivityInstrumentationTestCase2; diff --git a/test/src/org/apache/cordova/test/actions/lifecycle.java b/test/src/org/apache/cordova/test/lifecycle.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/lifecycle.java rename to test/src/org/apache/cordova/test/lifecycle.java index 8419b0e5..30c5b8ba 100755 --- a/test/src/org/apache/cordova/test/actions/lifecycle.java +++ b/test/src/org/apache/cordova/test/lifecycle.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/loading.java b/test/src/org/apache/cordova/test/loading.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/loading.java rename to test/src/org/apache/cordova/test/loading.java index 4c52c9f2..b1b08aea 100755 --- a/test/src/org/apache/cordova/test/actions/loading.java +++ b/test/src/org/apache/cordova/test/loading.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/menus.java b/test/src/org/apache/cordova/test/menus.java similarity index 98% rename from test/src/org/apache/cordova/test/actions/menus.java rename to test/src/org/apache/cordova/test/menus.java index c4cb6745..12d5230f 100755 --- a/test/src/org/apache/cordova/test/actions/menus.java +++ b/test/src/org/apache/cordova/test/menus.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import android.view.ContextMenu; diff --git a/test/src/org/apache/cordova/test/actions/splashscreen.java b/test/src/org/apache/cordova/test/splashscreen.java similarity index 97% rename from test/src/org/apache/cordova/test/actions/splashscreen.java rename to test/src/org/apache/cordova/test/splashscreen.java index 3d924e07..ef49d736 100755 --- a/test/src/org/apache/cordova/test/actions/splashscreen.java +++ b/test/src/org/apache/cordova/test/splashscreen.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/tests.java b/test/src/org/apache/cordova/test/tests.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/tests.java rename to test/src/org/apache/cordova/test/tests.java index bc326e30..80c7f24a 100755 --- a/test/src/org/apache/cordova/test/actions/tests.java +++ b/test/src/org/apache/cordova/test/tests.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/timeout.java b/test/src/org/apache/cordova/test/timeout.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/timeout.java rename to test/src/org/apache/cordova/test/timeout.java index 22c0881a..31edb8d5 100755 --- a/test/src/org/apache/cordova/test/actions/timeout.java +++ b/test/src/org/apache/cordova/test/timeout.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*; diff --git a/test/src/org/apache/cordova/test/actions/userwebview.java b/test/src/org/apache/cordova/test/userwebview.java similarity index 98% rename from test/src/org/apache/cordova/test/actions/userwebview.java rename to test/src/org/apache/cordova/test/userwebview.java index 305a2e9a..6146a40a 100755 --- a/test/src/org/apache/cordova/test/actions/userwebview.java +++ b/test/src/org/apache/cordova/test/userwebview.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import android.webkit.WebView; diff --git a/test/src/org/apache/cordova/test/actions/whitelist.java b/test/src/org/apache/cordova/test/whitelist.java similarity index 97% rename from test/src/org/apache/cordova/test/actions/whitelist.java rename to test/src/org/apache/cordova/test/whitelist.java index 7d5a51aa..26eebf32 100755 --- a/test/src/org/apache/cordova/test/actions/whitelist.java +++ b/test/src/org/apache/cordova/test/whitelist.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import android.webkit.WebView; diff --git a/test/src/org/apache/cordova/test/actions/xhr.java b/test/src/org/apache/cordova/test/xhr.java similarity index 96% rename from test/src/org/apache/cordova/test/actions/xhr.java rename to test/src/org/apache/cordova/test/xhr.java index 3695c113..402e0ad2 100755 --- a/test/src/org/apache/cordova/test/actions/xhr.java +++ b/test/src/org/apache/cordova/test/xhr.java @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -package org.apache.cordova.test.actions; +package org.apache.cordova.test; import android.os.Bundle; import org.apache.cordova.*;