describe("Service: AngularViewArray", function() {
  var angularViewArray;

  beforeEach(module('quay'));

  beforeEach(inject(function($injector) {
    angularViewArray = $injector.get('AngularViewArray');
  }));

  describe("create", function() {

    it("returns a ViewArray object", function() {
      var viewArray = angularViewArray.create();

      expect(viewArray).toBeDefined();
    });

    describe("returned ViewArray object", function() {
      var viewArray;

      beforeEach(function() {
        viewArray = angularViewArray.create();
      });

      describe("constructor", function() {
        // TODO
      });

      describe("length", function() {

        it("returns the number of entries", function() {
          viewArray.entries = [{}, {}, {}];

          expect(viewArray.length()).toEqual(viewArray.entries.length);
        });
      });

      describe("get", function() {

        it("returns the entry at a given index", function() {
          var index = 8;
          viewArray.entries = new Array(10);
          viewArray.entries[index] = 3;

          expect(viewArray.get(index)).toEqual(viewArray.entries[index]);
        });
      });

      describe("push", function() {

        it("adds given element to the end of entries", function() {
          var element = 3;
          var originalLength = viewArray.length();
          viewArray.push(element);

          expect(viewArray.entries.length).toEqual(originalLength + 1);
          expect(viewArray.get(originalLength)).toEqual(element);
        });

        it("sets 'hasEntries' to true", function() {
          viewArray.push(2);

          expect(viewArray.hasEntries).toBe(true);
        });

        it("starts timer if 'isVisible' is true", function() {
          spyOn(viewArray, "startTimer_").and.returnValue();
          viewArray.isVisible = true;
          viewArray.push(2);

          expect(viewArray.startTimer_).toHaveBeenCalled();
        });

        it("does not start timer if 'isVisible' is false", function() {
          spyOn(viewArray, "startTimer_").and.returnValue();
          viewArray.isVisible = false;
          viewArray.push(2);

          expect(viewArray.startTimer_).not.toHaveBeenCalled();
        });
      });

      describe("toggle", function() {

        it("sets 'isVisible' to false if currently true", function() {
          viewArray.isVisible = true;
          viewArray.toggle();

          expect(viewArray.isVisible).toBe(false);
        });

        it("sets 'isVisible' to true if currently false", function() {
          viewArray.isVisible = false;
          viewArray.toggle();

          expect(viewArray.isVisible).toBe(true);
        });
      });

      describe("setVisible", function() {

        it("sets 'isVisible' to false if given false", function() {
          viewArray.setVisible(false);

          expect(viewArray.isVisible).toBe(false);
        });

        it("sets 'visibleEntries' to empty array if given false", function() {
          viewArray.setVisible(false);

          expect(viewArray.visibleEntries.length).toEqual(0);
        });

        it("shows additional entries if given true", function() {
          spyOn(viewArray, "showAdditionalEntries_").and.returnValue();
          viewArray.setVisible(true);

          expect(viewArray.showAdditionalEntries_).toHaveBeenCalled();
        });

        it("does not show additional entries if given false", function() {
          spyOn(viewArray, "showAdditionalEntries_").and.returnValue();
          viewArray.setVisible(false);

          expect(viewArray.showAdditionalEntries_).not.toHaveBeenCalled();
        });

        it("starts timer if given true", function() {
          spyOn(viewArray, "startTimer_").and.returnValue();
          viewArray.setVisible(true);

          expect(viewArray.startTimer_).toHaveBeenCalled();
        });

        it("stops timer if given false", function() {
          spyOn(viewArray, "stopTimer_").and.returnValue();
          viewArray.setVisible(true);

          expect(viewArray.stopTimer_).toHaveBeenCalled();
        });
      });
    });
  });
});