import { defaultValue } from "../../Source/Cesium.js"; import { Iso8601 } from "../../Source/Cesium.js"; import { JulianDate } from "../../Source/Cesium.js"; import { TimeInterval } from "../../Source/Cesium.js"; import { TimeIntervalCollection } from "../../Source/Cesium.js"; import { TimeStandard } from "../../Source/Cesium.js"; describe("Core/TimeIntervalCollection", function () { function defaultDataCallback(interval, index) { return index; } function iso8601ToJulianDateArray(iso8601Dates) { var julianDates = []; for (var i = 0; i < iso8601Dates.length; ++i) { julianDates[i] = JulianDate.fromIso8601(iso8601Dates[i]); } return julianDates; } function checkIntervals( intervals, julianDates, isStartIncluded, isStopIncluded, dataCallback ) { dataCallback = defaultValue(dataCallback, defaultDataCallback); var length = intervals.length; expect(length).toEqual(julianDates.length - 1); for (var i = 0; i < length; ++i) { var interval = intervals.get(i); expect(JulianDate.compare(interval.start, julianDates[i])).toEqual(0); expect(JulianDate.compare(interval.stop, julianDates[i + 1])).toEqual(0); expect(interval.isStartIncluded).toBe(i === 0 ? isStartIncluded : true); expect(interval.isStopIncluded).toBe( i === length - 1 ? isStopIncluded : false ); expect(interval.data).toEqual(dataCallback(interval, i)); } } function TestObject(value) { this.value = value; } TestObject.equals = function (left, right) { return left.value === right.value; }; TestObject.merge = function (left, right) { return new TestObject(left.value + right.value); }; it("constructing a default interval collection has expected property values.", function () { var intervals = new TimeIntervalCollection(); expect(intervals.length).toEqual(0); expect(intervals.start).toBeUndefined(); expect(intervals.stop).toBeUndefined(); expect(intervals.isStartIncluded).toEqual(false); expect(intervals.isStopIncluded).toEqual(false); expect(intervals.isEmpty).toEqual(true); expect(intervals.changedEvent).toBeDefined(); }); it("constructing an interval collection from array.", function () { var arg = [ new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }), new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }), ]; var intervals = new TimeIntervalCollection(arg); expect(intervals.length).toEqual(2); expect(intervals.start).toEqual(arg[0].start); expect(intervals.stop).toEqual(arg[1].stop); expect(intervals.isStartIncluded).toEqual(true); expect(intervals.isStopIncluded).toEqual(true); expect(intervals.isEmpty).toEqual(false); expect(intervals.changedEvent).toBeDefined(); }); it("isStartIncluded/isStopIncluded works.", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); expect(intervals.isStartIncluded).toBe(false); expect(intervals.isStopIncluded).toBe(false); intervals.addInterval(interval1); expect(intervals.isStartIncluded).toBe(true); expect(intervals.isStopIncluded).toBe(false); intervals.addInterval(interval2); expect(intervals.isStartIncluded).toBe(true); expect(intervals.isStopIncluded).toBe(true); }); it("contains works for a simple interval collection.", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); intervals.addInterval(interval1); intervals.addInterval(interval2); expect(intervals.contains(new JulianDate(0.5))).toEqual(false); expect(intervals.contains(new JulianDate(1.5))).toEqual(true); expect(intervals.contains(new JulianDate(2.0))).toEqual(false); expect(intervals.contains(new JulianDate(2.5))).toEqual(true); expect(intervals.contains(new JulianDate(3.0))).toEqual(true); expect(intervals.contains(new JulianDate(3.5))).toEqual(false); }); it("contains works for a endpoints of a closed interval collection.", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: true, }); intervals.addInterval(interval); expect(intervals.contains(interval.start)).toEqual(true); expect(intervals.contains(interval.stop)).toEqual(true); }); it("contains works for a endpoints of an open interval collection.", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: false, isStopIncluded: false, }); intervals.addInterval(interval); expect(intervals.contains(interval.start)).toEqual(false); expect(intervals.contains(interval.stop)).toEqual(false); }); it("indexOf finds the correct interval for a valid date", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); intervals.addInterval(interval1); intervals.addInterval(interval2); expect(intervals.indexOf(new JulianDate(2.5))).toEqual(1); }); it("indexOf returns complement of index of the interval that a missing date would come before", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); intervals.addInterval(interval1); intervals.addInterval(interval2); expect(intervals.indexOf(new JulianDate(2))).toEqual(~1); }); it("indexOf returns complement of collection length if the date is after all intervals.", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); intervals.addInterval(interval1); intervals.addInterval(interval2); expect(intervals.indexOf(new JulianDate(4))).toEqual(~2); }); it("get returns the interval at the correct index", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: false, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, }); var interval3 = new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: false, isStopIncluded: false, }); intervals.addInterval(interval1); intervals.addInterval(interval2); intervals.addInterval(interval3); expect(intervals.get(1)).toEqual(interval2); }); it("get is undefined for a out of range index", function () { var intervals = new TimeIntervalCollection(); expect(intervals.get(1)).toBeUndefined(); }); it("findInterval works when looking for an exact interval", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(0), stop: new JulianDate(1), isStartIncluded: false, isStopIncluded: false, data: 1, }); var interval2 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, data: 2, }); var interval3 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, data: 3, }); intervals.addInterval(interval1); intervals.addInterval(interval2); intervals.addInterval(interval3); expect( intervals.findInterval({ start: interval2.start, stop: interval2.stop, isStartIncluded: true, isStopIncluded: false, }) ).toEqual(interval2); }); it("findInterval works when you do not care about end points", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(0), stop: new JulianDate(1), isStartIncluded: false, isStopIncluded: false, data: 1, }); var interval2 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, data: 2, }); var interval3 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, data: 3, }); intervals.addInterval(interval1); intervals.addInterval(interval2); intervals.addInterval(interval3); expect( intervals.findInterval({ start: interval2.start, stop: interval2.stop, }) ).toEqual(interval2); }); it("getStart & getStop return expected values.", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: false, }); intervals.addInterval(interval1); intervals.addInterval(interval2); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval2.stop); }); it("isEmpty and clear return expected values", function () { var intervals = new TimeIntervalCollection(); intervals.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: false, isStopIncluded: true, }) ); expect(intervals.isEmpty).toEqual(false); intervals.removeAll(); expect(intervals.isEmpty).toEqual(true); }); it("length returns the correct interval length when adding intervals with different data", function () { var intervals = new TimeIntervalCollection(); expect(intervals.length).toEqual(0); intervals.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, data: 1, }) ); expect(intervals.length).toEqual(1); intervals.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: true, data: 2, }) ); expect(intervals.length).toEqual(3); intervals.removeAll(); expect(intervals.length).toEqual(0); }); it("length returns the correct length after two intervals with the same data are merged.", function () { var intervals = new TimeIntervalCollection(); intervals.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, data: 1, }) ); expect(intervals.length).toEqual(1); intervals.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: true, data: 1, }) ); expect(intervals.length).toEqual(1); intervals.removeAll(); expect(intervals.length).toEqual(0); }); it("addInterval and findIntervalContainingDate work when using non-overlapping intervals", function () { var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: true, data: 1, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, data: 2, }); var interval3 = new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: true, isStopIncluded: true, data: 3, }); var intervals = new TimeIntervalCollection(); intervals.addInterval(interval1); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start)).toEqual( interval1 ); expect(intervals.findIntervalContainingDate(interval1.stop)).toEqual( interval1 ); intervals.addInterval(interval2); expect(intervals.length).toEqual(2); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval2.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start)).toEqual( interval1 ); expect(intervals.findIntervalContainingDate(interval1.stop)).toEqual( interval1 ); expect(intervals.findIntervalContainingDate(interval2.stop)).toEqual( interval2 ); intervals.addInterval(interval3); expect(intervals.length).toEqual(3); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval3.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start)).toEqual( interval1 ); expect(intervals.findIntervalContainingDate(interval1.stop)).toEqual( interval1 ); expect(intervals.findIntervalContainingDate(interval2.stop)).toEqual( interval2 ); expect(intervals.findIntervalContainingDate(interval3.start)).toEqual( interval3 ); expect(intervals.findIntervalContainingDate(interval3.stop)).toEqual( interval3 ); }); it("addInterval and findIntervalContainingDate work when using overlapping intervals", function () { var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2.5), isStartIncluded: true, isStopIncluded: true, data: 1, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, data: 2, }); var interval3 = new TimeInterval({ start: interval1.start, stop: interval2.stop, isStartIncluded: true, isStopIncluded: true, data: 3, }); var intervals = new TimeIntervalCollection(); intervals.addInterval(interval1); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start).data).toEqual( 1 ); expect(intervals.findIntervalContainingDate(interval1.stop).data).toEqual( 1 ); intervals.addInterval(interval2); expect(intervals.length).toEqual(2); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval2.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start).data).toEqual( 1 ); expect(intervals.findIntervalContainingDate(interval1.stop).data).toEqual( 2 ); expect(intervals.findIntervalContainingDate(interval2.stop).data).toEqual( 2 ); intervals.addInterval(interval3); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval3.start); expect(intervals.stop).toEqual(interval3.stop); expect(intervals.isEmpty).toEqual(false); expect(intervals.findIntervalContainingDate(interval1.start).data).toEqual( 3 ); expect(intervals.findIntervalContainingDate(interval1.stop).data).toEqual( 3 ); expect(intervals.findIntervalContainingDate(interval2.start).data).toEqual( 3 ); expect(intervals.findIntervalContainingDate(interval2.stop).data).toEqual( 3 ); expect(intervals.findIntervalContainingDate(interval3.start).data).toEqual( 3 ); expect(intervals.findIntervalContainingDate(interval3.stop).data).toEqual( 3 ); }); it("findDataForIntervalContainingDate works", function () { var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2.5), isStartIncluded: true, isStopIncluded: true, data: 1, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, data: 2, }); var intervals = new TimeIntervalCollection(); intervals.addInterval(interval1); expect( intervals.findDataForIntervalContainingDate(interval1.start) ).toEqual(1); expect(intervals.findDataForIntervalContainingDate(interval1.stop)).toEqual( 1 ); intervals.addInterval(interval2); expect( intervals.findDataForIntervalContainingDate(interval1.start) ).toEqual(1); expect(intervals.findDataForIntervalContainingDate(interval1.stop)).toEqual( 2 ); expect(intervals.findDataForIntervalContainingDate(interval2.stop)).toEqual( 2 ); expect( intervals.findDataForIntervalContainingDate(new JulianDate(5)) ).toBeUndefined(); }); it("addInterval correctly intervals that have the same data when using equalsCallback", function () { var intervals = new TimeIntervalCollection(); var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, data: new TestObject(2), }); var interval2 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: false, data: new TestObject(2), }); var interval3 = new TimeInterval({ start: new JulianDate(3), stop: new JulianDate(4), isStartIncluded: false, isStopIncluded: true, data: new TestObject(2), }); var interval4 = new TimeInterval({ start: new JulianDate(3), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, data: new TestObject(3), }); intervals.addInterval(interval1, TestObject.equals); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.get(0).data.value).toEqual(2); intervals.addInterval(interval2, TestObject.equals); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.get(0).data.value).toEqual(2); intervals.addInterval(interval3, TestObject.equals); expect(intervals.length).toEqual(1); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.get(0).data.value).toEqual(2); intervals.addInterval(interval4, TestObject.equals); expect(intervals.length).toEqual(2); expect(intervals.start).toEqual(interval1.start); expect(intervals.stop).toEqual(interval1.stop); expect(intervals.get(0).start).toEqual(interval1.start); expect(intervals.get(0).stop).toEqual(interval4.start); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(false); expect(intervals.get(0).data.value).toEqual(2); expect(intervals.get(1).start).toEqual(interval4.start); expect(intervals.get(1).stop).toEqual(interval4.stop); expect(intervals.get(1).isStartIncluded).toEqual(true); expect(intervals.get(1).isStopIncluded).toEqual(true); expect(intervals.get(1).data.value).toEqual(3); }); it("removeInterval works correctly", function () { // test cases derived from STK Components test suite function createTimeInterval( startDays, stopDays, isStartIncluded, isStopIncluded ) { return new TimeInterval({ start: new JulianDate(startDays, 0.0, TimeStandard.TAI), stop: new JulianDate(stopDays, 0.0, TimeStandard.TAI), isStartIncluded: isStartIncluded, isStopIncluded: isStopIncluded, }); } var intervals = new TimeIntervalCollection(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); // Empty expect(intervals.removeInterval(TimeInterval.EMPTY)).toEqual(false); expect(intervals.length).toEqual(2); // Before first expect(intervals.removeInterval(createTimeInterval(1.0, 5.0))).toEqual( false ); expect(intervals.length).toEqual(2); // After last expect(intervals.removeInterval(createTimeInterval(50.0, 60.0))).toEqual( false ); expect(intervals.length).toEqual(2); // Inside hole expect(intervals.removeInterval(createTimeInterval(22.0, 28.0))).toEqual( false ); expect(intervals.length).toEqual(2); // From beginning expect(intervals.removeInterval(createTimeInterval(5.0, 15.0))).toEqual( true ); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(0).start)).toEqual(15.0); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); // From end expect(intervals.removeInterval(createTimeInterval(35.0, 45.0))).toEqual( true ); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(30.0); expect(JulianDate.totalDays(intervals.get(1).stop)).toEqual(35.0); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); // From middle of single interval expect(intervals.removeInterval(createTimeInterval(12.0, 18.0))).toEqual( true ); expect(intervals.length).toEqual(3); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(12.0); expect(intervals.get(0).isStopIncluded).toEqual(false); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(18.0); expect(intervals.get(1).isStartIncluded).toEqual(false); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); intervals.addInterval(createTimeInterval(45.0, 50.0)); // Span an entire interval and into part of next expect(intervals.removeInterval(createTimeInterval(25.0, 46.0))).toEqual( true ); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(46.0); expect(intervals.get(1).isStartIncluded).toEqual(false); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); intervals.addInterval(createTimeInterval(45.0, 50.0)); // Interval ends at same date as an existing interval expect(intervals.removeInterval(createTimeInterval(25.0, 40.0))).toEqual( true ); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(45.0); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); intervals.addInterval(createTimeInterval(45.0, 50.0)); // Interval ends at same date as an existing interval and single point of existing // interval survives. expect( intervals.removeInterval(createTimeInterval(25.0, 40.0, true, false)) ).toEqual(true); expect(intervals.length).toEqual(3); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(40.0); expect(JulianDate.totalDays(intervals.get(1).stop)).toEqual(40.0); expect(intervals.get(1).isStartIncluded).toEqual(true); expect(intervals.get(1).isStopIncluded).toEqual(true); expect(JulianDate.totalDays(intervals.get(2).start)).toEqual(45.0); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); intervals.addInterval(createTimeInterval(30.0, 40.0)); intervals.addInterval(createTimeInterval(40.0, 50.0, false, true)); // Interval ends at same date as an existing interval, single point of existing // interval survives, and single point can be combined with the next interval. expect( intervals.removeInterval(createTimeInterval(25.0, 40.0, true, false)) ).toEqual(true); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(40.0); expect(intervals.get(1).isStartIncluded).toEqual(true); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); // End point of removal interval overlaps first point of existing interval. expect(intervals.removeInterval(createTimeInterval(0.0, 10.0))).toEqual( true ); expect(intervals.length).toEqual(1); expect(JulianDate.totalDays(intervals.get(0).start)).toEqual(10.0); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); expect(intervals.get(0).isStartIncluded).toEqual(false); expect(intervals.get(0).isStopIncluded).toEqual(true); intervals.removeAll(); intervals.addInterval(createTimeInterval(10.0, 20.0)); // Start point of removal interval does NOT overlap last point of existing interval // because the start point is not included. expect( intervals.removeInterval(createTimeInterval(20.0, 30.0, false, true)) ).toEqual(false); expect(intervals.length).toEqual(1); expect(JulianDate.totalDays(intervals.get(0).start)).toEqual(10.0); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(20.0); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(true); // Removing an open interval from an otherwise identical closed interval intervals.removeAll(); intervals.addInterval(createTimeInterval(0.0, 20.0)); expect( intervals.removeInterval(createTimeInterval(0.0, 20.0, false, false)) ).toEqual(true); expect(intervals.length).toEqual(2); expect(JulianDate.totalDays(intervals.get(0).start)).toEqual(0.0); expect(JulianDate.totalDays(intervals.get(0).stop)).toEqual(0.0); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(true); expect(JulianDate.totalDays(intervals.get(1).start)).toEqual(20.0); expect(JulianDate.totalDays(intervals.get(1).stop)).toEqual(20.0); expect(intervals.get(1).isStartIncluded).toEqual(true); expect(intervals.get(1).isStopIncluded).toEqual(true); }); it("removeInterval removes the first interval correctly", function () { var intervals = new TimeIntervalCollection(); var from1To3 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(3), isStopIncluded: true, isStartIncluded: true, data: "1-to-3", }); var from3To6 = new TimeInterval({ start: new JulianDate(3), stop: new JulianDate(6), isStopIncluded: true, isStartIncluded: true, data: "3-to-6", }); intervals.addInterval(from1To3); intervals.addInterval(from3To6); expect(intervals.length).toEqual(2); expect(intervals.get(0).isStartIncluded).toBeTruthy(); expect(intervals.get(0).isStopIncluded).toBeFalsy(); // changed to false because 3-6 overlaps it expect(intervals.get(0).start.dayNumber).toEqual(1); expect(intervals.get(0).stop.dayNumber).toEqual(3); expect(intervals.get(0).data).toEqual("1-to-3"); expect(intervals.get(1).isStartIncluded).toBeTruthy(); expect(intervals.get(1).isStopIncluded).toBeTruthy(); expect(intervals.get(1).start.dayNumber).toEqual(3); expect(intervals.get(1).stop.dayNumber).toEqual(6); expect(intervals.get(1).data).toEqual("3-to-6"); var toRemove = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(3), isStopIncluded: true, isStartIncluded: true, data: undefined, }); expect(intervals.removeInterval(toRemove)).toEqual(true); expect(intervals.length).toEqual(1); expect(intervals.start.dayNumber).toEqual(3); expect(intervals.stop.dayNumber).toEqual(6); expect(intervals.get(0).start.dayNumber).toEqual(3); expect(intervals.get(0).stop.dayNumber).toEqual(6); expect(intervals.get(0).isStartIncluded).toEqual(false); expect(intervals.get(0).isStopIncluded).toEqual(true); expect(intervals.get(0).data).toEqual("3-to-6"); }); it("should add and remove intervals correctly (some kind of integration test)", function () { // about the year 3000 var CONST_DAY_NUM = 3000000; function intervalFromSeconds(seconds, data) { // make all intervals a few seconds in length return new TimeInterval({ start: new JulianDate(CONST_DAY_NUM, seconds), stop: new JulianDate(CONST_DAY_NUM, seconds + 4), isStartIncluded: true, isStopIncluded: true, data: data, }); } function addIntervals(collection, specs) { specs.forEach(function (spec) { collection.addInterval(intervalFromSeconds(spec.sec, spec.data)); }); } function removeInterval(collection, fromSecond, toSecond) { collection.removeInterval( new TimeInterval({ start: new JulianDate(CONST_DAY_NUM, fromSecond), stop: new JulianDate(CONST_DAY_NUM, toSecond), isStartIncluded: true, isStopIncluded: true, data: undefined, }) ); } function expectCollection(collection, count, expectation) { expectation.forEach(function (item) { var interval = collection.findIntervalContainingDate( new JulianDate(CONST_DAY_NUM, item.sec) ); if (item.data === null) { // expect the interval at this time not to exist if (interval !== undefined) { throw new Error( "expected undefined at " + item.sec + " seconds but it was " + interval.data ); } expect(interval).toBeUndefined(); } else if (interval === undefined) { throw new Error( "expected " + item.data + " at " + item.sec + " seconds, but it was undefined" ); } else if (interval.data !== item.data) { throw new Error( "expected " + item.data + " at " + item.sec + " seconds, but it was " + interval.data ); } }); if (collection.length !== count) { throw new Error( "Expected interval to have " + count + " elements but it had " + collection.length ); } } var collection = new TimeIntervalCollection(); addIntervals(collection, [ { sec: 0, data: 0 }, { sec: 2, data: 2 }, { sec: 4, data: 4 }, { sec: 6, data: 6 }, ]); expectCollection(collection, 4, [ { sec: 0, data: 0 }, { sec: 1, data: 0 }, { sec: 2, data: 2 }, { sec: 3, data: 2 }, { sec: 4, data: 4 }, { sec: 5, data: 4 }, { sec: 6, data: 6 }, { sec: 7, data: 6 }, { sec: 8, data: 6 }, { sec: 9, data: 6 }, { sec: 10, data: 6 }, { sec: 11, data: null }, ]); addIntervals(collection, [ { sec: 1, data: 1 }, { sec: 3, data: 3 }, ]); expectCollection(collection, 4, [ { sec: 0, data: 0 }, { sec: 1, data: 1 }, { sec: 2, data: 1 }, { sec: 3, data: 3 }, { sec: 4, data: 3 }, { sec: 5, data: 3 }, { sec: 6, data: 3 }, { sec: 7, data: 3 }, { sec: 8, data: 6 }, { sec: 9, data: 6 }, { sec: 10, data: 6 }, { sec: 11, data: null }, ]); addIntervals(collection, [{ sec: 3, data: 31 }]); expectCollection(collection, 4, [ { sec: 0, data: 0 }, { sec: 1, data: 1 }, { sec: 2, data: 1 }, { sec: 3, data: 31 }, { sec: 4, data: 31 }, { sec: 5, data: 31 }, { sec: 6, data: 31 }, { sec: 7, data: 31 }, { sec: 8, data: 6 }, { sec: 9, data: 6 }, { sec: 10, data: 6 }, { sec: 11, data: null }, ]); removeInterval(collection, 3, 8); expectCollection(collection, 3, [ { sec: 0, data: 0 }, { sec: 1, data: 1 }, { sec: 2, data: 1 }, { sec: 3, data: null }, { sec: 4, data: null }, { sec: 5, data: null }, { sec: 6, data: null }, { sec: 7, data: null }, { sec: 8, data: null }, { sec: 9, data: 6 }, { sec: 10, data: 6 }, { sec: 11, data: null }, ]); removeInterval(collection, 0, 1); expectCollection(collection, 2, [ { sec: 0, data: null }, { sec: 1, data: null }, { sec: 2, data: 1 }, { sec: 3, data: null }, { sec: 4, data: null }, { sec: 5, data: null }, { sec: 6, data: null }, { sec: 7, data: null }, { sec: 8, data: null }, { sec: 9, data: 6 }, { sec: 10, data: 6 }, { sec: 11, data: null }, ]); removeInterval(collection, 0, 11); expectCollection(collection, 0, [ { sec: 0, data: null }, { sec: 11, data: null }, ]); addIntervals(collection, [ { sec: 1, data: 1 }, { sec: 12, data: 12 }, ]); expectCollection(collection, 2, [ { sec: 0, data: null }, { sec: 1, data: 1 }, { sec: 2, data: 1 }, { sec: 3, data: 1 }, { sec: 4, data: 1 }, { sec: 5, data: 1 }, { sec: 6, data: null }, { sec: 7, data: null }, { sec: 8, data: null }, { sec: 9, data: null }, { sec: 10, data: null }, { sec: 11, data: null }, { sec: 12, data: 12 }, { sec: 13, data: 12 }, { sec: 14, data: 12 }, { sec: 15, data: 12 }, { sec: 16, data: 12 }, { sec: 17, data: null }, ]); removeInterval(collection, 0, 3); expectCollection(collection, 2, [ { sec: 0, data: null }, { sec: 1, data: null }, { sec: 2, data: null }, { sec: 3, data: null }, { sec: 4, data: 1 }, { sec: 5, data: 1 }, { sec: 6, data: null }, { sec: 7, data: null }, { sec: 8, data: null }, { sec: 12, data: 12 }, { sec: 16, data: 12 }, { sec: 17, data: null }, ]); }); it("removeInterval leaves a hole", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, }); var removedInterval = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: false, }); intervals.addInterval(interval); expect(intervals.removeInterval(removedInterval)).toEqual(true); expect(intervals.length).toEqual(2); expect(intervals.get(0).start).toEqual(interval.start); expect(intervals.get(0).stop).toEqual(removedInterval.start); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(false); expect(intervals.get(1).start).toEqual(removedInterval.stop); expect(intervals.get(1).stop).toEqual(interval.stop); expect(intervals.get(1).isStartIncluded).toEqual(true); expect(intervals.get(1).isStopIncluded).toEqual(true); }); it("removeInterval with an interval of the exact same size works.", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: false, }); intervals.addInterval(interval); expect(intervals.length).toEqual(1); expect(intervals.get(0).start).toEqual(interval.start); expect(intervals.get(0).stop).toEqual(interval.stop); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(false); intervals.removeInterval(interval); expect(intervals.length).toEqual(0); }); it("removeInterval with an empty interval has no affect.", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, }); intervals.addInterval(interval); expect(intervals.length).toEqual(1); expect(intervals.get(0).start).toEqual(interval.start); expect(intervals.get(0).stop).toEqual(interval.stop); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(true); expect(intervals.removeInterval(TimeInterval.EMPTY)).toEqual(false); expect(intervals.length).toEqual(1); expect(intervals.get(0).start).toEqual(interval.start); expect(intervals.get(0).stop).toEqual(interval.stop); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(true); }); it("removeInterval takes isStartIncluded and isStopIncluded into account", function () { var intervals = new TimeIntervalCollection(); var interval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, }); var removedInterval = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: false, isStopIncluded: false, }); intervals.addInterval(interval); expect(intervals.removeInterval(removedInterval)).toEqual(true); expect(intervals.length).toEqual(2); expect(intervals.get(0).start).toEqual(interval.start); expect(intervals.get(0).stop).toEqual(interval.start); expect(intervals.get(0).isStartIncluded).toEqual(true); expect(intervals.get(0).isStopIncluded).toEqual(true); expect(intervals.get(1).start).toEqual(interval.stop); expect(intervals.get(1).stop).toEqual(interval.stop); expect(intervals.get(1).isStartIncluded).toEqual(true); expect(intervals.get(1).isStopIncluded).toEqual(true); }); it("removeInterval removes overlapped intervals", function () { var intervals = new TimeIntervalCollection(); intervals.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }) ); intervals.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, }) ); intervals.addInterval( new TimeInterval({ start: new JulianDate(3), stop: new JulianDate(4), isStartIncluded: false, isStopIncluded: false, }) ); intervals.addInterval( new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: false, isStopIncluded: true, }) ); var removedInterval = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(4), isStartIncluded: false, isStopIncluded: false, }); expect(intervals.length).toEqual(4); expect(intervals.removeInterval(removedInterval)).toEqual(true); expect(intervals.length).toEqual(2); }); it("intersect works with an empty collection", function () { var left = new TimeIntervalCollection(); left.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, }) ); expect(left.intersect(new TimeIntervalCollection()).length).toEqual(0); }); it("intersect works non-overlapping intervals", function () { var left = new TimeIntervalCollection(); left.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: false, }) ); var right = new TimeIntervalCollection(); right.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: true, isStopIncluded: true, }) ); expect(left.intersect(right).length).toEqual(0); }); it("intersect works with intersecting intervals and no merge callback", function () { var left = new TimeIntervalCollection(); left.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, }) ); var right = new TimeIntervalCollection(); right.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, }) ); var intersectedIntervals = left.intersect(right); expect(intersectedIntervals.length).toEqual(1); expect(intersectedIntervals.get(0).start).toEqual(right.get(0).start); expect(intersectedIntervals.get(0).stop).toEqual(right.get(0).stop); expect(intersectedIntervals.get(0).isStartIncluded).toEqual(false); expect(intersectedIntervals.get(0).isStopIncluded).toEqual(false); }); it("intersect works with intersecting intervals an a merge callback", function () { var left = new TimeIntervalCollection(); left.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(4), isStartIncluded: true, isStopIncluded: true, data: new TestObject(1), }) ); var right = new TimeIntervalCollection(); right.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: false, data: new TestObject(2), }) ); var intersectedIntervals = left.intersect( right, TestObject.equals, TestObject.merge ); expect(intersectedIntervals.length).toEqual(1); expect(intersectedIntervals.get(0).start).toEqual(right.start); expect(intersectedIntervals.get(0).stop).toEqual(right.stop); expect(intersectedIntervals.get(0).isStartIncluded).toEqual(false); expect(intersectedIntervals.get(0).isStopIncluded).toEqual(false); expect(intersectedIntervals.get(0).data.value).toEqual(3); }); it("equals works without data", function () { var interval1 = new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: true, }); var interval2 = new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, }); var interval3 = new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: true, isStopIncluded: true, }); var left = new TimeIntervalCollection(); left.addInterval(interval1); left.addInterval(interval2); left.addInterval(interval3); var right = new TimeIntervalCollection(); right.addInterval(interval1); right.addInterval(interval2); right.addInterval(interval3); expect(left.equals(right)).toEqual(true); }); it("equals works with data", function () { var left = new TimeIntervalCollection(); left.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: true, data: {}, }) ); left.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, data: {}, }) ); left.addInterval( new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: true, isStopIncluded: true, data: {}, }) ); var right = new TimeIntervalCollection(); right.addInterval( new TimeInterval({ start: new JulianDate(1), stop: new JulianDate(2), isStartIncluded: true, isStopIncluded: true, data: {}, }) ); right.addInterval( new TimeInterval({ start: new JulianDate(2), stop: new JulianDate(3), isStartIncluded: false, isStopIncluded: true, data: {}, }) ); right.addInterval( new TimeInterval({ start: new JulianDate(4), stop: new JulianDate(5), isStartIncluded: true, isStopIncluded: true, data: {}, }) ); expect(left.equals(right)).toEqual(false); expect( left.equals(right, function () { return true; }) ).toEqual(true); expect( left.equals(right, function () { return false; }) ).toEqual(false); }); it("get throws with undefined", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.get(undefined); }).toThrowDeveloperError(); }); it("findIntervalContainingDate throws with undefined date", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.findIntervalContainingDate(undefined); }).toThrowDeveloperError(); }); it("findDataForIntervalContainingDate throws with undefined date", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.findDataForIntervalContainingDate(undefined); }).toThrowDeveloperError(); }); it("contains throws with undefined date", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.contains(undefined); }).toThrowDeveloperError(); }); it("indexOf throws with undefined date", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.indexOf(undefined); }).toThrowDeveloperError(); }); it("addInterval throws with undefined interval", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.addInterval(undefined, TestObject.equals); }).toThrowDeveloperError(); }); it("removeInterval throws with undefined", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.removeInterval(undefined); }).toThrowDeveloperError(); }); it("intersect throws with undefined interval", function () { var intervals = new TimeIntervalCollection(); expect(function () { intervals.intersect(undefined); }).toThrowDeveloperError(); }); it("changed event is raised as expected", function () { var interval = new TimeInterval({ start: new JulianDate(10, 0), stop: new JulianDate(12, 0), }); var intervals = new TimeIntervalCollection(); var listener = jasmine.createSpy("listener"); intervals.changedEvent.addEventListener(listener); intervals.addInterval(interval); expect(listener).toHaveBeenCalledWith(intervals); listener.calls.reset(); intervals.removeInterval(interval); expect(listener).toHaveBeenCalledWith(intervals); intervals.addInterval(interval); listener.calls.reset(); intervals.removeAll(); expect(listener).toHaveBeenCalledWith(intervals); }); it("fromIso8601 throws without options", function () { expect(function () { TimeIntervalCollection.fromIso8601(undefined); }).toThrowDeveloperError(); }); it("fromIso8601 throws without options.iso8601", function () { expect(function () { TimeIntervalCollection.fromIso8601({}); }).toThrowDeveloperError(); }); it("fromIso8601 return single interval if no duration", function () { var start = "2017-01-01T00:00:00Z"; var stop = "2017-01-02T00:00:00Z"; var julianDates = iso8601ToJulianDateArray([start, stop]); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: start + "/" + stop, isStartIncluded: false, isStopIncluded: false, }); checkIntervals(intervals, julianDates, false, false); }); it("fromIso8601 works with just year", function () { var iso8601Dates = [ "2017-01-01T00:00:00Z", "2018-01-01T00:00:00Z", "2019-01-01T00:00:00Z", "2020-01-01T00:00:00Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1Y", }); checkIntervals(intervals, julianDates, true, true); }); it("fromIso8601 works with just month", function () { var iso8601Dates = [ "2016-12-02T10:00:01.5Z", "2017-01-02T10:00:01.5Z", "2017-02-02T10:00:01.5Z", "2017-03-02T10:00:01.5Z", "2017-04-02T10:00:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1M", }); checkIntervals(intervals, julianDates, true, true); }); it("fromIso8601 works with just day", function () { var iso8601Dates = [ "2016-12-31T10:01:01.5Z", "2017-01-01T10:01:01.5Z", "2017-01-02T10:01:01.5Z", "2017-01-03T10:01:01.5Z", "2017-01-04T10:01:01.5Z", "2017-01-05T10:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1D", isStartIncluded: false, }); checkIntervals(intervals, julianDates, false, true); }); it("fromIso8601 works with just all date components", function () { var iso8601Dates = [ "2017-01-01T10:01:01.5Z", "2018-03-04T10:01:01.5Z", "2019-05-07T10:01:01.5Z", "2020-07-10T10:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1Y2M3D", isStopIncluded: false, }); checkIntervals(intervals, julianDates, true, false); }); it("fromIso8601 works with just just hour", function () { var iso8601Dates = [ "2017-01-01T22:01:01.5Z", "2017-01-01T23:01:01.5Z", "2017-01-02T00:01:01.5Z", "2017-01-02T01:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1H", isStartIncluded: false, }); checkIntervals(intervals, julianDates, false, true); }); it("fromIso8601 works with just just minute", function () { var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1M", isStopIncluded: false, }); checkIntervals(intervals, julianDates, true, false); }); it("fromIso8601 works with just just second", function () { var iso8601Dates = [ "2016-12-31T23:59:58.5Z", "2016-12-31T23:59:59.5Z", "2017-01-01T00:00:00.5Z", "2017-01-01T00:00:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1S", isStartIncluded: false, isStopIncluded: false, }); checkIntervals(intervals, julianDates, false, false); }); it("fromIso8601 works with just just millisecond", function () { var iso8601Dates = [ "2016-12-31T23:59:58.5Z", "2016-12-31T23:59:59Z", "2016-12-31T23:59:59.5Z", "2017-01-01T00:00:00Z", "2017-01-01T00:00:00.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT0.5S", }); checkIntervals(intervals, julianDates, true, true); }); it("fromIso8601 works with just all time components", function () { var iso8601Dates = [ "2017-01-01T10:01:01.5Z", "2017-01-01T11:03:05Z", "2017-01-01T12:05:08.5Z", "2017-01-01T13:07:12Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1H2M3.5S", }); checkIntervals(intervals, julianDates, true, true); }); it("fromIso8601 works with just all date and time components", function () { var iso8601Dates = [ "2017-01-01T10:01:01.5Z", "2018-03-04T11:03:05Z", "2019-05-07T12:05:08.5Z", "2020-07-10T13:07:12Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1Y2M3DT1H2M3.5S", }); checkIntervals(intervals, julianDates, true, true); }); it("fromIso8601 works with just all date and time components with date string for duration", function () { var iso8601Dates = [ "2017-01-01T10:01:01.5Z", "2018-03-04T11:03:05Z", "2019-05-07T12:05:08.5Z", "2020-07-10T13:07:12Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/0001-02-03T01:02:03.5", }); checkIntervals(intervals, julianDates, true, true); }); function dataCallback(interval, index) { if (JulianDate.compare(Iso8601.MINIMUM_VALUE, interval.start) === 0) { return "default"; } return JulianDate.toIso8601(interval.start); } it("fromIso8601 calls the dataCallback on interval create", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2017-01-01T10:01:01.5Z", "2018-03-04T11:03:05Z", "2019-05-07T12:05:08.5Z", "2020-07-10T13:07:12Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/P1Y2M3DT1H2M3.5S", dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(3); for (var i = 0; i < 3; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } checkIntervals(intervals, julianDates, true, true, dataCallback); }); it("fromIso8601 handles leadingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1M", isStartIncluded: true, isStopIncluded: false, leadingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(4); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(false); expect(leading.data).toEqual(dataCallback(leading, 0)); checkIntervals(intervals, julianDates, true, false, dataCallback); }); it("fromIso8601 handles trailingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1M", isStartIncluded: false, isStopIncluded: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(4); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(false); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); checkIntervals(intervals, julianDates, false, true, dataCallback); }); it("fromIso8601 handles leadingInterval and trailingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601({ iso8601: iso8601Dates[0] + "/" + iso8601Dates[iso8601Dates.length - 1] + "/PT1M", isStartIncluded: false, isStopIncluded: false, leadingInterval: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(5); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(true); expect(leading.data).toEqual(dataCallback(leading, 0)); // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(true); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); // Remove leading interval and check the rest checkIntervals(intervals, julianDates, false, false, dataCallback); }); it("fromIso8601DateArray handles leadingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601DateArray({ iso8601Dates: iso8601Dates, isStartIncluded: true, isStopIncluded: false, leadingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(4); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(false); expect(leading.data).toEqual(dataCallback(leading, 0)); checkIntervals(intervals, julianDates, true, false, dataCallback); }); it("fromIso8601DateArray handles trailingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601DateArray({ iso8601Dates: iso8601Dates, isStartIncluded: false, isStopIncluded: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(4); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(false); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); checkIntervals(intervals, julianDates, false, true, dataCallback); }); it("fromIso8601DateArray handles leadingInterval and trailingInterval option", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var intervals = TimeIntervalCollection.fromIso8601DateArray({ iso8601Dates: iso8601Dates, isStartIncluded: false, isStopIncluded: false, leadingInterval: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(5); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(true); expect(leading.data).toEqual(dataCallback(leading, 0)); // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(true); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); // Remove leading interval and check the rest checkIntervals(intervals, julianDates, false, false, dataCallback); }); it("fromIso8601DurationArray handles relativeToPrevious set to false", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var iso8601Durations = ["PT0M", "PT1M", "PT2M", "PT3M"]; var intervals = TimeIntervalCollection.fromIso8601DurationArray({ epoch: julianDates[0], iso8601Durations: iso8601Durations, relativeToPrevious: false, isStartIncluded: false, isStopIncluded: false, leadingInterval: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(5); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(true); expect(leading.data).toEqual(dataCallback(leading, 0)); // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(true); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); // Remove leading interval and check the rest checkIntervals(intervals, julianDates, false, false, dataCallback); }); it("fromIso8601DurationArray handles relativeToPrevious set to true", function () { var dataSpy = jasmine.createSpy("data").and.callFake(dataCallback); var iso8601Dates = [ "2016-12-31T23:58:01.5Z", "2016-12-31T23:59:01.5Z", "2017-01-01T00:00:01.5Z", "2017-01-01T00:01:01.5Z", ]; var julianDates = iso8601ToJulianDateArray(iso8601Dates); var iso8601Durations = ["PT0M", "PT1M", "PT1M", "PT1M"]; var intervals = TimeIntervalCollection.fromIso8601DurationArray({ epoch: julianDates[0], iso8601Durations: iso8601Durations, relativeToPrevious: true, isStartIncluded: false, isStopIncluded: false, leadingInterval: true, trailingInterval: true, dataCallback: dataSpy, }); expect(dataSpy.calls.count()).toEqual(5); for (var i = 0; i < 4; ++i) { expect(dataSpy).toHaveBeenCalledWith(intervals.get(i), i); } // Check leading interval var leading = intervals._intervals.shift(); expect(JulianDate.compare(leading.start, Iso8601.MINIMUM_VALUE)).toEqual(0); expect(JulianDate.compare(leading.stop, julianDates[0])).toEqual(0); expect(leading.isStartIncluded).toBe(true); expect(leading.isStopIncluded).toBe(true); expect(leading.data).toEqual(dataCallback(leading, 0)); // Check trailing interval var trailing = intervals._intervals.pop(); expect( JulianDate.compare(trailing.start, julianDates[iso8601Dates.length - 1]) ).toEqual(0); expect(JulianDate.compare(trailing.stop, Iso8601.MAXIMUM_VALUE)).toEqual(0); expect(trailing.isStartIncluded).toBe(true); expect(trailing.isStopIncluded).toBe(true); expect(trailing.data).toEqual(dataCallback(trailing, 4)); // Remove leading interval and check the rest checkIntervals(intervals, julianDates, false, false, dataCallback); }); });