summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/generic-sensor/resources/generic-sensor-helpers.js
blob: 9a51a591ce116e981310c0f1eb37cfc7eac722fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
'use strict';

// These tests rely on the User Agent providing an implementation of
// platform sensor backends.
//
// In Chromium-based browsers this implementation is provided by a polyfill
// in order to reduce the amount of test-only code shipped to users. To enable
// these tests the browser must be run with these options:
//
//   --enable-blink-features=MojoJS,MojoJSTest
async function loadChromiumResources() {
  await loadScript('/resources/testdriver.js');
  await loadScript('/resources/testdriver-vendor.js');
  await loadScript('/page-visibility/resources/window_state_context.js');
  await import('/resources/chromium/generic_sensor_mocks.js');
}

async function initialize_generic_sensor_tests() {
  if (typeof GenericSensorTest === 'undefined') {
    const script = document.createElement('script');
    script.src = '/resources/test-only-api.js';
    script.async = false;
    const p = new Promise((resolve, reject) => {
      script.onload = () => { resolve(); };
      script.onerror = e => { reject(e); };
    })
    document.head.appendChild(script);
    await p;

    if (isChromiumBased) {
      await loadChromiumResources();
    }
  }

  let sensorTest = new GenericSensorTest();
  await sensorTest.initialize();
  return sensorTest;
}

function sensor_test(func, name, properties) {
  promise_test(async (t) => {
    t.add_cleanup(() => {
      if (sensorTest)
        return sensorTest.reset();
    });

    let sensorTest = await initialize_generic_sensor_tests();
    return func(t, sensorTest.getSensorProvider());
  }, name, properties);
}

function verifySensorReading(pattern, values, timestamp, isNull) {
  // If |val| cannot be converted to a float, we return the original value.
  // This can happen when a value in |pattern| is not a number.
  function round(val) {
    const res = Number.parseFloat(val).toPrecision(6);
    return res === "NaN" ? val : res;
  }

  if (isNull) {
    return (values === null || values.every(r => r === null)) &&
           timestamp === null;
  }

  return values.every((r, i) => round(r) === round(pattern[i])) &&
         timestamp !== null;
}

function verifyXyzSensorReading(pattern, {x, y, z, timestamp}, isNull) {
  return verifySensorReading(pattern, [x, y, z], timestamp, isNull);
}

function verifyQuatSensorReading(pattern, {quaternion, timestamp}, isNull) {
  return verifySensorReading(pattern, quaternion, timestamp, isNull);
}

function verifyAlsSensorReading(pattern, {illuminance, timestamp}, isNull) {
  return verifySensorReading(pattern, [illuminance], timestamp, isNull);
}

function verifyGeoSensorReading(pattern, {latitude, longitude, altitude,
  accuracy, altitudeAccuracy, heading, speed, timestamp}, isNull) {
  return verifySensorReading(pattern, [latitude, longitude, altitude,
    accuracy, altitudeAccuracy, heading, speed], timestamp, isNull);
}

function verifyProximitySensorReading(pattern, {distance, max, near, timestamp}, isNull) {
  return verifySensorReading(pattern, [distance, max, near], timestamp, isNull);
}

// Assert that two Sensor objects have the same properties and values.
//
// Verifies that ``actual`` and ``expected`` have the same sensor properties
// and, if so, that their values are the same.
//
// @param {Sensor} actual - Test value.
// @param {Sensor} expected - Expected value.
function assert_sensor_equals(actual, expected) {
  assert_true(
      actual instanceof Sensor,
      'assert_sensor_equals: actual must be a Sensor');
  assert_true(
      expected instanceof Sensor,
      'assert_sensor_equals: expected must be a Sensor');

  // These properties vary per sensor type.
  const CUSTOM_PROPERTIES = [
    ['illuminance'], ['quaternion'], ['x', 'y', 'z'],
    [
      'latitude', 'longitude', 'altitude', 'accuracy', 'altitudeAccuracy',
      'heading', 'speed'
    ]
  ];

  // These properties are present on all objects derived from Sensor.
  const GENERAL_PROPERTIES = ['timestamp'];

  for (let customProperties of CUSTOM_PROPERTIES) {
    if (customProperties.every(p => p in actual) &&
        customProperties.every(p => p in expected)) {
      customProperties.forEach(p => {
        if (customProperties == 'quaternion') {
          assert_array_equals(
              actual[p], expected[p],
              `assert_sensor_equals: property '${p}' does not match`);
        } else {
          assert_equals(
              actual[p], expected[p],
              `assert_sensor_equals: property '${p}' does not match`);
        }
      });
      GENERAL_PROPERTIES.forEach(p => {
        assert_equals(
            actual[p], expected[p],
            `assert_sensor_equals: property '${p}' does not match`);
      });
      return;
    }
  }

  assert_true(false, 'assert_sensor_equals: sensors have different attributes');
}