You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2014/08/13 01:54:04 UTC
[3/4] git commit: CB-6963 renamed folder to tests + added nested
plugin.xml
CB-6963 renamed folder to tests + added nested plugin.xml
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/commit/658d86b1
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/tree/658d86b1
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/diff/658d86b1
Branch: refs/heads/master
Commit: 658d86b1b3c8f1d9a38e5b7dc5057875e5d203de
Parents: 3317891
Author: Martin Gonzalez <ma...@gmail.com>
Authored: Fri Aug 1 01:06:10 2014 -0500
Committer: Martin Gonzalez <ma...@gmail.com>
Committed: Fri Aug 1 01:06:10 2014 -0500
----------------------------------------------------------------------
test/tests.js | 764 --------------------------------------------------
tests/plugin.xml | 30 ++
tests/tests.js | 764 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 794 insertions(+), 764 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/658d86b1/test/tests.js
----------------------------------------------------------------------
diff --git a/test/tests.js b/test/tests.js
deleted file mode 100644
index cba8007..0000000
--- a/test/tests.js
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-exports.defineAutoTests = function () {
- var failed = function (done, msg, error) {
- var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg;
- expect(true).toFailWithMessage(info + '\n' + JSON.stringify(error));
- done();
- };
-
- var succeed = function (done, msg) {
- var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg;
- expect(true).toFailWithMessage(info);
- done();
- };
-
- describe('Media', function () {
-
- beforeEach(function () {
- // Custom Matcher
- jasmine.Expectation.addMatchers({
- toFailWithMessage : function () {
- return {
- compare : function (error, message) {
- var pass = false;
- return {
- pass : pass,
- message : message
- };
- }
- };
- }
- });
- });
-
- it("media.spec.1 should exist", function () {
- expect(Media).toBeDefined();
- expect(typeof Media).toBe("function");
- });
-
- it("media.spec.2 should have the following properties", function () {
- var media1 = new Media("dummy");
- expect(media1.id).toBeDefined();
- expect(media1.src).toBeDefined();
- expect(media1._duration).toBeDefined();
- expect(media1._position).toBeDefined();
- media1.release();
- });
-
- it("media.spec.3 should define constants for Media status", function () {
- expect(Media).toBeDefined();
- expect(Media.MEDIA_NONE).toBe(0);
- expect(Media.MEDIA_STARTING).toBe(1);
- expect(Media.MEDIA_RUNNING).toBe(2);
- expect(Media.MEDIA_PAUSED).toBe(3);
- expect(Media.MEDIA_STOPPED).toBe(4);
- });
-
- it("media.spec.4 should define constants for Media errors", function () {
- expect(MediaError).toBeDefined();
- expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
- expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
- expect(MediaError.MEDIA_ERR_NETWORK).toBe(2);
- expect(MediaError.MEDIA_ERR_DECODE).toBe(3);
- expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
- });
-
- it("media.spec.5 should contain a play function", function () {
- var media1 = new Media();
- expect(media1.play).toBeDefined();
- expect(typeof media1.play).toBe('function');
- media1.release();
- });
-
- it("media.spec.6 should contain a stop function", function () {
- var media1 = new Media();
- expect(media1.stop).toBeDefined();
- expect(typeof media1.stop).toBe('function');
- media1.release();
- });
-
- it("media.spec.7 should contain a seekTo function", function () {
- var media1 = new Media();
- expect(media1.seekTo).toBeDefined();
- expect(typeof media1.seekTo).toBe('function');
- media1.release();
- });
-
- it("media.spec.8 should contain a pause function", function () {
- var media1 = new Media();
- expect(media1.pause).toBeDefined();
- expect(typeof media1.pause).toBe('function');
- media1.release();
- });
-
- it("media.spec.9 should contain a getDuration function", function () {
- var media1 = new Media();
- expect(media1.getDuration).toBeDefined();
- expect(typeof media1.getDuration).toBe('function');
- media1.release();
- });
-
- it("media.spec.10 should contain a getCurrentPosition function", function () {
- var media1 = new Media();
- expect(media1.getCurrentPosition).toBeDefined();
- expect(typeof media1.getCurrentPosition).toBe('function');
- media1.release();
- });
-
- it("media.spec.11 should contain a startRecord function", function () {
- var media1 = new Media();
- expect(media1.startRecord).toBeDefined();
- expect(typeof media1.startRecord).toBe('function');
- media1.release();
- });
-
- it("media.spec.12 should contain a stopRecord function", function () {
- var media1 = new Media();
- expect(media1.stopRecord).toBeDefined();
- expect(typeof media1.stopRecord).toBe('function');
- media1.release();
- });
-
- it("media.spec.13 should contain a release function", function () {
- var media1 = new Media();
- expect(media1.release).toBeDefined();
- expect(typeof media1.release).toBe('function');
- media1.release();
- });
-
- it("media.spec.14 should contain a setVolume function", function () {
- var media1 = new Media();
- expect(media1.setVolume).toBeDefined();
- expect(typeof media1.setVolume).toBe('function');
- media1.release();
- });
-
- it("media.spec.15 should return MediaError for bad filename", function (done) {
- var fileName = 'invalid.file.name';
- //Error callback it has an unexpected behavior under Windows Phone,
- //it enters to the error callback several times, instead of just one walk-through
- //JIRA issue related with all details: CB-7092
- //the conditional statement should be removed once the issue is fixed.
-
- //bb10 dialog pops up, preventing tests from running
- if (cordova.platformId === 'blackberry10' || cordova.platformId === 'windowsphone') {
- expect(true).toFailWithMessage('Platform does not support this feature');
- done();
- } else {
- var badMedia = null;
- badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) {
- expect(result).toBeDefined();
- expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED);
- badMedia.release();
- done();
- });
- badMedia.play();
- }
- });
-
- it("media.spec.16 position should be set properly", function (done) {
- var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3',
- mediaState = Media.MEDIA_STOPPED,
- successCallback,
- flag = true,
- statusChange = function (statusCode) {
- if (statusCode == Media.MEDIA_RUNNING && flag) {
- //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
- //in case for some reason the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behavior it can be found at JIRA: CB-7099
- flag = false;
- setTimeout(function () {
- media1.getCurrentPosition(function (position) {
- expect(position).toBeGreaterThan(0.0);
- media1.stop();
- media1.release();
- done();
- }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'));
- }, 1000);
- }
- };
- media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange);
- media1.play();
- });
-
- it("media.spec.17 duration should be set properly", function (done) {
- if (cordova.platformId === 'blackberry10') {
- expect(true).toFailWithMessage('Platform does not supported this feature');
- done();
- }
- var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3',
- mediaState = Media.MEDIA_STOPPED,
- successCallback,
- flag = true,
- statusChange = function (statusCode) {
- if (statusCode == Media.MEDIA_RUNNING && flag) {
- //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
- //in case for some reason the statusChange callback is reached more than one time with the same status code.
- //Some information about this kind of behavior it can be found at JIRA: CB-7099.
- flag = false;
- setTimeout(function () {
- expect(media1.getDuration()).toBeGreaterThan(0.0);
- media1.stop();
- media1.release();
- done();
- }, 1000);
- }
- },
- media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange);
- media1.play();
- });
- });
-};
-
-//******************************************************************************************
-//***************************************Manual Tests***************************************
-//******************************************************************************************
-
-exports.defineManualTests = function (contentEl, createActionButton) {
- //-------------------------------------------------------------------------
- // Audio player
- //-------------------------------------------------------------------------
- var media1 = null;
- var media1Timer = null;
- var audioSrc = null;
- var defaultaudio = "http://cordova.apache.org/downloads/BlueZedEx.mp3";
-
- //Play audio function
- function playAudio(url) {
- console.log("playAudio()");
- console.log(" -- media=" + media1);
-
- var src = defaultaudio;
-
- if (url) {
- src = url;
- }
-
- // Stop playing if src is different from currently playing source
- if (src !== audioSrc) {
- if (media1 !== null) {
- stopAudio();
- media1 = null;
- }
- }
-
- if (media1 === null) {
-
- // TEST STREAMING AUDIO PLAYBACK
- //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3"; // works
- //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
- //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
- //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
- //var src = "MusicSearch/mp3/train.mp3"; // works
- //var src = "bryce.mp3"; // works
- //var src = "/android_asset/www/bryce.mp3"; // works
-
- media1 = new Media(src,
- function () {
- console.log("playAudio():Audio Success");
- },
- function (err) {
- console.log("playAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
- },
- function (status) {
- console.log("playAudio():Audio Status: " + status);
- setAudioStatus(Media.MEDIA_MSG[status]);
-
- // If stopped, then stop getting current position
- if (Media.MEDIA_STOPPED == status) {
- clearInterval(media1Timer);
- media1Timer = null;
- setAudioPosition("0 sec");
- }
- });
- }
- audioSrc = src;
- document.getElementById('durationValue').innerHTML = "";
- // Play audio
- media1.play();
- if (media1Timer === null && media1.getCurrentPosition) {
- media1Timer = setInterval(
- function () {
- media1.getCurrentPosition(
- function (position) {
- if (position >= 0.0) {
- setAudioPosition(position + " sec");
- }
- },
- function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
- },
- 1000);
- }
-
- // Get duration
- var counter = 0;
- var timerDur = setInterval(
- function () {
- counter = counter + 100;
- if (counter > 2000) {
- clearInterval(timerDur);
- }
- var dur = media1.getDuration();
- if (dur > 0) {
- clearInterval(timerDur);
- document.getElementById('durationValue').innerHTML = dur + " sec";
- }
- }, 100);
- }
-
- //Pause audio playback
- function pauseAudio() {
- console.log("pauseAudio()");
- if (media1) {
- media1.pause();
- }
- }
-
- //Stop audio
- function stopAudio() {
- console.log("stopAudio()");
- if (media1) {
- media1.stop();
- }
- clearInterval(media1Timer);
- media1Timer = null;
- }
-
- //Release audio
- function releaseAudio() {
- console.log("releaseAudio()");
- if (media1) {
- media1.stop(); //imlied stop of playback, resets timer
- media1.release();
- }
- }
-
- //Set audio status
- function setAudioStatus(status) {
- document.getElementById('statusValue').innerHTML = status;
- }
-
- //Set audio position
- function setAudioPosition(position) {
- document.getElementById('positionValue').innerHTML = position;
- }
-
- //Seek audio
- function seekAudio(mode) {
- var time = document.getElementById("seekInput").value;
- if (time === "") {
- time = 5000;
- } else {
- time = time * 1000; //we expect the input to be in seconds
- }
- if (media1 === null) {
- console.log("seekTo requested while media1 is null");
- if (audioSrc === null) {
- audioSrc = defaultaudio;
- }
- media1 = new Media(audioSrc,
- function () {
- console.log("seekToAudio():Audio Success");
- },
- function (err) {
- console.log("seekAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
- },
- function (status) {
- console.log("seekAudio():Audio Status: " + status);
- setAudioStatus(Media.MEDIA_MSG[status]);
-
- // If stopped, then stop getting current position
- if (Media.MEDIA_STOPPED == status) {
- clearInterval(media1Timer);
- media1Timer = null;
- setAudioPosition("0 sec");
- }
- });
- }
-
- media1.getCurrentPosition(
- function (position) {
- var deltat = time;
- if (mode === "by") {
- deltat = time + position * 1000;
- }
- media1.seekTo(deltat,
- function () {
- console.log("seekAudioTo():Audio Success");
- //force an update on the position display
- updatePosition();
- },
- function (err) {
- console.log("seekAudioTo():Audio Error: " + err.code);
- });
- },
- function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
- }
-
- //for forced updates of position after a successful seek
-
- function updatePosition() {
- media1.getCurrentPosition(
- function (position) {
- if (position >= 0.0) {
- setAudioPosition(position + " sec");
- }
- },
- function (e) {
- console.log("Error getting pos=" + e);
- setAudioPosition("Error: " + e);
- });
- }
-
- //-------------------------------------------------------------------------
- // Audio recorder
- //-------------------------------------------------------------------------
- var mediaRec = null;
- var recTime = 0;
- var recordSrc = "myRecording.mp3";
-
- //Record audio
- function recordAudio() {
- console.log("recordAudio()");
- console.log(" -- media=" + mediaRec);
- if (mediaRec == null) {
- var src = recordSrc;
- mediaRec = new Media(src,
- function () {
- console.log("recordAudio():Audio Success");
- },
- function (err) {
- console.log("recordAudio():Audio Error: " + err.code);
- setAudioStatus("Error: " + err.code);
- },
- function (status) {
- console.log("recordAudio():Audio Status: " + status);
- setAudioStatus(Media.MEDIA_MSG[status]);
- });
- }
-
- // Record audio
- mediaRec.startRecord();
-
- // Stop recording after 10 sec
- recTime = 0;
- var recInterval = setInterval(function () {
- recTime = recTime + 1;
- setAudioPosition(recTime + " sec");
- if (recTime >= 10) {
- clearInterval(recInterval);
- if (mediaRec.stopAudioRecord) {
- mediaRec.stopAudioRecord();
- } else {
- mediaRec.stopRecord();
- }
- console.log("recordAudio(): stop");
- }
- }, 1000);
- }
-
- //Play back recorded audio
- function playRecording() {
- playAudio(recordSrc);
- }
-
- //Function to create a file for iOS recording
-
- function getRecordSrc() {
- var fsFail = function (error) {
- console.log("error creating file for iOS recording");
- };
- var gotFile = function (file) {
- recordSrc = file.fullPath;
- //console.log("recording Src: " + recordSrc);
- };
- var gotFS = function (fileSystem) {
- fileSystem.root.getFile("iOSRecording.wav", {
- create : true
- }, gotFile, fsFail);
- };
- window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
- }
-
- //Function to create a file for BB recording
- function getRecordSrcBB() {
- var fsFail = function (error) {
- console.log("error creating file for BB recording");
- };
- var gotFile = function (file) {
- recordSrc = file.fullPath;
- };
- var gotFS = function (fileSystem) {
- fileSystem.root.getFile("BBRecording.amr", {
- create : true
- }, gotFile, fsFail);
- };
- window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
- }
-
-//Generate Dynamic Table
- function generateTable(tableId, rows, cells, elements) {
- var table = document.createElement('table');
- for (var r = 0; r < rows; r++) {
- var row = table.insertRow(r);
- for (var c = 0; c < cells; c++) {
- var cell = row.insertCell(c);
- cell.setAttribute("align", "center");
- for (var e in elements) {
- if (elements[e].position.row == r && elements[e].position.cell == c) {
- var htmlElement = document.createElement(elements[e].tag);
- var content;
-
- if (elements[e].content !== "") {
- content = document.createTextNode(elements[e].content);
- htmlElement.appendChild(content);
- }
- if (elements[e].type) {
- htmlElement.type = elements[e].type;
- }
- htmlElement.setAttribute("id", elements[e].id);
- cell.appendChild(htmlElement);
- }
- }
- }
- }
- table.setAttribute("align", "center");
- table.setAttribute("id", tableId);
- return table;
- }
-
-//Audio && Record Elements
- var elementsResultsAudio=
- [{
- id : "statusTag",
- content : "Status:",
- tag : "div",
- position : {
- row : 0,
- cell : 0
- }
- }, {
- id : "statusValue",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 2
- }
- }, {
- id : "durationTag",
- content : "Duration:",
- tag : "div",
- position : {
- row : 1,
- cell : 0
- }
- }, {
- id : "durationValue",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 2
- }
- }, {
- id : "positionTag",
- content : "Position:",
- tag : "div",
- position : {
- row : 2,
- cell : 0
- }
- }, {
- id : "positionValue",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 2
- }
- }],
- elementsAudio =
- [{
- id : "playBtn",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 0
- }
- }, {
- id : "pauseBtn",
- content : "",
- tag : "div",
- position : {
- row : 0,
- cell : 1
- }
- }, {
- id : "stopBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 0
- }
- }, {
- id : "releaseBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 1
- }
- }, {
- id : "seekByBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 0
- }
- }, {
- id : "seekToBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 1
- }
- }, {
- id : "seekInput",
- content : "",
- tag : "input",
- type : "number",
- position : {
- row : 2,
- cell : 2
- }
- }
- ],
- elementsRecord =
- [{
- id : "recordbtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 0
- }
- }, {
- id : "recordplayBtn",
- content : "",
- tag : "div",
- position : {
- row : 1,
- cell : 1
- }
- }, {
- id : "recordpauseBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 0
- }
- }, {
- id : "recordstopBtn",
- content : "",
- tag : "div",
- position : {
- row : 2,
- cell : 1
- }
- }
- ];
-
- //Title audio results
- var div = document.createElement('h2');
- div.appendChild(document.createTextNode('Audio'));
- div.setAttribute("align", "center");
- contentEl.appendChild(div);
- //Generate and add results table
- contentEl.appendChild(generateTable('info', 3, 3, elementsResultsAudio));
-
- //Title audio actions
- div = document.createElement('h2');
- div.appendChild(document.createTextNode('Actions'));
- div.setAttribute("align", "center");
- contentEl.appendChild(div);
- //Generate and add buttons table
- contentEl.appendChild(generateTable('audioActions', 3, 3, elementsAudio));
- createActionButton('Play', function () {
- playAudio();
- }, 'playBtn');
- createActionButton('Pause', function () {
- pauseAudio();
- }, 'pauseBtn');
- createActionButton('Stop', function () {
- stopAudio();
- }, 'stopBtn');
- createActionButton('Release', function () {
- releaseAudio();
- }, 'releaseBtn');
- createActionButton('Seek By', function () {
- seekAudio('by');
- }, 'seekByBtn');
- createActionButton('Seek To', function () {
- seekAudio('to');
- }, 'seekToBtn');
- //get Special path to record if iOS || Blackberry
- if (cordova.platformId === 'ios')
- getRecordSrc();
- else
- if (cordova.platformId === 'blackberry')
- getRecordSrcBB();
-
- //Title Record Audio
- div = document.createElement('h2');
- div.appendChild(document.createTextNode('Record Audio'));
- div.setAttribute("align", "center");
- contentEl.appendChild(div);
- //Generate and add Record buttons table
- contentEl.appendChild(generateTable('recordContent', 3, 3, elementsRecord));
- createActionButton('Record Audio \n 10 sec', function () {
- recordAudio();
- }, 'recordbtn');
- createActionButton('Play', function () {
- playRecording();
- }, 'recordplayBtn');
- createActionButton('Pause', function () {
- pauseAudio();
- }, 'recordpauseBtn');
- createActionButton('Stop', function () {
- stopAudio();
- }, 'recordstopBtn');
-};
http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/658d86b1/tests/plugin.xml
----------------------------------------------------------------------
diff --git a/tests/plugin.xml b/tests/plugin.xml
new file mode 100644
index 0000000..e23aea9
--- /dev/null
+++ b/tests/plugin.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
+ xmlns:rim="http://www.blackberry.com/ns/widgets"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="org.apache.cordova.media.tests"
+ version="0.2.12-dev">
+ <name>Cordova Media Plugin Tests</name>
+ <license>Apache 2.0</license>
+ <js-module src="tests.js" name="tests">
+ </js-module>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/658d86b1/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
new file mode 100644
index 0000000..cba8007
--- /dev/null
+++ b/tests/tests.js
@@ -0,0 +1,764 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+exports.defineAutoTests = function () {
+ var failed = function (done, msg, error) {
+ var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg;
+ expect(true).toFailWithMessage(info + '\n' + JSON.stringify(error));
+ done();
+ };
+
+ var succeed = function (done, msg) {
+ var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg;
+ expect(true).toFailWithMessage(info);
+ done();
+ };
+
+ describe('Media', function () {
+
+ beforeEach(function () {
+ // Custom Matcher
+ jasmine.Expectation.addMatchers({
+ toFailWithMessage : function () {
+ return {
+ compare : function (error, message) {
+ var pass = false;
+ return {
+ pass : pass,
+ message : message
+ };
+ }
+ };
+ }
+ });
+ });
+
+ it("media.spec.1 should exist", function () {
+ expect(Media).toBeDefined();
+ expect(typeof Media).toBe("function");
+ });
+
+ it("media.spec.2 should have the following properties", function () {
+ var media1 = new Media("dummy");
+ expect(media1.id).toBeDefined();
+ expect(media1.src).toBeDefined();
+ expect(media1._duration).toBeDefined();
+ expect(media1._position).toBeDefined();
+ media1.release();
+ });
+
+ it("media.spec.3 should define constants for Media status", function () {
+ expect(Media).toBeDefined();
+ expect(Media.MEDIA_NONE).toBe(0);
+ expect(Media.MEDIA_STARTING).toBe(1);
+ expect(Media.MEDIA_RUNNING).toBe(2);
+ expect(Media.MEDIA_PAUSED).toBe(3);
+ expect(Media.MEDIA_STOPPED).toBe(4);
+ });
+
+ it("media.spec.4 should define constants for Media errors", function () {
+ expect(MediaError).toBeDefined();
+ expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
+ expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
+ expect(MediaError.MEDIA_ERR_NETWORK).toBe(2);
+ expect(MediaError.MEDIA_ERR_DECODE).toBe(3);
+ expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
+ });
+
+ it("media.spec.5 should contain a play function", function () {
+ var media1 = new Media();
+ expect(media1.play).toBeDefined();
+ expect(typeof media1.play).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.6 should contain a stop function", function () {
+ var media1 = new Media();
+ expect(media1.stop).toBeDefined();
+ expect(typeof media1.stop).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.7 should contain a seekTo function", function () {
+ var media1 = new Media();
+ expect(media1.seekTo).toBeDefined();
+ expect(typeof media1.seekTo).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.8 should contain a pause function", function () {
+ var media1 = new Media();
+ expect(media1.pause).toBeDefined();
+ expect(typeof media1.pause).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.9 should contain a getDuration function", function () {
+ var media1 = new Media();
+ expect(media1.getDuration).toBeDefined();
+ expect(typeof media1.getDuration).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.10 should contain a getCurrentPosition function", function () {
+ var media1 = new Media();
+ expect(media1.getCurrentPosition).toBeDefined();
+ expect(typeof media1.getCurrentPosition).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.11 should contain a startRecord function", function () {
+ var media1 = new Media();
+ expect(media1.startRecord).toBeDefined();
+ expect(typeof media1.startRecord).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.12 should contain a stopRecord function", function () {
+ var media1 = new Media();
+ expect(media1.stopRecord).toBeDefined();
+ expect(typeof media1.stopRecord).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.13 should contain a release function", function () {
+ var media1 = new Media();
+ expect(media1.release).toBeDefined();
+ expect(typeof media1.release).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.14 should contain a setVolume function", function () {
+ var media1 = new Media();
+ expect(media1.setVolume).toBeDefined();
+ expect(typeof media1.setVolume).toBe('function');
+ media1.release();
+ });
+
+ it("media.spec.15 should return MediaError for bad filename", function (done) {
+ var fileName = 'invalid.file.name';
+ //Error callback it has an unexpected behavior under Windows Phone,
+ //it enters to the error callback several times, instead of just one walk-through
+ //JIRA issue related with all details: CB-7092
+ //the conditional statement should be removed once the issue is fixed.
+
+ //bb10 dialog pops up, preventing tests from running
+ if (cordova.platformId === 'blackberry10' || cordova.platformId === 'windowsphone') {
+ expect(true).toFailWithMessage('Platform does not support this feature');
+ done();
+ } else {
+ var badMedia = null;
+ badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) {
+ expect(result).toBeDefined();
+ expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED);
+ badMedia.release();
+ done();
+ });
+ badMedia.play();
+ }
+ });
+
+ it("media.spec.16 position should be set properly", function (done) {
+ var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3',
+ mediaState = Media.MEDIA_STOPPED,
+ successCallback,
+ flag = true,
+ statusChange = function (statusCode) {
+ if (statusCode == Media.MEDIA_RUNNING && flag) {
+ //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
+ //in case for some reason the statusChange callback is reached more than one time with the same status code.
+ //Some information about this kind of behavior it can be found at JIRA: CB-7099
+ flag = false;
+ setTimeout(function () {
+ media1.getCurrentPosition(function (position) {
+ expect(position).toBeGreaterThan(0.0);
+ media1.stop();
+ media1.release();
+ done();
+ }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position'));
+ }, 1000);
+ }
+ };
+ media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange);
+ media1.play();
+ });
+
+ it("media.spec.17 duration should be set properly", function (done) {
+ if (cordova.platformId === 'blackberry10') {
+ expect(true).toFailWithMessage('Platform does not supported this feature');
+ done();
+ }
+ var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3',
+ mediaState = Media.MEDIA_STOPPED,
+ successCallback,
+ flag = true,
+ statusChange = function (statusCode) {
+ if (statusCode == Media.MEDIA_RUNNING && flag) {
+ //flag variable used to ensure an extra security statement to ensure that the callback is processed only once,
+ //in case for some reason the statusChange callback is reached more than one time with the same status code.
+ //Some information about this kind of behavior it can be found at JIRA: CB-7099.
+ flag = false;
+ setTimeout(function () {
+ expect(media1.getDuration()).toBeGreaterThan(0.0);
+ media1.stop();
+ media1.release();
+ done();
+ }, 1000);
+ }
+ },
+ media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange);
+ media1.play();
+ });
+ });
+};
+
+//******************************************************************************************
+//***************************************Manual Tests***************************************
+//******************************************************************************************
+
+exports.defineManualTests = function (contentEl, createActionButton) {
+ //-------------------------------------------------------------------------
+ // Audio player
+ //-------------------------------------------------------------------------
+ var media1 = null;
+ var media1Timer = null;
+ var audioSrc = null;
+ var defaultaudio = "http://cordova.apache.org/downloads/BlueZedEx.mp3";
+
+ //Play audio function
+ function playAudio(url) {
+ console.log("playAudio()");
+ console.log(" -- media=" + media1);
+
+ var src = defaultaudio;
+
+ if (url) {
+ src = url;
+ }
+
+ // Stop playing if src is different from currently playing source
+ if (src !== audioSrc) {
+ if (media1 !== null) {
+ stopAudio();
+ media1 = null;
+ }
+ }
+
+ if (media1 === null) {
+
+ // TEST STREAMING AUDIO PLAYBACK
+ //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3"; // works
+ //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
+ //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
+ //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
+ //var src = "MusicSearch/mp3/train.mp3"; // works
+ //var src = "bryce.mp3"; // works
+ //var src = "/android_asset/www/bryce.mp3"; // works
+
+ media1 = new Media(src,
+ function () {
+ console.log("playAudio():Audio Success");
+ },
+ function (err) {
+ console.log("playAudio():Audio Error: " + err.code);
+ setAudioStatus("Error: " + err.code);
+ },
+ function (status) {
+ console.log("playAudio():Audio Status: " + status);
+ setAudioStatus(Media.MEDIA_MSG[status]);
+
+ // If stopped, then stop getting current position
+ if (Media.MEDIA_STOPPED == status) {
+ clearInterval(media1Timer);
+ media1Timer = null;
+ setAudioPosition("0 sec");
+ }
+ });
+ }
+ audioSrc = src;
+ document.getElementById('durationValue').innerHTML = "";
+ // Play audio
+ media1.play();
+ if (media1Timer === null && media1.getCurrentPosition) {
+ media1Timer = setInterval(
+ function () {
+ media1.getCurrentPosition(
+ function (position) {
+ if (position >= 0.0) {
+ setAudioPosition(position + " sec");
+ }
+ },
+ function (e) {
+ console.log("Error getting pos=" + e);
+ setAudioPosition("Error: " + e);
+ });
+ },
+ 1000);
+ }
+
+ // Get duration
+ var counter = 0;
+ var timerDur = setInterval(
+ function () {
+ counter = counter + 100;
+ if (counter > 2000) {
+ clearInterval(timerDur);
+ }
+ var dur = media1.getDuration();
+ if (dur > 0) {
+ clearInterval(timerDur);
+ document.getElementById('durationValue').innerHTML = dur + " sec";
+ }
+ }, 100);
+ }
+
+ //Pause audio playback
+ function pauseAudio() {
+ console.log("pauseAudio()");
+ if (media1) {
+ media1.pause();
+ }
+ }
+
+ //Stop audio
+ function stopAudio() {
+ console.log("stopAudio()");
+ if (media1) {
+ media1.stop();
+ }
+ clearInterval(media1Timer);
+ media1Timer = null;
+ }
+
+ //Release audio
+ function releaseAudio() {
+ console.log("releaseAudio()");
+ if (media1) {
+ media1.stop(); //imlied stop of playback, resets timer
+ media1.release();
+ }
+ }
+
+ //Set audio status
+ function setAudioStatus(status) {
+ document.getElementById('statusValue').innerHTML = status;
+ }
+
+ //Set audio position
+ function setAudioPosition(position) {
+ document.getElementById('positionValue').innerHTML = position;
+ }
+
+ //Seek audio
+ function seekAudio(mode) {
+ var time = document.getElementById("seekInput").value;
+ if (time === "") {
+ time = 5000;
+ } else {
+ time = time * 1000; //we expect the input to be in seconds
+ }
+ if (media1 === null) {
+ console.log("seekTo requested while media1 is null");
+ if (audioSrc === null) {
+ audioSrc = defaultaudio;
+ }
+ media1 = new Media(audioSrc,
+ function () {
+ console.log("seekToAudio():Audio Success");
+ },
+ function (err) {
+ console.log("seekAudio():Audio Error: " + err.code);
+ setAudioStatus("Error: " + err.code);
+ },
+ function (status) {
+ console.log("seekAudio():Audio Status: " + status);
+ setAudioStatus(Media.MEDIA_MSG[status]);
+
+ // If stopped, then stop getting current position
+ if (Media.MEDIA_STOPPED == status) {
+ clearInterval(media1Timer);
+ media1Timer = null;
+ setAudioPosition("0 sec");
+ }
+ });
+ }
+
+ media1.getCurrentPosition(
+ function (position) {
+ var deltat = time;
+ if (mode === "by") {
+ deltat = time + position * 1000;
+ }
+ media1.seekTo(deltat,
+ function () {
+ console.log("seekAudioTo():Audio Success");
+ //force an update on the position display
+ updatePosition();
+ },
+ function (err) {
+ console.log("seekAudioTo():Audio Error: " + err.code);
+ });
+ },
+ function (e) {
+ console.log("Error getting pos=" + e);
+ setAudioPosition("Error: " + e);
+ });
+ }
+
+ //for forced updates of position after a successful seek
+
+ function updatePosition() {
+ media1.getCurrentPosition(
+ function (position) {
+ if (position >= 0.0) {
+ setAudioPosition(position + " sec");
+ }
+ },
+ function (e) {
+ console.log("Error getting pos=" + e);
+ setAudioPosition("Error: " + e);
+ });
+ }
+
+ //-------------------------------------------------------------------------
+ // Audio recorder
+ //-------------------------------------------------------------------------
+ var mediaRec = null;
+ var recTime = 0;
+ var recordSrc = "myRecording.mp3";
+
+ //Record audio
+ function recordAudio() {
+ console.log("recordAudio()");
+ console.log(" -- media=" + mediaRec);
+ if (mediaRec == null) {
+ var src = recordSrc;
+ mediaRec = new Media(src,
+ function () {
+ console.log("recordAudio():Audio Success");
+ },
+ function (err) {
+ console.log("recordAudio():Audio Error: " + err.code);
+ setAudioStatus("Error: " + err.code);
+ },
+ function (status) {
+ console.log("recordAudio():Audio Status: " + status);
+ setAudioStatus(Media.MEDIA_MSG[status]);
+ });
+ }
+
+ // Record audio
+ mediaRec.startRecord();
+
+ // Stop recording after 10 sec
+ recTime = 0;
+ var recInterval = setInterval(function () {
+ recTime = recTime + 1;
+ setAudioPosition(recTime + " sec");
+ if (recTime >= 10) {
+ clearInterval(recInterval);
+ if (mediaRec.stopAudioRecord) {
+ mediaRec.stopAudioRecord();
+ } else {
+ mediaRec.stopRecord();
+ }
+ console.log("recordAudio(): stop");
+ }
+ }, 1000);
+ }
+
+ //Play back recorded audio
+ function playRecording() {
+ playAudio(recordSrc);
+ }
+
+ //Function to create a file for iOS recording
+
+ function getRecordSrc() {
+ var fsFail = function (error) {
+ console.log("error creating file for iOS recording");
+ };
+ var gotFile = function (file) {
+ recordSrc = file.fullPath;
+ //console.log("recording Src: " + recordSrc);
+ };
+ var gotFS = function (fileSystem) {
+ fileSystem.root.getFile("iOSRecording.wav", {
+ create : true
+ }, gotFile, fsFail);
+ };
+ window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
+ }
+
+ //Function to create a file for BB recording
+ function getRecordSrcBB() {
+ var fsFail = function (error) {
+ console.log("error creating file for BB recording");
+ };
+ var gotFile = function (file) {
+ recordSrc = file.fullPath;
+ };
+ var gotFS = function (fileSystem) {
+ fileSystem.root.getFile("BBRecording.amr", {
+ create : true
+ }, gotFile, fsFail);
+ };
+ window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
+ }
+
+//Generate Dynamic Table
+ function generateTable(tableId, rows, cells, elements) {
+ var table = document.createElement('table');
+ for (var r = 0; r < rows; r++) {
+ var row = table.insertRow(r);
+ for (var c = 0; c < cells; c++) {
+ var cell = row.insertCell(c);
+ cell.setAttribute("align", "center");
+ for (var e in elements) {
+ if (elements[e].position.row == r && elements[e].position.cell == c) {
+ var htmlElement = document.createElement(elements[e].tag);
+ var content;
+
+ if (elements[e].content !== "") {
+ content = document.createTextNode(elements[e].content);
+ htmlElement.appendChild(content);
+ }
+ if (elements[e].type) {
+ htmlElement.type = elements[e].type;
+ }
+ htmlElement.setAttribute("id", elements[e].id);
+ cell.appendChild(htmlElement);
+ }
+ }
+ }
+ }
+ table.setAttribute("align", "center");
+ table.setAttribute("id", tableId);
+ return table;
+ }
+
+//Audio && Record Elements
+ var elementsResultsAudio=
+ [{
+ id : "statusTag",
+ content : "Status:",
+ tag : "div",
+ position : {
+ row : 0,
+ cell : 0
+ }
+ }, {
+ id : "statusValue",
+ content : "",
+ tag : "div",
+ position : {
+ row : 0,
+ cell : 2
+ }
+ }, {
+ id : "durationTag",
+ content : "Duration:",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 0
+ }
+ }, {
+ id : "durationValue",
+ content : "",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 2
+ }
+ }, {
+ id : "positionTag",
+ content : "Position:",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 0
+ }
+ }, {
+ id : "positionValue",
+ content : "",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 2
+ }
+ }],
+ elementsAudio =
+ [{
+ id : "playBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 0,
+ cell : 0
+ }
+ }, {
+ id : "pauseBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 0,
+ cell : 1
+ }
+ }, {
+ id : "stopBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 0
+ }
+ }, {
+ id : "releaseBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 1
+ }
+ }, {
+ id : "seekByBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 0
+ }
+ }, {
+ id : "seekToBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 1
+ }
+ }, {
+ id : "seekInput",
+ content : "",
+ tag : "input",
+ type : "number",
+ position : {
+ row : 2,
+ cell : 2
+ }
+ }
+ ],
+ elementsRecord =
+ [{
+ id : "recordbtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 0
+ }
+ }, {
+ id : "recordplayBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 1,
+ cell : 1
+ }
+ }, {
+ id : "recordpauseBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 0
+ }
+ }, {
+ id : "recordstopBtn",
+ content : "",
+ tag : "div",
+ position : {
+ row : 2,
+ cell : 1
+ }
+ }
+ ];
+
+ //Title audio results
+ var div = document.createElement('h2');
+ div.appendChild(document.createTextNode('Audio'));
+ div.setAttribute("align", "center");
+ contentEl.appendChild(div);
+ //Generate and add results table
+ contentEl.appendChild(generateTable('info', 3, 3, elementsResultsAudio));
+
+ //Title audio actions
+ div = document.createElement('h2');
+ div.appendChild(document.createTextNode('Actions'));
+ div.setAttribute("align", "center");
+ contentEl.appendChild(div);
+ //Generate and add buttons table
+ contentEl.appendChild(generateTable('audioActions', 3, 3, elementsAudio));
+ createActionButton('Play', function () {
+ playAudio();
+ }, 'playBtn');
+ createActionButton('Pause', function () {
+ pauseAudio();
+ }, 'pauseBtn');
+ createActionButton('Stop', function () {
+ stopAudio();
+ }, 'stopBtn');
+ createActionButton('Release', function () {
+ releaseAudio();
+ }, 'releaseBtn');
+ createActionButton('Seek By', function () {
+ seekAudio('by');
+ }, 'seekByBtn');
+ createActionButton('Seek To', function () {
+ seekAudio('to');
+ }, 'seekToBtn');
+ //get Special path to record if iOS || Blackberry
+ if (cordova.platformId === 'ios')
+ getRecordSrc();
+ else
+ if (cordova.platformId === 'blackberry')
+ getRecordSrcBB();
+
+ //Title Record Audio
+ div = document.createElement('h2');
+ div.appendChild(document.createTextNode('Record Audio'));
+ div.setAttribute("align", "center");
+ contentEl.appendChild(div);
+ //Generate and add Record buttons table
+ contentEl.appendChild(generateTable('recordContent', 3, 3, elementsRecord));
+ createActionButton('Record Audio \n 10 sec', function () {
+ recordAudio();
+ }, 'recordbtn');
+ createActionButton('Play', function () {
+ playRecording();
+ }, 'recordplayBtn');
+ createActionButton('Pause', function () {
+ pauseAudio();
+ }, 'recordpauseBtn');
+ createActionButton('Stop', function () {
+ stopAudio();
+ }, 'recordstopBtn');
+};