tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

translator.optional.https.window.js (9280B)


      1 // META: title=Optional Translator tests
      2 // META: global=window
      3 // META: timeout=long
      4 // META: script=../resources/util.js
      5 // META: script=/common/gc.js
      6 // META: script=/resources/testdriver.js
      7 // META: script=resources/util.js
      8 //
      9 // Setting `timeout=long` as this test may require downloading the translation
     10 // library and the language models.
     11 
     12 'use strict';
     13 
     14 // TODO(crbug.com/390246212): Support model state controls for WPTs.
     15 promise_test(async t => {
     16  // Create requires user activation when availability is 'downloadable'.
     17  const languagePair = {sourceLanguage: 'en', targetLanguage: 'ja'};
     18  assert_implements_optional(await Translator.availability(languagePair) == 'downloadable');
     19  assert_false(navigator.userActivation.isActive);
     20  await promise_rejects_dom(t, 'NotAllowedError', Translator.create(languagePair));
     21  await test_driver.bless('Translator.create', async () => { await Translator.create(languagePair); });
     22 
     23  // Create does not require user activation when availability is 'available'.
     24  assert_equals(await Translator.availability(languagePair), 'available');
     25  assert_false(navigator.userActivation.isActive);
     26  await Translator.create(languagePair);
     27 }, 'Create requires user activation when availability is "downloadable"');
     28 
     29 promise_test(async t => {
     30  const translator =
     31      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     32  assert_equals(await translator.translate('hello'), 'こんにちは');
     33 }, 'Simple Translator.translate() call');
     34 
     35 promise_test(async () => {
     36  const translator =
     37      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     38  const streamingResponse = translator.translateStreaming('hello');
     39  assert_equals(
     40      Object.prototype.toString.call(streamingResponse),
     41      '[object ReadableStream]');
     42  let result = '';
     43  for await (const chunk of streamingResponse) {
     44    result += chunk;
     45  }
     46  assert_equals(await translator.translate('hello'), 'こんにちは');
     47 }, 'Simple Translator.translateStreaming() call');
     48 
     49 promise_test(async () => {
     50  const translator =
     51      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     52  const streamingResponse = translator.translateStreaming('Welcome. Nice to meet you.');
     53  assert_equals(
     54      Object.prototype.toString.call(streamingResponse),
     55      '[object ReadableStream]');
     56  let result = '';
     57  for await (const chunk of streamingResponse) {
     58    result += chunk;
     59  }
     60  assert_equals(result, 'ようこそ。 はじめまして。');
     61 }, 'Multiple sentence Translator.translateStreaming() call');
     62 
     63 promise_test(async () => {
     64  const translator =
     65      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     66  const streamingResponse = translator.translateStreaming('Hello, Dr. Sanders. Nice to meet you.');
     67  assert_equals(
     68      Object.prototype.toString.call(streamingResponse),
     69      '[object ReadableStream]');
     70  let result = '';
     71  for await (const chunk of streamingResponse) {
     72    result += chunk;
     73  }
     74  assert_equals(result, 'こんにちは、サンダース博士です。 はじめまして。');
     75 }, 'Multiple sentence Translator.translateStreaming() call with honorific');
     76 
     77 promise_test(async () => {
     78  const translator =
     79      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     80  const streamingResponse = translator.translateStreaming('hello');
     81  garbageCollect();
     82  assert_equals(Object.prototype.toString.call(streamingResponse),
     83                '[object ReadableStream]');
     84  let result = '';
     85  for await (const value of streamingResponse) {
     86    result += value;
     87    garbageCollect();
     88  }
     89  assert_greater_than(result.length, 0, 'The result should not be empty.');
     90 }, 'Translate Streaming API must continue even after GC has been performed.');
     91 
     92 promise_test(async t => {
     93  const translator =
     94      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
     95  assert_equals(translator.sourceLanguage, 'en');
     96  assert_equals(translator.targetLanguage, 'ja');
     97 }, 'Translator: sourceLanguage and targetLanguage are equal to their respective option passed in to Translator.create.');
     98 
     99 promise_test(async t => {
    100  const controller = new AbortController();
    101  controller.abort();
    102 
    103  const createPromise = createTranslator(
    104      {signal: controller.signal, sourceLanguage: 'en', targetLanguage: 'ja'});
    105 
    106  await promise_rejects_dom(t, 'AbortError', createPromise);
    107 }, 'Translator.create() call with an aborted signal.');
    108 
    109 promise_test(async t => {
    110  await testAbortPromise(t, signal => {
    111    return createTranslator(
    112        {signal, sourceLanguage: 'en', targetLanguage: 'ja'});
    113  });
    114 }, 'Aborting Translator.create().');
    115 
    116 promise_test(async t => {
    117  const controller = new AbortController();
    118  controller.abort();
    119 
    120  const translator =
    121      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    122  const translatePromise =
    123      translator.translate('hello', {signal: controller.signal});
    124 
    125  await promise_rejects_dom(t, 'AbortError', translatePromise);
    126 }, 'Translator.translate() call with an aborted signal.');
    127 
    128 promise_test(async t => {
    129  const translator =
    130      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    131  await testAbortPromise(t, signal => {
    132    return translator.translate('hello', {signal});
    133  });
    134 }, 'Aborting Translator.translate().');
    135 
    136 promise_test(async t => {
    137  await testDestroy(
    138    t, createTranslator, { sourceLanguage: 'en', targetLanguage: 'ja' }, [
    139    translator => translator.translate(kTestPrompt),
    140    translator => translator.measureInputUsage(kTestPrompt),
    141  ]);
    142 }, 'Calling Translator.destroy() aborts calls to write and measureInputUsage.');
    143 
    144 promise_test(async (t) => {
    145  const translator =
    146    await createTranslator({ sourceLanguage: 'en', targetLanguage: 'ja' });
    147  const stream = translator.translateStreaming(kTestPrompt);
    148 
    149  translator.destroy();
    150 
    151  await promise_rejects_dom(
    152    t, 'AbortError', stream.pipeTo(new WritableStream()));
    153 }, 'Translator.translateStreaming() fails after destroyed');
    154 
    155 promise_test(async t => {
    156  await testCreateAbort(
    157    t, createTranslator, { sourceLanguage: 'en', targetLanguage: 'ja' }, [
    158    translator => translator.translate(kTestPrompt),
    159    translator => translator.measureInputUsage(kTestPrompt),
    160  ]);
    161 }, 'Translator.create()\'s abort signal destroys its Translator after creation.');
    162 
    163 promise_test(async t => {
    164  await testMonitor(
    165      createTranslator, {sourceLanguage: 'en', targetLanguage: 'ja'});
    166 }, 'Translator.create() notifies its monitor on downloadprogress');
    167 
    168 promise_test(async t => {
    169  await testCreateMonitorWithAbort(
    170      t, createTranslator, {sourceLanguage: 'en', targetLanguage: 'ja'});
    171 }, 'Progress events are not emitted after aborted.');
    172 
    173 promise_test(async t => {
    174  const translator =
    175      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    176 
    177  // Strings containing only white space are not translatable.
    178  const nonTranslatableStrings = ['', ' ', '     ', ' \r\n\t\f'];
    179 
    180  // Strings containing only control characters are not translatable.
    181  for (let c = 0; c < 0x1F; c++) {
    182    nonTranslatableStrings.push(String.fromCharCode(c));
    183  }
    184 
    185  const translatedNonTranslatableString = await Promise.all(
    186      nonTranslatableStrings.map(str => translator.translate(str)));
    187 
    188  // Non translatable strings should be echoed back
    189  assert_array_equals(translatedNonTranslatableString, nonTranslatableStrings);
    190 
    191  // Adding translatable text makes it translatable.
    192  const translatableStrings =
    193      nonTranslatableStrings.map(str => `Hello ${str} world`);
    194 
    195  const translatedTranslatableString = await Promise.all(
    196      translatableStrings.map(str => translator.translate(str)));
    197 
    198  // All the strings should have been translated in some way.
    199  for (let i = 0; i < translatableStrings.length; i++) {
    200    assert_not_equals(translatedTranslatableString[i], translatableStrings[i]);
    201  }
    202 }, 'Translator.translate() echoes non-translatable content');
    203 
    204 promise_test(async t => {
    205  const translator =
    206      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    207 
    208  const text = 'hello';
    209  const inputUsage = await translator.measureInputUsage(text);
    210 
    211  assert_greater_than_equal(translator.inputQuota, 0);
    212  assert_greater_than_equal(inputUsage, 0);
    213 
    214  if (inputUsage < translator.inputQuota) {
    215    assert_equals(await translator.translate(text), 'こんにちは');
    216  } else {
    217    await promise_rejects_quotaexceedederror(t, translator.translate(text), requested => requested !== null, translator.inputQuota);
    218  }
    219 }, 'Translator.measureInputUsage() and inputQuota basic usage.');
    220 
    221 promise_test(async t => {
    222  const controller = new AbortController();
    223  controller.abort();
    224 
    225  const translator =
    226      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    227  const measureInputUsagePromise =
    228      translator.measureInputUsage('hello', {signal: controller.signal});
    229 
    230  await promise_rejects_dom(t, 'AbortError', measureInputUsagePromise);
    231 }, 'Translator.measureInputUsage() call with an aborted signal.');
    232 
    233 promise_test(async t => {
    234  const translator =
    235      await createTranslator({sourceLanguage: 'en', targetLanguage: 'ja'});
    236  await testAbortPromise(t, signal => {
    237    return translator.measureInputUsage('hello', {signal});
    238  });
    239 }, 'Aborting Translator.measureInputUsage().');