/*
 *
 * 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('utils', function () {
    var utils = cordova.require('cordova/utils');

    describe('utils.arrayIndexOf', function () {
        it('Test#001 : should return -1 when not found', function () {
            expect(utils.arrayIndexOf([1, 2, 3], 4)).toBe(-1);
        });
        it('Test#002 : should return 0 for first item', function () {
            expect(utils.arrayIndexOf([1, 2, 3], 1)).toBe(0);
        });
        it('Test#003 : should return 2 for last item', function () {
            expect(utils.arrayIndexOf([1, 2, 3], 3)).toBe(2);
        });
        it('Test#004 : should return index of first occurance', function () {
            expect(utils.arrayIndexOf([1, 2, 1], 1)).toBe(0);
        });
    });

    describe('utils.arrayRemove', function () {
        it('Test#005 : should return true when removed.', function () {
            var a = [1, 2, 3];
            expect(utils.arrayRemove(a, 2)).toBe(true);
            expect(a).toEqual([1, 3]);
        });
        it('Test#006 : should return false when item was not there.', function () {
            var a = [1, 2, 3];
            expect(utils.arrayRemove(a, 4)).toBe(false);
            expect(a).toEqual([1, 2, 3]);
        });
        it('Test#007 : should remove only first occurance', function () {
            var a = [1, 2, 1];
            expect(utils.arrayRemove(a, 1)).toBe(true);
            expect(a).toEqual([2, 1]);
        });
    });

    describe('isArray', function () {
        it('Test#008 : should return true for [].', function () {
            var isArray = utils.isArray([]);
            expect(isArray).toBe(true);
        });
        it('Test#009 : should return true for new Array().', function () {
            var isArray = utils.isArray(new Array()); // eslint-disable-line no-array-constructor
            expect(isArray).toBe(true);
        });
        it('Test#010 : should return false for {}.', function () {
            var isArray = utils.isArray({});
            expect(isArray).toBe(false);
        });
    });

    describe('isDate', function () {
        it('Test#011 : should return true for new Date().', function () {
            var isDate = utils.isDate(new Date());
            expect(isDate).toBe(true);
        });
        it('Test#012 : should return false for {}.', function () {
            var isDate = utils.isDate({});
            expect(isDate).toBe(false);
        });
    });

    describe('when cloning', function () {
        it('Test#013 : can clone an array', function () {
            var orig = [1, 2, 3, {four: 4}, '5'];

            expect(utils.clone(orig)).toEqual(orig);
            expect(utils.clone(orig)).not.toBe(orig);
        });

        it('Test#014 : can clone null', function () {
            expect(utils.clone(null)).toBeNull();
        });

        it('Test#015 : can clone undefined', function () {
            expect(utils.clone(undefined)).not.toBeDefined();
        });

        it('Test#016 : can clone a function', function () {
            var f = function () { return 4; };
            expect(utils.clone(f)).toBe(f);
        });

        it('Test#017 : can clone a number', function () {
            expect(utils.clone(4)).toBe(4);
        });

        it('Test#018 : can clone a string', function () {
            expect(utils.clone('why')).toBe('why');
        });

        it('Test#19 : can clone a date', function () {
            var d = Date.now();
            expect(utils.clone(d)).toBe(d);
        });

        it('Test#020 : can clone an object', function () {

            var orig = {
                a: {
                    b: {
                        c: 'd'
                    }
                },
                e: 'f',
                g: 'unit'
            };
            var expected = {
                a: {
                    b: {
                        c: 'd'
                    }
                },
                e: 'f',
                g: 'unit'
            };

            expect(utils.clone(orig)).toEqual(expected);
        });
    });

    describe('when closing around a function', function () {
        it('Test#021 : calls the original function when calling the closed function', function () {
            var f = jasmine.createSpy();
            utils.close(null, f)();
            expect(f).toHaveBeenCalled();
        });

        it('Test#022 : uses the correct context for the closed function', function () {
            var context = {};
            utils.close(context, function () {
                expect(this).toBe(context);
            })();
        });

        it('Test#023 : passes the arguments to the closed function', function () {
            utils.close(null, function (arg) {
                expect(arg).toBe(1);
            })(1);
        });

        it('Test#024 : overrides the arguments when provided', function () {
            utils.close(null, function (arg) {
                expect(arg).toBe(42);
            }, [42])(16);
        });
    });

    it('Test#025 : can create a uuid', function () {
        var uuid = utils.createUUID();
        expect(uuid).toMatch(/^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/);
        expect(uuid).not.toEqual(utils.createUUID());
    });

});
