1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Include test fixture.
6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js',
7 '../testing/assert_additions.js']);
12 * @extends {ChromeVoxUnitTestBase}
14 function CvoxExpandingBrailleTranslatorUnitTest() {}
16 CvoxExpandingBrailleTranslatorUnitTest.prototype = {
17 __proto__: ChromeVoxUnitTestBase.prototype,
21 'cvox.ExpandingBrailleTranslator',
24 'cvox.ValueSelectionSpan',
30 * An implementation of {@link cvox.LibLouis.Translator} whose translation
31 * output is an array buffer of the same byte length as the input and where
32 * each byte is equal to the character code of {@code resultChar}. The
33 * position mappings are one to one in both directions.
34 * @param {string} resultChar A one character string used for each byte of the
37 * @extends {cvox.LibLouis.Translator}
39 function FakeTranslator(resultChar) {
40 /** @private {string} */
41 this.resultChar_ = resultChar;
44 FakeTranslator.prototype = {
46 translate: function(text, callback) {
47 var result = new Uint8Array(text.length);
48 var textToBraille = [];
49 var brailleToText = [];
50 for (var i = 0; i < text.length; ++i) {
51 result[i] = this.resultChar_.charCodeAt(0);
52 textToBraille.push(i);
53 brailleToText.push(i);
55 callback(result.buffer, textToBraille, brailleToText);
60 * Asserts that a array buffer, viewed as an uint8 array, matches
61 * the contents of a string. The character code of each character of the
62 * string shall match the corresponding byte in the array buffer.
63 * @param {ArrayBuffer} actual Actual array buffer.
64 * @param {string} expected Array of expected bytes.
66 function assertArrayBufferMatches(expected, actual) {
67 assertTrue(actual instanceof ArrayBuffer);
68 var a = new Uint8Array(actual);
69 assertEquals(expected.length, a.length);
70 for (var i = 0; i < a.length; ++i) {
71 assertEquals(expected.charCodeAt(i), a[i], 'Position ' + i);
75 TEST_F('CvoxExpandingBrailleTranslatorUnitTest', 'TranslationError',
77 var text = new cvox.Spannable('error ok', new cvox.ValueSpan());
78 text.setSpan(new cvox.ValueSelectionSpan, 0, 0);
79 var contractedTranslator = new FakeTranslator('c');
80 // Translator that always results in an error.
81 var uncontractedTranslator = {
82 translate: function(text, callback) {
83 callback(null, null, null);
86 var translationResult = null;
88 var expandingTranslator = new cvox.ExpandingBrailleTranslator(
89 contractedTranslator, uncontractedTranslator);
90 expandingTranslator.translate(
91 text, cvox.ExpandingBrailleTranslator.ExpansionType.SELECTION,
92 function(cells, textToBraille, brailleToText) {
93 // Expect the string ' ok' to be translated using the contracted
94 // translator. The preceding part isn't included because it resulted
95 // in a translation error.
96 assertArrayBufferMatches('ccc', cells);
97 assertEqualsJSON([0, 0, 0, 0, 0, 0, 1, 2], textToBraille);
98 assertEqualsJSON([5, 6, 7], brailleToText);
102 // Test for many variations of successful translations.
104 var totalRunTranslationTests = 0;
107 * Performs the translation and checks the output.
108 * @param {string} name Name that describes the input for error messages.
109 * @param {boolean} contracted Whether to use a contracted translator
110 * in addition to the uncontracted one.
111 * @param {cvox.ExpandingBrailleTranslator.ExpansionType} valueExpansion
112 * Value expansion argument to pass to the translator.
113 * @param {string} text Input string.
114 * @param {string} expectedOutput Expected output as a string (see
115 * {@code TESTDATA} below for a description of the format).
117 function doTranslationTest(name, contracted, valueExpansion, text,
119 totalRunTranslationTests++;
120 var uncontractedTranslator = new FakeTranslator('u');
121 var expandingTranslator;
123 var contractedTranslator = new FakeTranslator('c');
124 expandingTranslator = new cvox.ExpandingBrailleTranslator(
125 contractedTranslator, uncontractedTranslator);
127 expandingTranslator = new cvox.ExpandingBrailleTranslator(
128 uncontractedTranslator);
130 var expectedMapping = [];
131 for (var i = 0; i < expectedOutput.length; ++i) {
132 expectedMapping[i] = i;
135 expandingTranslator.translate(
136 text, valueExpansion, function(cells, textToBraille, brailleToText) {
137 assertArrayBufferMatches(expectedOutput, cells, name);
138 assertEqualsJSON(expectedMapping, textToBraille, name);
139 assertEqualsJSON(expectedMapping, brailleToText, name);
144 * Runs two tests, one with the given values and one with the given values
145 * where the text is surrounded by a typical name and role.
146 * @param {{name: string, input: string, contractedOutput: string}}
147 * testCase An entry of {@code TESTDATA}.
148 * @param {boolean} contracted Whether to use both uncontracted
149 * and contracted translators.
150 * @param {cvox.ExpandingBrailleTranslation.ExpansionType} valueExpansion
151 * What kind of value expansion to apply.
152 * @param {cvox.Spannable} text Input text.
153 * @param {string=} opt_expectedContractedOutput Expected output (see
156 function runTranslationTestVariants(testCase, contracted, valueExpansion) {
157 var expType = cvox.ExpandingBrailleTranslator.ExpansionType;
158 // Construct the full name.
159 var fullName = contracted ? 'Contracted_' : 'Uncontracted_';
160 fullName += 'Expansion' + valueExpansion + '_';
161 fullName += testCase.name;
162 // The expected output depends on the contraction mode and value expansion.
163 var outputChar = contracted ? 'c' : 'u';
165 if (contracted && valueExpansion === expType.SELECTION) {
166 expectedOutput = testCase.contractedOutput;
167 } else if (contracted && valueExpansion === expType.ALL) {
168 expectedOutput = new Array(testCase.input.getLength() + 1).join('u');
171 new Array(testCase.input.getLength() + 1).join(outputChar);
173 doTranslationTest(fullName, contracted, valueExpansion, testCase.input,
176 // Run another test, with the value surrounded by some text.
177 var surroundedText = new cvox.Spannable('Name: ');
178 var surroundedExpectedOutput =
179 new Array('Name: '.length + 1).join(outputChar);
180 surroundedText.append(testCase.input);
181 surroundedExpectedOutput += expectedOutput;
182 if (testCase.input.getLength() > 0) {
183 surroundedText.append(' ');
184 surroundedExpectedOutput += outputChar;
186 surroundedText.append('edtxt');
187 surroundedExpectedOutput +=
188 new Array('edtxt'.length + 1).join(outputChar);
189 doTranslationTest(fullName + '_Surrounded', contracted, valueExpansion,
190 surroundedText, surroundedExpectedOutput);
194 * Creates a spannable text with optional selection.
195 * @param {string} text The text.
196 * @param {=opt_selectionStart} Selection start or caret position. No
197 * selection is added if undefined.
198 * @param {=opt_selectionEnd} Selection end if selection is not a caret.
200 function createText(text, opt_selectionStart, opt_selectionEnd) {
201 var result = new cvox.Spannable(text);
203 result.setSpan(new cvox.ValueSpan, 0, text.length);
204 if (goog.isDef(opt_selectionStart)) {
206 new cvox.ValueSelectionSpan,
208 goog.isDef(opt_selectionEnd) ? opt_selectionEnd : opt_selectionStart);
214 var TEXT = 'Hello, world!';
216 TEST_F('CvoxExpandingBrailleTranslatorUnitTest', 'successfulTranslations',
219 * Dictionary of test strings, keyed on a descriptive name for the
220 * test case. The value is an array of the input string to the translation
221 * and the expected output using a translator with both uncontracted
222 * and contracted underlying translators. The expected output is
223 * in the form of a string of the same length as the input, where an 'u'
224 * means that the uncontracted translator was used at this location and a
225 * 'c' means that the contracted translator was used.
229 input: createText(''),
230 contractedOutput: '' },
231 { name: 'emptyTextWithCaret',
232 input: createText('', 0),
233 contractedOutput: '' },
234 { name: 'textWithNoSelection',
235 input: createText(TEXT),
236 contractedOutput: 'ccccccccccccc' },
237 { name: 'textWithCaretAtStart',
238 input: createText(TEXT, 0),
239 contractedOutput: 'uuuuuuccccccc' },
240 { name: 'textWithCaretAtEnd',
241 input: createText(TEXT, TEXT.length),
242 contractedOutput: 'cccccccuuuuuu' },
243 { name: 'textWithCaretInWhitespace',
244 input: createText(TEXT, 6),
245 contractedOutput: 'uuuuuuucccccc' },
246 { name: 'textWithSelectionEndInWhitespace',
247 input: createText(TEXT, 0, 7),
248 contractedOutput: 'uuuuuuucccccc' },
249 { name: 'textWithSelectionInTwoWords',
250 input: createText(TEXT, 2, 9),
251 contractedOutput: 'uuuuuucuuuuuu' }
254 var expType = cvox.ExpandingBrailleTranslator.ExpansionType;
255 for (var i = 0, testCase; testCase = TESTDATA[i]; ++i) {
256 runTranslationTestVariants(testCase, false, expType.SELECTION);
257 runTranslationTestVariants(testCase, true, expType.NONE);
258 runTranslationTestVariants(testCase, true, expType.SELECTION);
259 runTranslationTestVariants(testCase, true, expType.ALL);
261 // Make sure that the logic above runs the tests, adjust when adding more
263 assertEquals(64, totalRunTranslationTests);