You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cordova.apache.org by audreyso <gi...@git.apache.org> on 2017/06/29 17:19:13 UTC

[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

GitHub user audreyso opened a pull request:

    https://github.com/apache/cordova-lib/pull/573

    CB-12361 : updated addHelper tests

    <!--
    Please make sure the checklist boxes are all checked before submitting the PR. The checklist
    is intended as a quick reference, for complete details please see our Contributor Guidelines:
    
    http://cordova.apache.org/contribute/contribute_guidelines.html
    
    Thanks!
    -->
    
    ### Platforms affected
    
    
    ### What does this PR do?
    updated addHelper tests
    
    ### What testing has been done on this change?
    
    
    ### Checklist
    - [X] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
    - [X] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
    - [X] Added automated test coverage as appropriate for this change.


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/audreyso/cordova-lib CB-12361-6

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/cordova-lib/pull/573.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #573
    
----
commit acda3f4be22c4dbb69bde54adf42ccc185080ba2
Author: Audrey So <au...@apache.org>
Date:   2017-06-29T16:46:57Z

    CB-12361 : updated addHelper tests

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by audreyso <gi...@git.apache.org>.
Github user audreyso commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127110528
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    fixed! thanks @stevengill !!!


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124867315
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    --- End diff --
    
    I would move this into a beforeEach since it seems like you use it throughout the tests


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127055093
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    Yup. Just do string matching for the first part of the warning.  https://github.com/apache/cordova-lib/pull/573#discussion_r127032404


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124893969
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            xit('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_addHelper.installPluginsForNewPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should save the platform metadata', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_metadata.save).toHaveBeenCalledWith('/some/path', 'atari', undefined);
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should write out the version of platform just added/updated to config.xml if the save option is provided', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true}).then(function(result) {
    +                    expect(cfg_parser_mock.prototype.removeEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.addEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.write).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            describe('if the project contains a package.json', function () {
    +                beforeEach(function () {
    +                    var pkgJsonEmpty = {};
    +                    //spy for package.json to exist
    +                    fs.existsSync.and.callFake(function(filePath) {
    +                        if(path.basename(filePath) === 'package.json') {
    +                            return true;
    +                        } else {
    +                            return false;
    +                        }
    +                    });
    +                    //require packge.json object
    +                    spyOn(cordova_util, 'requireNoCache').and.returnValue(pkgJsonEmpty);
    +                });
    +
    +                xit('should write out the platform just added/updated to the cordova.platforms property of package.json',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should only write the package.json file if it was modified', function (done) {
    +                    var pkgJsonFull = { 'cordova': {'platforms': ['atari']}};
    +                    cordova_util.requireNoCache.and.returnValue(pkgJsonFull);
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).not.toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should file the after_platform_* hook',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(hooks_mock.fire).toHaveBeenCalledWith( 'before_platform_add', Object({ save: true, searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +        });
    +    });
    +    describe('downloadPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(Q, 'reject').and.callThrough();
    +            platform_addHelper.downloadPlatform.and.callThrough();
    +        });
    +        describe('errors', function () {
    +            it('should reject the promise should fetch fail', function (done) {
    +                fetch_mock.and.returnValue(Q.reject('fetch has failed, rejecting promise'));
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '67', {fetch: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(e.message).toContain('fetch has failed, rejecting promise');
    +                }).done(done);
    +            });
    +
    +            it('should reject the promise should lazy_load.git_clone fail', function (done) {
    +                spyOn(events, 'emit');
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(false);
    +                spyOn(lazy_load, 'git_clone').and.callThrough();
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(events.emit.calls.argsFor(2)[1].toString()).toContain('Cloning failed. Let\'s try handling it as a tarball');
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should lazy_load.based_on_config fail', function (done) {
    +                spyOn(gitclone, 'clone').and.callThrough();
    +                spyOn(lazy_load, 'git_clone').and.returnValue(true);
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(false);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(Q.reject.calls.allArgs().toString()).toContain('Failed to fetch platform android@https://github.com/apache/cordova-android');
    +                    expect(lazy_load.based_on_config).not.toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should both git_clone and based_on_config fail after the latter was fallen back on', function (done) {
    +                spyOn(lazy_load, 'git_clone').and.returnValue(Q.reject('git_clone failed'));
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(Q.reject('based_on_config failed'));
    +                cordova_util.isUrl.and.returnValue(true);
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +        });
    +        describe('happy path', function () {
    +            it('should invoke cordova-fetch if fetch was provided as an option', function (done) {
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '6.0.0', {fetch: true}).then(function () {
    +                    expect(fetch_mock).toHaveBeenCalledWith('cordova-android@6.0.0', projectRoot, Object({ fetch: true }));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            });
    +
    +            it('should invoke lazy_load.git_clone if the version to download is a URL', function (done) {
    +                spyOn(lazy_load, 'git_clone').and.callThrough();
    +                spyOn(gitclone, 'clone').and.returnValue(true);
    +                spyOn(events, 'emit');
    +                fetch_mock.and.returnValue(true);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit.calls.argsFor(0)[1]).toBe('git cloning: https://github.com/apache/cordova-android');
    +                    expect(cordova_util.isUrl).toHaveBeenCalledWith('https://github.com/apache/cordova-android');
    +                    expect(lazy_load.git_clone).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +
    +            it('should attempt to lazy_load.based_on_config if lazy_load.git_clone fails', function (done) {
    +                spyOn(events, 'emit');
    +                spyOn(lazy_load, 'based_on_config');
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('"git" command line tool is not installed: make sure it is accessible on your PATH.');
    +                    expect(events.emit.calls.argsFor(2)[1]).toBe('Cloning failed. Let\'s try handling it as a tarball');
    +                    expect(lazy_load.based_on_config).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +            
    +            it('should by default attempt to lazy_load.based_on_config', function (done) {
    +                spyOn(lazy_load, 'based_on_config');
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '6.0.0', {save:true}).then(function () {
    +                    expect(lazy_load.based_on_config).toHaveBeenCalledWith('/some/path', 'android@6.0.0', Object({ save: true }));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +
    +            it('should pass along a libDir argument to getPlatformDetailsFromDir on a successful platform download', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save:true}).then(function () {
    +                    expect(require('../../../src/cordova/platform/index').getPlatformDetailsFromDir).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +        });
    +    });
    +    describe('installPluginsForNewPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(events, 'emit');
    +            spyOn(fetch_metadata, 'get_fetch_metadata');
    +            spyOn(plugman, 'install').and.returnValue(Q());
    +            platform_addHelper.installPluginsForNewPlatform.and.callThrough();
    +        });
    +
    +        it('should immediately return if there are no plugins to install into the platform', function (done) {
    +            platform_addHelper.installPluginsForNewPlatform('android', projectRoot).then(function () {
    +                expect(plugman.install).not.toHaveBeenCalled();
    +            }).fail(function (e) {
    +                fail('fail handler unexpectedly invoked');
    +            }).done(done);
    +        });
    +
    +        it('should invoke plugman.install, giving correct platform, plugin and other arguments', function (done) {
    +            spyOn(cordova_util, 'findPlugins').and.returnValue(['cordova-plugin-whitelist']);
    +            fetch_metadata.get_fetch_metadata.and.returnValue({ });
    +            platform_addHelper.installPluginsForNewPlatform('browser', projectRoot, {save:true , fetch:true}).then(function () {
    +                expect(plugman.install).toHaveBeenCalled();
    +                expect(events.emit.calls.argsFor(0)[1]).toContain('Installing plugin "cordova-plugin-whitelist" following successful platform add of browser');
    --- End diff --
    
    use `toHaveBeenCalledWith`



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124890998
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    --- End diff --
    
    don't need these spys


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124873252
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            xit('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_addHelper.installPluginsForNewPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should save the platform metadata', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_metadata.save).toHaveBeenCalledWith('/some/path', 'atari', undefined);
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should write out the version of platform just added/updated to config.xml if the save option is provided', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true}).then(function(result) {
    +                    expect(cfg_parser_mock.prototype.removeEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.addEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.write).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            describe('if the project contains a package.json', function () {
    +                beforeEach(function () {
    +                    var pkgJsonEmpty = {};
    --- End diff --
    
    You can also setup a mock for pkgJson. See https://github.com/apache/cordova-lib/pull/569/files#diff-cf8ce8cb2269ffb838e27c4e446bb0ddR40 and lines 65-69 https://github.com/apache/cordova-lib/pull/569/files#diff-cf8ce8cb2269ffb838e27c4e446bb0ddR65. Then you can do stuff like https://github.com/apache/cordova-lib/pull/569/files#diff-cf8ce8cb2269ffb838e27c4e446bb0ddR245


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by audreyso <gi...@git.apache.org>.
Github user audreyso commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127007878
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    Ohh yes @stevengill  I commented this out b/c it’s failing on travis, but passing locally.
    Failure I’m getting is:
    
    ```
     Expected spy emit to have been called with [ 'warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.' ] but actual calls were [ 'warning', 'WARNING: Applications for platform atari can not be built on this OS - linux.' ], [ 'verbose', 'No version supplied. Retrieving version from config.xml...' ], [ 'log', 'Adding atari project...' ].
    
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124879975
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    --- End diff --
    
    `platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform], {restoring:true}).then(function () {`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124874233
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    --- End diff --
    
    You might want to return an object instead of true since `requireNoCache` is primarily used for `package.json`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124892113
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            xit('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    --- End diff --
    
    pass in restoring option so you can run this test


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124878233
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    --- End diff --
    
    For consistency, maybe have the fail handlers use the same wording as above. https://github.com/apache/cordova-lib/pull/573/files#diff-c1a353458ab1cba5a926c809aadd9312R99
    
    `fail('addHelper success handler unexpectedly invoked');`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/cordova-lib/pull/573


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124868182
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    --- End diff --
    
    @filmaj suggested we avoid the `.calls` api and instead use `toHaveBeenCalledWith()`. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by audreyso <gi...@git.apache.org>.
Github user audreyso commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127008421
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    In this case, could I use:
    
    ```
    expect(events.emit.calls.argsFor(0)[1]).toBe('WARNING: Applications for platform atari can not be built on this OS - darwin.');
    
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by purplecabbage <gi...@git.apache.org>.
Github user purplecabbage commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127039183
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    This test will always fail somewhere ... currently failing on Travis because the OS is `linux` and not `darwin` and also failing on Appveyor where process.platform is `win32`
    Isn't it enough to just test that the call was a 'warning' and started with 'WARNING: Applications for platform' ?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124878443
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    --- End diff --
    
    `fail('addHelper success handler unexpectedly invoked');`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124878766
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    --- End diff --
    
    Don't think you need these two spyOn's anymore since they are inline requires


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124881302
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    --- End diff --
    
    can you do a `expect(fetch_mock).toHaveBeenCalled()` or even a `toHaveBeenCalledWith()` with some args if that makes sense


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124871034
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    --- End diff --
    
    I would move this spyOn into a before each since you use it for various tests


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127032404
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    I think we want to avoid using the `.calls` api. The `linux` vs `darwin` error makes sense. Travis runs linux, macs are darwin. Maybe using string matching like you did earlier in the file `expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));`. Obviously change the matching string to what the error should be. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124894106
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            xit('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_addHelper.installPluginsForNewPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should save the platform metadata', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_metadata.save).toHaveBeenCalledWith('/some/path', 'atari', undefined);
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should write out the version of platform just added/updated to config.xml if the save option is provided', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true}).then(function(result) {
    +                    expect(cfg_parser_mock.prototype.removeEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.addEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.write).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            describe('if the project contains a package.json', function () {
    +                beforeEach(function () {
    +                    var pkgJsonEmpty = {};
    +                    //spy for package.json to exist
    +                    fs.existsSync.and.callFake(function(filePath) {
    +                        if(path.basename(filePath) === 'package.json') {
    +                            return true;
    +                        } else {
    +                            return false;
    +                        }
    +                    });
    +                    //require packge.json object
    +                    spyOn(cordova_util, 'requireNoCache').and.returnValue(pkgJsonEmpty);
    +                });
    +
    +                xit('should write out the platform just added/updated to the cordova.platforms property of package.json',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should only write the package.json file if it was modified', function (done) {
    +                    var pkgJsonFull = { 'cordova': {'platforms': ['atari']}};
    +                    cordova_util.requireNoCache.and.returnValue(pkgJsonFull);
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).not.toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should file the after_platform_* hook',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(hooks_mock.fire).toHaveBeenCalledWith( 'before_platform_add', Object({ save: true, searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +        });
    +    });
    +    describe('downloadPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(Q, 'reject').and.callThrough();
    +            platform_addHelper.downloadPlatform.and.callThrough();
    +        });
    +        describe('errors', function () {
    +            it('should reject the promise should fetch fail', function (done) {
    +                fetch_mock.and.returnValue(Q.reject('fetch has failed, rejecting promise'));
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '67', {fetch: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(e.message).toContain('fetch has failed, rejecting promise');
    +                }).done(done);
    +            });
    +
    +            it('should reject the promise should lazy_load.git_clone fail', function (done) {
    +                spyOn(events, 'emit');
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(false);
    +                spyOn(lazy_load, 'git_clone').and.callThrough();
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(events.emit.calls.argsFor(2)[1].toString()).toContain('Cloning failed. Let\'s try handling it as a tarball');
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should lazy_load.based_on_config fail', function (done) {
    +                spyOn(gitclone, 'clone').and.callThrough();
    +                spyOn(lazy_load, 'git_clone').and.returnValue(true);
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(false);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(Q.reject.calls.allArgs().toString()).toContain('Failed to fetch platform android@https://github.com/apache/cordova-android');
    +                    expect(lazy_load.based_on_config).not.toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should both git_clone and based_on_config fail after the latter was fallen back on', function (done) {
    +                spyOn(lazy_load, 'git_clone').and.returnValue(Q.reject('git_clone failed'));
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(Q.reject('based_on_config failed'));
    +                cordova_util.isUrl.and.returnValue(true);
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +        });
    +        describe('happy path', function () {
    +            it('should invoke cordova-fetch if fetch was provided as an option', function (done) {
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '6.0.0', {fetch: true}).then(function () {
    +                    expect(fetch_mock).toHaveBeenCalledWith('cordova-android@6.0.0', projectRoot, Object({ fetch: true }));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            });
    +
    +            it('should invoke lazy_load.git_clone if the version to download is a URL', function (done) {
    +                spyOn(lazy_load, 'git_clone').and.callThrough();
    +                spyOn(gitclone, 'clone').and.returnValue(true);
    +                spyOn(events, 'emit');
    +                fetch_mock.and.returnValue(true);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit.calls.argsFor(0)[1]).toBe('git cloning: https://github.com/apache/cordova-android');
    +                    expect(cordova_util.isUrl).toHaveBeenCalledWith('https://github.com/apache/cordova-android');
    +                    expect(lazy_load.git_clone).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +
    +            it('should attempt to lazy_load.based_on_config if lazy_load.git_clone fails', function (done) {
    +                spyOn(events, 'emit');
    +                spyOn(lazy_load, 'based_on_config');
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('"git" command line tool is not installed: make sure it is accessible on your PATH.');
    +                    expect(events.emit.calls.argsFor(2)[1]).toBe('Cloning failed. Let\'s try handling it as a tarball');
    +                    expect(lazy_load.based_on_config).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +            
    +            it('should by default attempt to lazy_load.based_on_config', function (done) {
    +                spyOn(lazy_load, 'based_on_config');
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '6.0.0', {save:true}).then(function () {
    +                    expect(lazy_load.based_on_config).toHaveBeenCalledWith('/some/path', 'android@6.0.0', Object({ save: true }));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +
    +            it('should pass along a libDir argument to getPlatformDetailsFromDir on a successful platform download', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save:true}).then(function () {
    +                    expect(require('../../../src/cordova/platform/index').getPlatformDetailsFromDir).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +        });
    +    });
    +    describe('installPluginsForNewPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(events, 'emit');
    +            spyOn(fetch_metadata, 'get_fetch_metadata');
    +            spyOn(plugman, 'install').and.returnValue(Q());
    +            platform_addHelper.installPluginsForNewPlatform.and.callThrough();
    +        });
    +
    +        it('should immediately return if there are no plugins to install into the platform', function (done) {
    +            platform_addHelper.installPluginsForNewPlatform('android', projectRoot).then(function () {
    +                expect(plugman.install).not.toHaveBeenCalled();
    +            }).fail(function (e) {
    +                fail('fail handler unexpectedly invoked');
    +            }).done(done);
    +        });
    +
    +        it('should invoke plugman.install, giving correct platform, plugin and other arguments', function (done) {
    +            spyOn(cordova_util, 'findPlugins').and.returnValue(['cordova-plugin-whitelist']);
    +            fetch_metadata.get_fetch_metadata.and.returnValue({ });
    +            platform_addHelper.installPluginsForNewPlatform('browser', projectRoot, {save:true , fetch:true}).then(function () {
    +                expect(plugman.install).toHaveBeenCalled();
    +                expect(events.emit.calls.argsFor(0)[1]).toContain('Installing plugin "cordova-plugin-whitelist" following successful platform add of browser');
    +            }).fail(function (e) {
    +                fail('fail handler unexpectedly invoked');
    +            }).done(done);
    +        });
    +
    +        it('should include any plugin variables as options when invoking plugman install', function (done) {
    +            spyOn(cordova_util, 'findPlugins').and.returnValue(['cordova-plugin-camera']);
    +            fetch_metadata.get_fetch_metadata.and.returnValue({ source: {}, variables: {} });
    +            platform_addHelper.installPluginsForNewPlatform('browser', projectRoot, {save:true , fetch:true}).then(function () {
    +                expect(plugman.install).toHaveBeenCalled();
    +                expect(events.emit.calls.argsFor(1)[1]).toContain('Found variables for "cordova-plugin-camera". Processing as cli_variables.');
    --- End diff --
    
    toHaveBeenCalledWith


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124893454
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            xit('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_addHelper.installPluginsForNewPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should save the platform metadata', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_metadata.save).toHaveBeenCalledWith('/some/path', 'atari', undefined);
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should write out the version of platform just added/updated to config.xml if the save option is provided', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true}).then(function(result) {
    +                    expect(cfg_parser_mock.prototype.removeEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.addEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.write).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            describe('if the project contains a package.json', function () {
    +                beforeEach(function () {
    +                    var pkgJsonEmpty = {};
    +                    //spy for package.json to exist
    +                    fs.existsSync.and.callFake(function(filePath) {
    +                        if(path.basename(filePath) === 'package.json') {
    +                            return true;
    +                        } else {
    +                            return false;
    +                        }
    +                    });
    +                    //require packge.json object
    +                    spyOn(cordova_util, 'requireNoCache').and.returnValue(pkgJsonEmpty);
    +                });
    +
    +                xit('should write out the platform just added/updated to the cordova.platforms property of package.json',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should only write the package.json file if it was modified', function (done) {
    +                    var pkgJsonFull = { 'cordova': {'platforms': ['atari']}};
    +                    cordova_util.requireNoCache.and.returnValue(pkgJsonFull);
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(fs.writeFileSync).not.toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                xit('should file the after_platform_* hook',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true}).then(function(result) {
    +                        expect(hooks_mock.fire).toHaveBeenCalledWith( 'before_platform_add', Object({ save: true, searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +        });
    +    });
    +    describe('downloadPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(Q, 'reject').and.callThrough();
    +            platform_addHelper.downloadPlatform.and.callThrough();
    +        });
    +        describe('errors', function () {
    +            it('should reject the promise should fetch fail', function (done) {
    +                fetch_mock.and.returnValue(Q.reject('fetch has failed, rejecting promise'));
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '67', {fetch: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(e.message).toContain('fetch has failed, rejecting promise');
    +                }).done(done);
    +            });
    +
    +            it('should reject the promise should lazy_load.git_clone fail', function (done) {
    +                spyOn(events, 'emit');
    +                spyOn(lazy_load, 'based_on_config').and.returnValue(false);
    --- End diff --
    
    I'd suggest moving these lazy_load spyOns into the beforeEach on line 328. Then just set the value as needed in the it via `lazy_load.based_on_config.and.returnValue(false);`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by audreyso <gi...@git.apache.org>.
Github user audreyso commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r127066391
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    Hmm string matching does not seem to work in this case. It worked for the 1st test b/c the error message is:
     
    ```
    events.emit(platform + ' has been deprecated and will be removed in the next major release of cordova.’);
    ```
    (There's no warn, log, verbose, etc in this message).
    
    
    But events.emit('warning', msg); is not able to be used with stringMatching unless you remove ‘warning’ so it’s like this:
    
    ```
    events.emit(msg);
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124881373
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    --- End diff --
    
    don't need these spyOn's


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124880319
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    --- End diff --
    
    use `toHaveBeenCalledWith()`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124879465
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    --- End diff --
    
    So I think you don't need to `xit` all of these tests. You probably want one or two `xit` tests for the ones that actually hit the inline require of `prepare`. I think you can skip prepare by setting `opts.restoring` to true. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r126842836
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    --- End diff --
    
    why did you decide to comment on the events.emit check?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124863854
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    --- End diff --
    
    don't need these comments I take it. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r126843121
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            it('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform], {restoring:true}).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform], {restoring:true}).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {restoring:true}).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {restoring:true}).then(function() {
    +                    expect(events.emit).toHaveBeenCalledWith('verbose', 'Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true, restoring:true}).then(function() {
    +                    expect(fetch_mock).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +
    +            it('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true, restoring:true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            it('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios'], {restoring:true}).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    --- End diff --
    
    maybe leave a comment above this explaining why it is `xit`. 
    
    `preparePlatforms` can't be spied on as it is dynamically required due to circular references.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r126844076
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,439 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    var package_json_mock;
    +    package_json_mock = jasmine.createSpyObj('package json mock', ['cordova', 'dependencies']);
    +    package_json_mock.dependencies = {};
    +    package_json_mock.cordova = {};
    +
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        spyOn(events, 'emit');
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +        spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function (done) {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +        fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(cordova_util.hostSupports).toHaveBeenCalled();
    +                //expect(events.emit).toHaveBeenCalledWith('warning', 'WARNING: Applications for platform atari can not be built on this OS - darwin.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            it('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform], {restoring:true}).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform], {restoring:true}).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {restoring:true}).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {restoring:true}).then(function() {
    +                    expect(events.emit).toHaveBeenCalledWith('verbose', 'Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            it('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true, restoring:true}).then(function() {
    +                    expect(fetch_mock).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +
    +            it('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true, restoring:true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            it('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios'], {restoring:true}).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +
    +            describe('when the restoring option is not provided', function () {
    +                xit('should invoke preparePlatforms twice (?!?), once before installPluginsForNewPlatforms and once after... ?!', function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true}).then(function(result) {
    +                        expect(prepare.preparePlatforms).toHaveBeenCalledWith([ 'atari' ], '/some/path', Object({ searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +
    +            it('should invoke the installPluginsForNewPlatforms method in the platform-add case', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true, restoring:true}).then(function(result) {
    +                    expect(platform_addHelper.installPluginsForNewPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            it('should save the platform metadata', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, fetch: true, restoring:true}).then(function(result) {
    +                    expect(platform_metadata.save).toHaveBeenCalledWith('/some/path', 'atari', undefined);
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            it('should write out the version of platform just added/updated to config.xml if the save option is provided', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, restoring:true}).then(function(result) {
    +                    expect(cfg_parser_mock.prototype.removeEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.addEngine).toHaveBeenCalled();
    +                    expect(cfg_parser_mock.prototype.write).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            describe('if the project contains a package.json', function () {
    +                it('should write out the platform just added/updated to the cordova.platforms property of package.json',function (done) {
    +                    fs.existsSync.and.callFake(function(filePath) {
    +                        if(path.basename(filePath) === 'package.json') {
    +                            return true;
    +                        } else {
    +                            return false;
    +                        }
    +                    });
    +                    package_json_mock.cordova = {'platforms':['ios']};
    +                    cordova_util.requireNoCache.and.returnValue(package_json_mock);
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['android'], {save: true, restoring:true}).then(function(result) {
    +                        expect(fs.writeFileSync).toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                it('should only write the package.json file if it was modified', function (done) {
    +                    package_json_mock.cordova = {'platforms':['ios']};
    +                    cordova_util.requireNoCache.and.returnValue(package_json_mock);
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, restoring:true}).then(function(result) {
    +                        expect(fs.writeFileSync).not.toHaveBeenCalled();
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +
    +                it('should file the after_platform_* hook',function (done) {
    +                    platform_addHelper('add', hooks_mock, projectRoot, ['atari'], {save: true, restoring:true}).then(function(result) {
    +                        expect(hooks_mock.fire).toHaveBeenCalledWith( 'before_platform_add', Object({ save: true, restoring: true, searchpath: undefined }));
    +                    }).fail(function (err) {
    +                        fail('unexpected failure handler invoked!');
    +                        console.error(err);
    +                    }).done(done);
    +                });
    +            });
    +        });
    +    });
    +    describe('downloadPlatform', function () {
    +        beforeEach(function () {
    +            spyOn(Q, 'reject').and.callThrough();
    +            spyOn(lazy_load, 'based_on_config');
    +            spyOn(lazy_load, 'git_clone').and.callThrough();
    +            platform_addHelper.downloadPlatform.and.callThrough();
    +        });
    +        describe('errors', function () {
    +            it('should reject the promise should fetch fail', function (done) {
    +                fetch_mock.and.returnValue(Q.reject('fetch has failed, rejecting promise'));
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '67', {fetch: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(e.message).toContain('fetch has failed, rejecting promise');
    +                }).done(done);
    +            });
    +
    +            it('should reject the promise should lazy_load.git_clone fail', function (done) {
    +                lazy_load.based_on_config.and.returnValue(false);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(events.emit).toHaveBeenCalledWith('verbose', 'Cloning failed. Let\'s try handling it as a tarball');
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should lazy_load.based_on_config fail', function (done) {
    +                spyOn(gitclone, 'clone').and.callThrough();
    +                lazy_load.git_clone.and.returnValue(true);
    +                lazy_load.based_on_config.and.returnValue(false);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                    expect(lazy_load.based_on_config).not.toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +
    +            it('should reject the promise should both git_clone and based_on_config fail after the latter was fallen back on', function (done) {
    +                lazy_load.git_clone.and.returnValue(Q.reject('git_clone failed'));
    +                lazy_load.based_on_config.and.returnValue(Q.reject('based_on_config failed'));
    +                cordova_util.isUrl.and.returnValue(true);
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    fail('success handler unexpectedly invoked');
    +                }).fail(function (e) {
    +                    expect(Q.reject).toHaveBeenCalled();
    +                }).done(done);
    +            },60000);
    +        });
    +        describe('happy path', function () {
    +            it('should invoke cordova-fetch if fetch was provided as an option', function (done) {
    +                fetch_mock.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', '6.0.0', {fetch: true}).then(function () {
    +                    expect(fetch_mock).toHaveBeenCalledWith('cordova-android@6.0.0', projectRoot, Object({ fetch: true }));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            });
    +
    +            it('should invoke lazy_load.git_clone if the version to download is a URL', function (done) {
    +                lazy_load.git_clone.and.callThrough();
    +                spyOn(gitclone, 'clone').and.returnValue(true);
    +                fetch_mock.and.returnValue(true);
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit).toHaveBeenCalledWith('log', 'git cloning: https://github.com/apache/cordova-android');
    +                    expect(cordova_util.isUrl).toHaveBeenCalledWith('https://github.com/apache/cordova-android');
    +                    expect(lazy_load.git_clone).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +
    +            it('should attempt to lazy_load.based_on_config if lazy_load.git_clone fails', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                platform_addHelper.downloadPlatform(projectRoot, 'android', 'https://github.com/apache/cordova-android', {save: true}).then(function () {
    +                    expect(events.emit).toHaveBeenCalledWith('verbose', '"git" command line tool is not installed: make sure it is accessible on your PATH.');
    +                    expect(events.emit).toHaveBeenCalledWith('verbose','Cloning failed. Let\'s try handling it as a tarball');
    +                    expect(lazy_load.based_on_config).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                }).done(done);
    +            },60000);
    +            
    +            it('should by default attempt to lazy_load.based_on_config', function (done) {
    +                // spyOn(lazy_load, 'based_on_config');
    --- End diff --
    
    done need this comment


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


[GitHub] cordova-lib pull request #573: CB-12361 : updated addHelper tests

Posted by stevengill <gi...@git.apache.org>.
Github user stevengill commented on a diff in the pull request:

    https://github.com/apache/cordova-lib/pull/573#discussion_r124891852
  
    --- Diff: spec/cordova/platform/addHelper.spec.js ---
    @@ -16,34 +16,459 @@
     */
     /* eslint-env jasmine */
     
    +var path = require('path');
    +var fs = require('fs');
    +var Q = require('q');
    +var shell = require('shelljs');
    +var events = require('cordova-common').events;
    +var rewire = require('rewire');
    +var platform_addHelper = rewire('../../../src/cordova/platform/addHelper');
    +var platform_module = require('../../../src/cordova/platform');
    +var platform_metadata = require('../../../src/cordova/platform_metadata');
    +var cordova_util = require('../../../src/cordova/util');
    +var cordova_config = require('../../../src/cordova/config');
    +var plugman = require('../../../src/plugman/plugman');
    +var fetch_metadata = require('../../../src/plugman/util/metadata');
    +var lazy_load = require('../../../src/cordova/lazy_load');
    +// require module here
    +// spy on it and return 
    +var cordova = require('../../../src/cordova/cordova');
    +var prepare = require('../../../src/cordova/prepare');
    +var gitclone = require('../../../src/gitclone');
    +var fail;
    +
     describe('cordova/platform/addHelper', function () {
    +    var projectRoot = '/some/path';
    +    // These _mock and _revert_mock objects use rewire as the modules these mocks replace
    +    // during testing all return functions, which we cannot spy on using jasmine.
    +    // Thus, we replace these modules inside the scope of addHelper.js using rewire, and shim
    +    // in these _mock test dummies. The test dummies themselves are constructed using
    +    // jasmine.createSpy inside the first beforeEach.
    +    var cfg_parser_mock = function () {};
    +    var cfg_parser_revert_mock;
    +    var hooks_mock;
    +    var platform_api_mock;
    +    var fetch_mock;
    +    var fetch_revert_mock;
    +    var prepare_mock;
    +    var prepare_revert_mock;
    +    var fake_platform = {
    +        'platform': 'atari'
    +    };
    +    beforeEach(function () {
    +        hooks_mock = jasmine.createSpyObj('hooksRunner mock', ['fire']);
    +        hooks_mock.fire.and.returnValue(Q());
    +        cfg_parser_mock.prototype = jasmine.createSpyObj('config parser mock', ['write', 'removeEngine', 'addEngine', 'getHookScripts']);
    +        cfg_parser_revert_mock = platform_addHelper.__set__('ConfigParser', cfg_parser_mock);
    +        fetch_mock = jasmine.createSpy('fetch mock').and.returnValue(Q());
    +        fetch_revert_mock = platform_addHelper.__set__('fetch', fetch_mock);
    +        prepare_mock = jasmine.createSpy('prepare mock').and.returnValue(Q());
    +        prepare_mock.preparePlatforms = jasmine.createSpy('preparePlatforms mock').and.returnValue(Q());
    +        prepare_revert_mock = platform_addHelper.__set__('prepare', prepare_mock);
    +        spyOn(shell, 'mkdir');
    +        spyOn(fs, 'existsSync').and.returnValue(false);
    +        spyOn(fs, 'writeFileSync');
    +        spyOn(cordova_util, 'projectConfig').and.returnValue(path.join(projectRoot, 'config.xml'));
    +        spyOn(cordova_util, 'isDirectory').and.returnValue(false);
    +        spyOn(cordova_util, 'fixRelativePath').and.callFake(function (input) { return input; });
    +        spyOn(cordova_util, 'isUrl').and.returnValue(false);
    +        spyOn(cordova_util, 'hostSupports').and.returnValue(true);
    +        spyOn(cordova_util, 'removePlatformPluginsJson');
    +        spyOn(cordova_config, 'read').and.returnValue({});
    +        // Fake platform details we will use for our mocks, returned by either
    +        // getPlatfromDetailsFromDir (in the local-directory case), or
    +        // downloadPlatform (in every other case)
    +        spyOn(platform_module, 'getPlatformDetailsFromDir').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'downloadPlatform').and.returnValue(Q(fake_platform));
    +        spyOn(platform_addHelper, 'getVersionFromConfigFile').and.returnValue(false);
    +        spyOn(platform_addHelper, 'installPluginsForNewPlatform').and.returnValue(Q());
    +        platform_api_mock = jasmine.createSpyObj('platform api mock', ['createPlatform', 'updatePlatform']);
    +        platform_api_mock.createPlatform.and.returnValue(Q());
    +        platform_api_mock.updatePlatform.and.returnValue(Q());
    +        spyOn(cordova_util, 'getPlatformApiFunction').and.returnValue(platform_api_mock);
    +        spyOn(platform_metadata, 'save');
    +    });
    +    afterEach(function () {
    +        cfg_parser_revert_mock();
    +        fetch_revert_mock();
    +        prepare_revert_mock();
    +    });
         describe('error/warning conditions', function () {
    -        it('should require specifying at least one platform');
    -        it('should warn if host OS does not support the specified platform');
    +        it('should require specifying at least one platform', function (done) {
    +            platform_addHelper('add', hooks_mock).then(function () {
    +                fail('addHelper success handler unexpectedly invoked');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('No platform specified.');
    +            }).done(done);
    +        });
    +
    +        it('should log if host OS does not support the specified platform', function () {
    +            cordova_util.hostSupports.and.returnValue(false);
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(events.emit.calls.mostRecent().args[1]).toContain('can not be built on this OS');
    +        });
    +
    +        it('should throw if platform was already added before adding', function (done) {
    +            fs.existsSync.and.returnValue('/some/path/platforms/ios');
    +            spyOn(cordova_util, 'requireNoCache').and.returnValue(true);
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('already added.');
    +            }).done(done);
    +        });
    +
    +        it('should throw if platform was not added before updating', function(done) {
    +            platform_addHelper('update', hooks_mock, projectRoot, ['atari']).then(function () {
    +                fail('addHelper should throw error');
    +            }).fail(function (e) {
    +                expect(e.message).toContain('Platform "atari" is not yet added. See `cordova platform list`.');
    +            }).done(done);
    +        });
         });
         describe('happy path (success conditions)', function () {
    -        it('should fire the before_platform_* hook');
    -        it('should warn about deprecated platforms');
    -        /*
    -         * first "leg" (`then`) of the promise is platform "spec" support:
    -         * - tries to infer spec from either package.json or config.xml
    -         * - defaults to pinned version for platform.
    -         * - downloads the platform, passing in spec.
    -         * --> how to test: spy on downloadPlatform, validate spec passed.
    -         * --> should mock out downloadPlatform completely for all happy path tests. this would short-circuit the first addHelper promise `then`.
    -         * second "leg" (`then`) of the promise:
    -         * - checks for already-added or not-added platform requirements. TODO: couldnt we move this up to before downloading, to the initial error/warning checks?
    -         * - invokes platform api createPlatform or updatePlatform
    -         * - if not restoring, runs a `prepare`
    -         * - if just added, installsPluginsForNewPlatform (TODO for fil: familiarize yourself why not just a regular "install plugin for platform" - why the 'newPlatform' API?)
    -         * - if not restoring, run a prepare. TODO: didnt we just do this? we just installed plugins, so maybe its needed, but couldnt we just run a single prepare after possibly installing plugins?
    -         * third `then`:
    -         * - save particular platform version installed to platform metadata.
    -         * - if autosaving or opts.save is provided, write platform to config.xml
    -         * fourth `then`:
    -         * - save added platform to package.json if exists.
    -         * fifth `then`:
    -         * - fire after_platform_add/update hook
    -         */
    +        it('should fire the before_platform_* hook', function () {
    +            platform_addHelper('add', hooks_mock, projectRoot, ['atari']);
    +            expect(hooks_mock.fire).toHaveBeenCalledWith('before_platform_add', jasmine.any(Object));
    +        });
    +
    +        it('should warn about using deprecated platforms', function (done) {
    +            spyOn(events, 'emit');
    +            platform_addHelper('add', hooks_mock, projectRoot, ['ubuntu', 'blackberry10']);
    +            process.nextTick(function () {
    +                expect(events.emit).toHaveBeenCalledWith(jasmine.stringMatching(/has been deprecated/));
    +                done();
    +            });
    +        });
    +        describe('platform spec inference', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should retrieve platform details from directories-specified-as-platforms using getPlatformDetailsFromDir', function (done) {
    +                cordova_util.isDirectory.and.returnValue(true);
    +                var directory_to_platform = '/path/to/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [directory_to_platform]).then(function () {
    +                    expect(platform_module.getPlatformDetailsFromDir).toHaveBeenCalledWith(directory_to_platform, null);
    +                    expect(platform_addHelper.downloadPlatform).not.toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should retrieve platform details from URLs-specified-as-platforms using downloadPlatform', function (done) {
    +                cordova_util.isUrl.and.returnValue(true);
    +                var url_to_platform = 'http://github.com/apache/cordova-atari';
    +                platform_addHelper('add', hooks_mock, projectRoot, [url_to_platform]).then(function () {
    +                    expect(platform_addHelper.downloadPlatform).toHaveBeenCalledWith(projectRoot, null, url_to_platform, jasmine.any(Object));
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should attempt to retrieve from config.xml if exists and package.json does not', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['atari']).then(function() {
    +                    expect(platform_addHelper.getVersionFromConfigFile).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should fall back to using pinned version if both package.json and config.xml do not specify it', function (done) {
    +                spyOn(events,'emit');
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios']).then(function() {
    +                    expect(events.emit.calls.argsFor(1)[1]).toBe('Grabbing pinned version.');
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke fetch if provided as an option and spec is a directory', function (done) {
    +                cordova_util.isDirectory.and.returnValue(projectRoot);
    +                cordova_util.fixRelativePath.and.returnValue(projectRoot);
    +                spyOn(path, 'resolve').and.callThrough();
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save:true, fetch: true}).then(function() {
    +                    expect(path.resolve).toHaveBeenCalled();
    +                }).fail(function (e) {
    +                    fail('fail handler unexpectedly invoked');
    +                    console.error(e);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            xit('should invoke the createPlatform platform API method when adding a platform, providing destination location, parsed config file and platform detail options as arguments', function (done) {
    +                platform_addHelper('add', hooks_mock, projectRoot, ['ios'], {save: true, fetch: true}).then(function(result) {
    +                    expect(platform_api_mock.createPlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +
    +            xit('should invoke the update platform API method when updating a platform, providing destination location and plaform detail options as arguments', function(done) {
    +                spyOn(cordova_util, 'requireNoCache').and.returnValue({});
    +                cordova_util.isDirectory.and.returnValue(true);
    +                fs.existsSync.and.returnValue(true);
    +                platform_addHelper('update', hooks_mock, projectRoot, ['ios']).then(function(result) {
    +                    expect(platform_api_mock.updatePlatform).toHaveBeenCalled();
    +                }).fail(function (err) {
    +                    fail('unexpected failure handler invoked!');
    +                    console.error(err);
    +                }).done(done);
    +            });
    +        });
    +
    +        describe('after platform api invocation', function () {
    +            beforeEach(function () {
    +                spyOn(cordova, 'prepare').and.returnValue(Q());
    +                spyOn(prepare, 'preparePlatforms').and.returnValue(Q());
    +            });
    +
    +            describe('when the restoring option is not provided', function () {
    --- End diff --
    
    This one you need to keep `xit` since restoring option is not provided


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org