| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Include test fixture. |
| GEN_INCLUDE(['../testing/chromevox_unittest_base.js']); |
| |
| UnserializableSpan = function() {}; |
| |
| StatelessSerializableSpan = function() {}; |
| |
| NonStatelessSerializableSpan = function(value) { |
| this.value = value; |
| }; |
| |
| /** |
| * @param {!Object} obj object containing the |
| * serializable representation. |
| * @return {!Object} The Spannable. |
| */ |
| NonStatelessSerializableSpan.fromJson = function(obj) { |
| return new NonStatelessSerializableSpan(obj.value / 2); |
| }; |
| |
| /** |
| * @return {Object} the json serializable form. |
| */ |
| NonStatelessSerializableSpan.prototype.toJson = function() { |
| return {value: this.value * 2}; |
| }; |
| |
| /** |
| * @param {Spannable} spannable |
| * @param {*} annotation |
| */ |
| function assertSpanNotFound(spannable, annotation) { |
| assertFalse(spannable.hasSpan(annotation)); |
| assertException( |
| 'Span ' + annotation + ' shouldn\'t be in spannable ' + spannable, |
| function() { |
| spannable.getSpanStart(annotation); |
| }, |
| 'Error'); |
| assertException( |
| 'Span ' + annotation + ' shouldn\'t be in spannable ' + spannable, |
| function() { |
| spannable.getSpanEnd(annotation); |
| }, |
| 'Error'); |
| assertException( |
| 'Span ' + annotation + ' shouldn\'t be in spannable ' + spannable, |
| function() { |
| spannable.getSpanLength(annotation); |
| }, |
| 'Error'); |
| } |
| |
| /** |
| * Test fixture. |
| * @constructor |
| * @extends {ChromeVoxUnitTestBase} |
| */ |
| function ChromeVoxSpannableUnitTest() {} |
| |
| ChromeVoxSpannableUnitTest.prototype = { |
| __proto__: ChromeVoxUnitTestBase.prototype, |
| |
| /** @override */ |
| closureModuleDeps: [ |
| 'Spannable', |
| ], |
| |
| /** @override */ |
| setUp: function() { |
| Spannable.registerStatelessSerializableSpan( |
| StatelessSerializableSpan, 'StatelessSerializableSpan'); |
| |
| Spannable.registerSerializableSpan( |
| NonStatelessSerializableSpan, 'NonStatelessSerializableSpan', |
| NonStatelessSerializableSpan.fromJson, |
| NonStatelessSerializableSpan.prototype.toJson); |
| } |
| }; |
| |
| TEST_F('ChromeVoxSpannableUnitTest', 'ToStringUnannotated', function() { |
| assertEquals('', new Spannable().toString()); |
| assertEquals('hello world', new Spannable('hello world').toString()); |
| }); |
| |
| /** Tests that toString works correctly on annotated strings. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'ToStringAnnotated', function() { |
| var spannable = new Spannable('Hello Google'); |
| spannable.setSpan('http://www.google.com/', 6, 12); |
| assertEquals('Hello Google', spannable.toString()); |
| }); |
| |
| /** Tests the length calculation. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'LengthProperty', function() { |
| var spannable = new Spannable('Hello'); |
| spannable.setSpan({}, 0, 3); |
| assertEquals(5, spannable.length); |
| spannable.append(' world'); |
| assertEquals(11, spannable.length); |
| spannable.append(new Spannable(' from Spannable')); |
| assertEquals(26, spannable.length); |
| }); |
| |
| /** Tests that a span can be added and retrieved at the beginning. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SpanBeginning', function() { |
| var annotation = {}; |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation, 0, 5); |
| assertTrue(spannable.hasSpan(annotation)); |
| assertSame(annotation, spannable.getSpan(0)); |
| assertSame(annotation, spannable.getSpan(3)); |
| assertUndefined(spannable.getSpan(5)); |
| assertUndefined(spannable.getSpan(8)); |
| }); |
| |
| /** Tests that a span can be added and retrieved at the beginning. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SpanEnd', function() { |
| var annotation = {}; |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation, 6, 11); |
| assertTrue(spannable.hasSpan(annotation)); |
| assertUndefined(spannable.getSpan(3)); |
| assertUndefined(spannable.getSpan(5)); |
| assertSame(annotation, spannable.getSpan(6)); |
| assertSame(annotation, spannable.getSpan(10)); |
| }); |
| |
| /** Tests that a zero-length span is not retrieved. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SpanZeroLength', function() { |
| var annotation = {}; |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation, 3, 3); |
| assertTrue(spannable.hasSpan(annotation)); |
| assertUndefined(spannable.getSpan(2)); |
| assertUndefined(spannable.getSpan(3)); |
| assertUndefined(spannable.getSpan(4)); |
| }); |
| |
| /** Tests that a removed span is not returned. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'RemoveSpan', function() { |
| var annotation = {}; |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation, 0, 3); |
| assertSame(annotation, spannable.getSpan(1)); |
| spannable.removeSpan(annotation); |
| assertFalse(spannable.hasSpan(annotation)); |
| assertUndefined(spannable.getSpan(1)); |
| }); |
| |
| /** Tests that adding a span in one place removes it from another. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SetSpanMoves', function() { |
| var annotation = {}; |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation, 0, 3); |
| assertSame(annotation, spannable.getSpan(1)); |
| assertUndefined(spannable.getSpan(4)); |
| spannable.setSpan(annotation, 3, 6); |
| assertUndefined(spannable.getSpan(1)); |
| assertSame(annotation, spannable.getSpan(4)); |
| }); |
| |
| /** Tests that setSpan objects to out-of-range arguments. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SetSpanRangeError', function() { |
| var spannable = new Spannable('Hello world'); |
| |
| // Start index out of range. |
| assertException('expected range error', function() { |
| spannable.setSpan({}, -1, 0); |
| }, 'RangeError'); |
| |
| // End index out of range. |
| assertException('expected range error', function() { |
| spannable.setSpan({}, 0, 12); |
| }, 'RangeError'); |
| |
| // End before start. |
| assertException('expected range error', function() { |
| spannable.setSpan({}, 1, 0); |
| }, 'RangeError'); |
| }); |
| |
| /** |
| * Tests that multiple spans can be retrieved at one point. |
| * The first one added which applies should be returned by getSpan. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'MultipleSpans', function() { |
| var annotation1 = { number: 1 }; |
| var annotation2 = { number: 2 }; |
| assertNotSame(annotation1, annotation2); |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(annotation1, 1, 4); |
| spannable.setSpan(annotation2, 2, 7); |
| assertSame(annotation1, spannable.getSpan(1)); |
| assertThat([annotation1], eqJSON(spannable.getSpans(1))); |
| assertSame(annotation1, spannable.getSpan(3)); |
| assertThat([annotation1, annotation2], eqJSON(spannable.getSpans(3))); |
| assertSame(annotation2, spannable.getSpan(6)); |
| assertThat([annotation2], eqJSON(spannable.getSpans(6))); |
| }); |
| |
| /** Tests that appending appends the strings. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'AppendToString', function() { |
| var spannable = new Spannable('Google'); |
| assertEquals('Google', spannable.toString()); |
| spannable.append(' Chrome'); |
| assertEquals('Google Chrome', spannable.toString()); |
| spannable.append(new Spannable('Vox')); |
| assertEquals('Google ChromeVox', spannable.toString()); |
| }); |
| |
| /** |
| * Tests that appending Spannables combines annotations. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'AppendAnnotations', function() { |
| var annotation1 = { number: 1 }; |
| var annotation2 = { number: 2 }; |
| assertNotSame(annotation1, annotation2); |
| var left = new Spannable('hello'); |
| left.setSpan(annotation1, 0, 3); |
| var right = new Spannable(' world'); |
| right.setSpan(annotation2, 0, 3); |
| left.append(right); |
| assertSame(annotation1, left.getSpan(1)); |
| assertSame(annotation2, left.getSpan(6)); |
| }); |
| |
| /** |
| * Tests that a span's bounds can be retrieved. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanStartAndEndAndLength', function() { |
| var annotation = {}; |
| var spannable = new Spannable('potato wedges'); |
| spannable.setSpan(annotation, 8, 12); |
| assertEquals(8, spannable.getSpanStart(annotation)); |
| assertEquals(12, spannable.getSpanEnd(annotation)); |
| assertEquals(4, spannable.getSpanLength(annotation)); |
| }); |
| |
| /** |
| * Tests that an absent span's bounds are reported correctly. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanStartAndEndAndLengthAbsent', |
| function() { |
| var annotation = {}; |
| var spannable = new Spannable('potato wedges'); |
| assertSpanNotFound(spannable, annotation); |
| }); |
| |
| /** |
| * Test that a zero length span can still be found. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanStartAndEndAndLengthZeroLength', |
| function() { |
| var annotation = {}; |
| var spannable = new Spannable('potato wedges'); |
| spannable.setSpan(annotation, 8, 8); |
| assertEquals(8, spannable.getSpanStart(annotation)); |
| assertEquals(8, spannable.getSpanEnd(annotation)); |
| assertEquals(0, spannable.getSpanLength(annotation)); |
| }); |
| |
| /** |
| * Tests that == (but not ===) objects are treated distinctly when getting |
| * span bounds. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanStartAndEndEquality', function() { |
| // Note that 0 == '' and '' == 0 in JavaScript. |
| var spannable = new Spannable('wat'); |
| spannable.setSpan(0, 0, 0); |
| spannable.setSpan('', 1, 3); |
| assertEquals(0, spannable.getSpanStart(0)); |
| assertEquals(0, spannable.getSpanEnd(0)); |
| assertEquals(1, spannable.getSpanStart('')); |
| assertEquals(3, spannable.getSpanEnd('')); |
| }); |
| |
| /** |
| * Tests that substrings have the correct character sequence. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'Substring', function() { |
| var assertSubstringResult = function(expected, initial, start, opt_end) { |
| var spannable = new Spannable(initial); |
| var substring = spannable.substring(start, opt_end); |
| assertEquals(expected, substring.toString()); |
| }; |
| assertSubstringResult('Page', 'Google PageRank', 7, 11); |
| assertSubstringResult('Goog', 'Google PageRank', 0, 4); |
| assertSubstringResult('Rank', 'Google PageRank', 11, 15); |
| assertSubstringResult('Rank', 'Google PageRank', 11); |
| }); |
| |
| /** |
| * Tests that substring arguments are validated properly. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SubstringRangeError', function() { |
| var assertRangeError = function(initial, start, opt_end) { |
| var spannable = new Spannable(initial); |
| assertException('expected range error', function() { |
| spannable.substring(start, opt_end); |
| }, 'RangeError'); |
| }; |
| assertRangeError('Google PageRank', -1, 5); |
| assertRangeError('Google PageRank', 0, 99); |
| assertRangeError('Google PageRank', 5, 2); |
| }); |
| |
| /** |
| * Tests that spans in the substring range are preserved. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SubstringSpansIncluded', function() { |
| var assertSpanIncluded = function(expectedSpanStart, expectedSpanEnd, |
| initial, initialSpanStart, initialSpanEnd, start, opt_end) { |
| var annotation = {}; |
| var spannable = new Spannable(initial); |
| spannable.setSpan(annotation, initialSpanStart, initialSpanEnd); |
| var substring = spannable.substring(start, opt_end); |
| assertTrue(substring.hasSpan(annotation)); |
| assertEquals(expectedSpanStart, substring.getSpanStart(annotation)); |
| assertEquals(expectedSpanEnd, substring.getSpanEnd(annotation)); |
| }; |
| assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7); |
| assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7, 13); |
| assertSpanIncluded(1, 5, 'potato wedges', 8, 12, 7, 12); |
| assertSpanIncluded(0, 4, 'potato wedges', 8, 12, 8, 12); |
| assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0); |
| assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0, 3); |
| assertSpanIncluded(0, 3, 'potato wedges', 0, 3, 0, 6); |
| assertSpanIncluded(0, 5, 'potato wedges', 8, 13, 8); |
| assertSpanIncluded(0, 5, 'potato wedges', 8, 13, 8, 13); |
| assertSpanIncluded(1, 6, 'potato wedges', 8, 13, 7, 13); |
| |
| // Note: we should keep zero-length spans, even at the edges of the range. |
| assertSpanIncluded(0, 0, 'potato wedges', 0, 0, 0, 0); |
| assertSpanIncluded(0, 0, 'potato wedges', 0, 0, 0, 6); |
| assertSpanIncluded(1, 1, 'potato wedges', 8, 8, 7, 13); |
| assertSpanIncluded(6, 6, 'potato wedges', 6, 6, 0, 6); |
| }); |
| |
| /** |
| * Tests that spans outside the range are omitted. |
| * It's fine to keep zero-length spans at the ends, though. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SubstringSpansExcluded', function() { |
| var assertSpanExcluded = function(initial, spanStart, spanEnd, |
| start, opt_end) { |
| var annotation = {}; |
| var spannable = new Spannable(initial); |
| spannable.setSpan(annotation, spanStart, spanEnd); |
| var substring = spannable.substring(start, opt_end); |
| assertSpanNotFound(substring, annotation); |
| }; |
| assertSpanExcluded('potato wedges', 8, 12, 0, 6); |
| assertSpanExcluded('potato wedges', 7, 12, 0, 6); |
| assertSpanExcluded('potato wedges', 0, 6, 8); |
| assertSpanExcluded('potato wedges', 6, 6, 8); |
| }); |
| |
| /** |
| * Tests that spans which cross the boundary are clipped. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'SubstringSpansClipped', function() { |
| var assertSpanIncluded = function(expectedSpanStart, expectedSpanEnd, |
| initial, initialSpanStart, initialSpanEnd, start, opt_end) { |
| var annotation = {}; |
| var spannable = new Spannable(initial); |
| spannable.setSpan(annotation, initialSpanStart, initialSpanEnd); |
| var substring = spannable.substring(start, opt_end); |
| assertEquals(expectedSpanStart, substring.getSpanStart(annotation)); |
| assertEquals(expectedSpanEnd, substring.getSpanEnd(annotation)); |
| }; |
| assertSpanIncluded(0, 4, 'potato wedges', 7, 13, 8, 12); |
| assertSpanIncluded(0, 0, 'potato wedges', 0, 6, 0, 0); |
| assertSpanIncluded(0, 0, 'potato wedges', 0, 6, 6, 6); |
| |
| // The first of the above should produce "edge". |
| assertEquals('edge', |
| new Spannable('potato wedges').substring(8, 12).toString()); |
| }); |
| |
| /** |
| * Tests that whitespace is trimmed. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'Trim', function() { |
| var assertTrimResult = function(expected, initial) { |
| assertEquals(expected, new Spannable(initial).trim().toString()); |
| }; |
| assertTrimResult('John F. Kennedy', 'John F. Kennedy'); |
| assertTrimResult('John F. Kennedy', ' John F. Kennedy'); |
| assertTrimResult('John F. Kennedy', 'John F. Kennedy '); |
| assertTrimResult('John F. Kennedy', ' \r\t \nJohn F. Kennedy\n\n \n'); |
| assertTrimResult('', ''); |
| assertTrimResult('', ' \t\t \n\r'); |
| }); |
| |
| /** |
| * Tests that trim keeps, drops and clips spans. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'TrimSpans', function() { |
| var spannable = new Spannable(' \t Kennedy\n'); |
| spannable.setSpan('tab', 1, 2); |
| spannable.setSpan('jfk', 3, 10); |
| spannable.setSpan('jfk-newline', 3, 11); |
| var trimmed = spannable.trim(); |
| assertSpanNotFound(trimmed, 'tab'); |
| assertEquals(0, trimmed.getSpanStart('jfk')); |
| assertEquals(7, trimmed.getSpanEnd('jfk')); |
| assertEquals(0, trimmed.getSpanStart('jfk-newline')); |
| assertEquals(7, trimmed.getSpanEnd('jfk-newline')); |
| }); |
| |
| /** |
| * Tests that when a string is all whitespace, we trim off the *end*. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'TrimAllWhitespace', function() { |
| var spannable = new Spannable(' '); |
| spannable.setSpan('cursor 1', 0, 0); |
| spannable.setSpan('cursor 2', 2, 2); |
| var trimmed = spannable.trim(); |
| assertEquals(0, trimmed.getSpanStart('cursor 1')); |
| assertEquals(0, trimmed.getSpanEnd('cursor 1')); |
| assertSpanNotFound(trimmed, 'cursor 2'); |
| }); |
| |
| /** |
| * Tests finding a span which is an instance of a given class. |
| */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanInstanceOf', function() { |
| function ExampleConstructorBase() {} |
| function ExampleConstructor1() {} |
| function ExampleConstructor2() {} |
| function ExampleConstructor3() {} |
| ExampleConstructor1.prototype = new ExampleConstructorBase(); |
| ExampleConstructor2.prototype = new ExampleConstructorBase(); |
| ExampleConstructor3.prototype = new ExampleConstructorBase(); |
| var ex1 = new ExampleConstructor1(); |
| var ex2 = new ExampleConstructor2(); |
| var spannable = new Spannable('Hello world'); |
| spannable.setSpan(ex1, 0, 0); |
| spannable.setSpan(ex2, 1, 1); |
| assertEquals(ex1, spannable.getSpanInstanceOf(ExampleConstructor1)); |
| assertEquals(ex2, spannable.getSpanInstanceOf(ExampleConstructor2)); |
| assertUndefined(spannable.getSpanInstanceOf(ExampleConstructor3)); |
| assertEquals(ex1, spannable.getSpanInstanceOf(ExampleConstructorBase)); |
| }); |
| |
| /** Tests trimming only left or right. */ |
| TEST_F('ChromeVoxSpannableUnitTest', 'TrimLeftOrRight', function() { |
| var spannable = new Spannable(' '); |
| spannable.setSpan('cursor 1', 0, 0); |
| spannable.setSpan('cursor 2', 2, 2); |
| var trimmed = spannable.trimLeft(); |
| assertEquals(0, trimmed.getSpanStart('cursor 1')); |
| assertEquals(0, trimmed.getSpanEnd('cursor 1')); |
| assertSpanNotFound(trimmed, 'cursor 2'); |
| |
| var spannable2 = new Spannable('0 '); |
| spannable2.setSpan('cursor 1', 0, 0); |
| spannable2.setSpan('cursor 2', 2, 2); |
| var trimmed2 = spannable2.trimLeft(); |
| assertEquals(0, trimmed2.getSpanStart('cursor 1')); |
| assertEquals(0, trimmed2.getSpanEnd('cursor 1')); |
| assertEquals(2, trimmed2.getSpanStart('cursor 2')); |
| assertEquals(2, trimmed2.getSpanEnd('cursor 2')); |
| trimmed2 = trimmed2.trimRight(); |
| assertEquals(0, trimmed2.getSpanStart('cursor 1')); |
| assertEquals(0, trimmed2.getSpanEnd('cursor 1')); |
| assertSpanNotFound(trimmed2, 'cursor 2'); |
| |
| var spannable3 = new Spannable(' 0'); |
| spannable3.setSpan('cursor 1', 0, 0); |
| spannable3.setSpan('cursor 2', 2, 2); |
| var trimmed3 = spannable3.trimRight(); |
| assertEquals(0, trimmed3.getSpanStart('cursor 1')); |
| assertEquals(0, trimmed3.getSpanEnd('cursor 1')); |
| assertEquals(2, trimmed3.getSpanStart('cursor 2')); |
| assertEquals(2, trimmed3.getSpanEnd('cursor 2')); |
| trimmed3 = trimmed3.trimLeft(); |
| assertSpanNotFound(trimmed3, 'cursor 1'); |
| assertEquals(0, trimmed3.getSpanStart('cursor 2')); |
| assertEquals(0, trimmed3.getSpanEnd('cursor 2')); |
| }); |
| |
| TEST_F('ChromeVoxSpannableUnitTest', 'Serialize', function() { |
| var fresh = new Spannable('text'); |
| var freshStatelessSerializable = new StatelessSerializableSpan(); |
| var freshNonStatelessSerializable = new NonStatelessSerializableSpan(14); |
| fresh.setSpan(new UnserializableSpan(), 0, 1); |
| fresh.setSpan(freshStatelessSerializable, 0, 2); |
| fresh.setSpan(freshNonStatelessSerializable, 3, 4); |
| var thawn = Spannable.fromJson(fresh.toJson()); |
| var thawnStatelessSerializable = thawn.getSpanInstanceOf( |
| StatelessSerializableSpan); |
| var thawnNonStatelessSerializable = thawn.getSpanInstanceOf( |
| NonStatelessSerializableSpan); |
| assertThat('text', eqJSON(thawn.toString())); |
| assertUndefined(thawn.getSpanInstanceOf(UnserializableSpan)); |
| assertThat( |
| fresh.getSpanStart(freshStatelessSerializable), |
| eqJSON(thawn.getSpanStart(thawnStatelessSerializable))); |
| assertThat( |
| fresh.getSpanEnd(freshStatelessSerializable), |
| eqJSON(thawn.getSpanEnd(thawnStatelessSerializable))); |
| assertThat(freshNonStatelessSerializable, |
| eqJSON(thawnNonStatelessSerializable)); |
| }); |
| |
| TEST_F('ChromeVoxSpannableUnitTest', 'GetSpanIntervals', function() { |
| function Foo() {} |
| function Bar() {} |
| var ms = new MultiSpannable('f12b45f78b01'); |
| var foo = new Foo(); |
| var bar = new Bar(); |
| ms.setSpan(foo, 0, 3); |
| ms.setSpan(bar, 3, 6); |
| ms.setSpan(foo, 6, 9); |
| ms.setSpan(bar, 9, 12); |
| assertEquals(2, ms.getSpansInstanceOf(Foo).length); |
| assertEquals(2, ms.getSpansInstanceOf(Bar).length); |
| |
| var fooIntervals = ms.getSpanIntervals(foo); |
| assertEquals(2, fooIntervals.length); |
| assertEquals(0, fooIntervals[0].start); |
| assertEquals(3, fooIntervals[0].end); |
| assertEquals(6, fooIntervals[1].start); |
| assertEquals(9, fooIntervals[1].end); |
| |
| var barIntervals = ms.getSpanIntervals(bar); |
| assertEquals(2, barIntervals.length); |
| assertEquals(3, barIntervals[0].start); |
| assertEquals(6, barIntervals[0].end); |
| assertEquals(9, barIntervals[1].start); |
| assertEquals(12, barIntervals[1].end); |
| }); |