/*
 *
 * 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("exist 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(require,
                {}, {
                    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");
        });
    });
});
