define([
    'bitbucket/util/state',
    'bitbucket/internal/model/page-state'
], function(
    state,
    pageState
) {
    'use strict';

    module('util-state', {
        afterEach: function () {
            // ensure other tests that use pageState have the initial state
            pageState.setProject(undefined);
            pageState.setRevisionRef(undefined);
        }
    });

    test('Documented API is available', function() {
        equal(typeof state.getCurrentUser, 'function');
        equal(typeof state.getProject, 'function');
        equal(typeof state.getRepository, 'function');
        equal(typeof state.getPullRequest, 'function');
        equal(typeof state.getRef, 'function');
        equal(typeof state.getCommit, 'function');
        equal(typeof state.getFilePath, 'function');
    });

    test('Extended properties can be added to the API', function() {
        pageState.extend('sourceRepository');

        try {
            equal(typeof state.getSourceRepository, 'function');
        } finally {
            delete state.getSourceRepository;
            delete pageState.getSourceRepository;
            delete pageState.setSourceRepository;
        }
    });

    test('returns primitive values', function() {
        [
            [undefined, false], // until 4.0, then undefined
            [null, false], // until 4.0, then null
            [false, false],
            [true, true],
            [0, 0],
            [1, 1],
            ['', ''],
            ['a', 'a']
        ].forEach(function(pair) {
            var input = pair[0];
            var output = pair[1];

            pageState.setProject(input);
            strictEqual(state.getProject(), output);
        });
    });

    test('returns toJSON result of objects', function() {
        var expected = { a: 1 };
        pageState.setProject({
            toJSON : function() {
                return expected;
            }
        });

        deepEqual(state.getProject(), expected);
    });

    test('Returns a deep copy', function() {
        var expected = { nested: { a : 1 } };
        pageState.setProject(expected);
        deepEqual(state.getProject(), expected);
        notEqual(state.getProject(), expected);
        notEqual(state.getProject().nested, expected.nested);
    });

    test('revisionRef renamed to Ref', function() {
        var expected = { a: 1 };
        pageState.setRevisionRef(expected);

        deepEqual(state.getRef(), expected);
    });

    test('returns a commit', function() {
        var expected = { a: 1 };
        pageState.setCommit(expected);

        deepEqual(state.getCommit(), expected);
    });
});