/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

describe("require + define", function () {
    it("exists off of cordova", function () {
        var cordova = require('cordova');
        expect(cordova.require).toBeDefined();
        expect(cordova.define).toBeDefined();
    });

    describe("when defining", function () {
        it("can define and remove module", function () {
            define("a", jasmine.createSpy());
            define.remove("a");
        });

        it("can remove a module that doesn't exist", function () {
            define.remove("can't touch this");
        });

        it("throws an error the module already exists", function () {
            expect(function () {
                define("cordova", function () {});
            }).toThrow("module cordova already defined");
        });

        it("doesn't call the factory method when defining", function () {
            var factory = jasmine.createSpy();
            define("ff", factory);
            expect(factory).not.toHaveBeenCalled();
        });
    });

    describe("when requiring", function () {
        it("throws an exception when module doesn't exist", function () {
            expect(function () {
                require("your mom");
            }).toThrow("module your mom not found");
        });

        it("throws an exception when modules depend on each other", function () {
            define("ModuleA", function(require, exports, module) {
                require("ModuleB");
            });
            define("ModuleB", function(require, exports, module) {
                require("ModuleA");
            });
            expect(function () {
                require("ModuleA");
            }).toThrow("Cycle in require graph: ModuleA->ModuleB->ModuleA");
            define.remove("ModuleA");
            define.remove("ModuleB");
        });

        it("throws an exception when a cycle of requires occurs", function () {
            define("ModuleA", function(require, exports, module) {
                require("ModuleB");
            });
            define("ModuleB", function(require, exports, module) {
                require("ModuleC");
            });
            define("ModuleC", function(require, exports, module) {
                require("ModuleA");
            });
            expect(function () {
                require("ModuleA");
            }).toThrow("Cycle in require graph: ModuleA->ModuleB->ModuleC->ModuleA");
            define.remove("ModuleA");
            define.remove("ModuleB");
            define.remove("ModuleC");
        });

        it("calls the factory method when requiring", function () {
            var factory = jasmine.createSpy();
            define("dino", factory);
            require("dino");

            expect(factory).toHaveBeenCalledWith(jasmine.any(Function),
                {}, {
                    id: "dino",
                    exports: {}
                });

            define.remove("dino");
        });

        it("returns the exports object", function () {
            define("a", function (require, exports, module) {
                exports.stuff = "asdf";
            });

            var v = require("a");
            expect(v.stuff).toBe("asdf");
            define.remove("a");
        });

        it("can use both the exports and module.exports object", function () {
            define("a", function (require, exports, module) {
                exports.a = "a";
                module.exports.b = "b";
            });

            var v = require("a");
            expect(v.a).toBe("a");
            expect(v.b).toBe("b");
            define.remove("a");
        });

        it("returns was is assigned to module.exports", function () {
            var Foo = function () { };
            define("a", function (require, exports, module) {
                module.exports = new Foo();
            });

            var v = require("a");
            expect(v instanceof Foo).toBe(true);
            define.remove("a");
        });

        it("has the id and exports values but not the factory on the module object", function () {
            var factory = function (require, exports, module) {
                expect(module.id).toBe("a");
                expect(module.exports).toBeDefined();
                expect(module.factory).not.toBeDefined();
            };

            define("a", factory);
            require("a");
        });

        it("can handle multiple defined modules that use cordova's unique handling of relative require paths", function () {
            define("plugin.ios.foo", function (require, exports, module) {
                module.exports = require("./bar") * 2;
            });
            define("plugin.ios.bar", function (require, exports, module) {
                module.exports = 2;
            });
            expect(require("plugin.ios.foo")).toEqual(4);
        });
    });
});
