Drop unused test helpers (#214)

* Remove unused module mockxhr

* Remove unnecessary test utils

* Remove unused placeholders

* Inline testmodule fixture

* Move test-platform modules to test/
diff --git a/src/common/builder.js b/src/common/builder.js
index 29b7307..7b6dc40 100644
--- a/src/common/builder.js
+++ b/src/common/builder.js
@@ -30,7 +30,6 @@
 }
 
 function clobber (obj, key, value) {
-    exports.replaceHookForTesting(obj, key);
     var needsProperty = false;
     try {
         obj[key] = value;
@@ -130,4 +129,3 @@
 };
 exports.recursiveMerge = recursiveMerge;
 exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function () {};
diff --git a/src/common/platform.js b/src/common/platform.js
deleted file mode 100644
index 8cef3c6..0000000
--- a/src/common/platform.js
+++ /dev/null
@@ -1,22 +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.
- *
-*/
-
-throw new Error('should have been replaced at build time with platform implementation');
diff --git a/src/legacy-exec/test/platform.js b/src/legacy-exec/test/platform.js
deleted file mode 100644
index 08bb635..0000000
--- a/src/legacy-exec/test/platform.js
+++ /dev/null
@@ -1,36 +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.
- *
-*/
-
-module.exports = {
-    id: 'test platform',
-    bootstrap: function () {
-        var propertyreplacer = require('cordova/test/propertyreplacer');
-
-        require('cordova/builder').replaceHookForTesting = function (obj, key) {
-            // This doesn't clean up non-clobbering assignments, nor does it work for
-            // getters. It does work to un-clobber clobbered / merged symbols, which
-            // is generally good enough for tests.
-            if (obj[key]) {
-                propertyreplacer.stub(obj, key);
-            }
-        };
-    }
-};
diff --git a/src/legacy-exec/test/test/mockxhr.js b/src/legacy-exec/test/test/mockxhr.js
deleted file mode 100644
index b0a001d..0000000
--- a/src/legacy-exec/test/test/mockxhr.js
+++ /dev/null
@@ -1,121 +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.
- *
-*/
-
-var utils = require('cordova/utils');
-var activeXhrs = [];
-var isInstalled = false;
-var origXhr = this.XMLHttpRequest;
-
-function MockXhr () {
-    this.requestHeaders = {};
-    this.readyState = 0;
-
-    this.onreadystatechange = null;
-    this.onload = null;
-    this.onerror = null;
-    this.clearResponse_();
-}
-
-MockXhr.prototype.clearResponse_ = function () {
-    this.url = null;
-    this.method = null;
-    this.async = null;
-    this.requestPayload = undefined;
-
-    this.statusCode = 0;
-    this.responseText = '';
-    this.responseHeaders = {};
-};
-
-MockXhr.prototype.setReadyState_ = function (value) {
-    this.readyState = value;
-    this.onreadystatechange && this.onreadystatechange();
-};
-
-MockXhr.prototype.open = function (method, url, async) {
-    if (this.readyState !== 0 && this.readyState !== 4) {
-        throw Error('Tried to open MockXhr while request in progress.');
-    }
-    this.clearResponse_();
-    this.method = method;
-    this.url = url;
-    this.async = async;
-    this.setReadyState_(1);
-};
-
-MockXhr.prototype.setRequestHeader = function (key, val) {
-    if (this.readyState !== 1) {
-        throw Error('Tried to setRequestHeader() without call to open()');
-    }
-    this.requestHeaders[key] = String(val);
-};
-
-MockXhr.prototype.send = function (payload) {
-    if (this.readyState !== 1) {
-        throw Error('Tried to send MockXhr without call to open().');
-    }
-    this.requestPayload = payload;
-    this.setReadyState_(2);
-
-    activeXhrs.push(this);
-};
-
-MockXhr.prototype.simulateResponse = function (statusCode, responseText, responseHeaders) {
-    if (this.readyState !== 2) {
-        throw Error('Call to simulateResponse() when MockXhr is in state ' + this.readyState);
-    }
-    for (var i = this.readyState; i <= 4; i++) {
-        if (i === 2) {
-            this.statusCode = statusCode;
-            this.responseHeaders = responseHeaders || this.responseHeaders;
-        }
-        if (i === 4) {
-            this.responseText = responseText;
-        }
-        this.setReadyState_(i);
-    }
-    if (statusCode === 200) {
-        this.onload && this.onload();
-    } else {
-        this.onerror && this.onerror();
-    }
-    utils.arrayRemove(activeXhrs, this);
-};
-
-function install () {
-    if (isInstalled) {
-        throw Error('mockxhr.install called without uninstall.');
-    }
-    isInstalled = true;
-    activeXhrs.length = 0;
-    XMLHttpRequest = MockXhr; // eslint-disable-line no-undef
-}
-
-function uninstall () {
-    XMLHttpRequest = origXhr; // eslint-disable-line no-undef
-    isInstalled = false;
-}
-
-module.exports = {
-    install: install,
-    uninstall: uninstall,
-    activeXhrs: activeXhrs
-};
diff --git a/src/legacy-exec/test/test/propertyreplacer.js b/src/legacy-exec/test/test/propertyreplacer.js
deleted file mode 100644
index 89da92a..0000000
--- a/src/legacy-exec/test/test/propertyreplacer.js
+++ /dev/null
@@ -1,45 +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.
- *
-*/
-
-/* eslint-env jasmine */
-
-// Use this helper module to stub out properties within Jasmine tests.
-// Original values will be restored after each test.
-
-var stubs = [];
-
-function removeAllStubs () {
-    for (const stub of stubs) {
-        stub.obj[stub.key] = stub.value;
-    }
-    stubs = [];
-}
-
-afterEach(removeAllStubs);
-
-exports.stub = function (obj, key, value) {
-    stubs.push({
-        obj: obj,
-        key: key,
-        value: obj[key]
-    });
-    obj[key] = value;
-};
diff --git a/src/legacy-exec/test/test/testmodule.js b/src/legacy-exec/test/test/testmodule.js
deleted file mode 100644
index 4a238d4..0000000
--- a/src/legacy-exec/test/test/testmodule.js
+++ /dev/null
@@ -1,27 +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.
- *
-*/
-
-module.exports = {
-    func: function () {},
-    num: 2,
-    obj: { str: 'hello' },
-    subObj: { str: 'testSubObj' }
-};
diff --git a/test/build.js b/test/build.js
index 5a54eb0..63947d0 100755
--- a/test/build.js
+++ b/test/build.js
@@ -27,7 +27,7 @@
         extraModules: collectTestBuildModules(),
         preprocess (f) {
             // Do not instrument our test dummies
-            if (f.path.includes('src/legacy-exec/test/')) return f;
+            if (f.path.includes('/test/test-platform-modules/')) return f;
 
             const contents = instrumenter.instrumentSync(f.contents, f.path);
             return Object.assign({}, f, { contents });
@@ -51,6 +51,6 @@
     });
 
     // Finally, add modules provided by test platform
-    const testModulesPath = path.join(__dirname, '../src/legacy-exec/test');
+    const testModulesPath = path.join(__dirname, 'test-platform-modules');
     return Object.assign(...platformModules, collectModules(testModulesPath));
 }
diff --git a/src/legacy-exec/test/exec.js b/test/test-platform-modules/exec.js
similarity index 100%
rename from src/legacy-exec/test/exec.js
rename to test/test-platform-modules/exec.js
diff --git a/src/common/exec.js b/test/test-platform-modules/platform.js
similarity index 89%
rename from src/common/exec.js
rename to test/test-platform-modules/platform.js
index 8cef3c6..90e9fa4 100644
--- a/src/common/exec.js
+++ b/test/test-platform-modules/platform.js
@@ -19,4 +19,7 @@
  *
 */
 
-throw new Error('should have been replaced at build time with platform implementation');
+module.exports = {
+    id: 'test platform',
+    bootstrap: function () {}
+};
diff --git a/test/test.modulemapper.js b/test/test.modulemapper.js
index db09c75..61c9b94 100644
--- a/test/test.modulemapper.js
+++ b/test/test.modulemapper.js
@@ -20,11 +20,20 @@
 
 describe('modulemapper', function () {
     var modulemapper = cordova.require('cordova/modulemapper');
-    var testmodule = cordova.require('cordova/test/testmodule');
     var utils = cordova.require('cordova/utils');
-    var context;
+    var context, testmodule;
 
     beforeEach(function () {
+        testmodule = {
+            func: function () {},
+            num: 2,
+            obj: { str: 'hello' },
+            subObj: { str: 'testSubObj' }
+        };
+        cordova.define('cordova/test/testmodule', (r, e, module) => {
+            module.exports = testmodule;
+        });
+
         function TestClass () {}
         TestClass.prototype.method1 = function () { return 'orig'; };
 
@@ -39,6 +48,7 @@
 
     afterEach(function () {
         modulemapper.reset();
+        cordova.define.remove('cordova/test/testmodule');
     });
 
     it('Test#001 : should throw in module does not exist', function () {