summaryrefslogtreecommitdiffstats
path: root/dom/system/tests/ioutils/test_ioutils_read_write_json.html
blob: e356e50c47d4481ac3c847c9f830dd65a5a9b652 (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <title>Test the IOUtils file I/O API</title>
  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
  <script src="file_ioutils_test_fixtures.js"></script>
  <script>
    "use strict";

    const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
    const { ObjectUtils } = ChromeUtils.import(
      "resource://gre/modules/ObjectUtils.jsm"
    );

    const OBJECT = {
      "foo": [
        "bar",
        123,
        456.789,
        true,
        false,
        null,
      ],
      "bar": {
        "baz": {},
      },
    };

    const ARRAY = [1, 2.3, true, false, null, { "foo": "bar" }];

    const PRIMITIVES = [123, true, false, "hello, world", null];

    add_task(async function read_json() {
      const filename = PathUtils.join(PathUtils.tempDir, "test_ioutils_read_json.tmp");

      info("Testing IOUtils.readJSON() with a serialized object...");
      await IOUtils.writeUTF8(filename, JSON.stringify(OBJECT));
      const readObject = await IOUtils.readJSON(filename);
      const parsedObject = JSON.parse(await IOUtils.readUTF8(filename));
      ok(ObjectUtils.deepEqual(OBJECT, readObject), "JSON objects should round-trip");
      ok(
        ObjectUtils.deepEqual(parsedObject, readObject),
        "IOUtils.readJSON() equivalent to JSON.parse() for objects"
      );

      info("Testing IOUtils.readJSON() with a serialized array...");
      await IOUtils.writeUTF8(filename, JSON.stringify(ARRAY));
      const readArray = await IOUtils.readJSON(filename);
      const parsedArray = JSON.parse(await IOUtils.readUTF8(filename));
      ok(ObjectUtils.deepEqual(ARRAY, readArray), "JSON arrays should round-trip");
      ok(
        ObjectUtils.deepEqual(parsedArray, readArray),
        "IOUtils.readJSON() equivalent to JSON.parse(IOUtils.readUTF8()) for arrays"
      );

      info("Testing IOUtils.readJSON() with serialized primitives...");
      for (const primitive of PRIMITIVES) {
        await IOUtils.writeUTF8(filename, JSON.stringify(primitive));
        const readPrimitive = await IOUtils.readJSON(filename);
        const parsedPrimitive = JSON.parse(await IOUtils.readUTF8(filename));
        ok(primitive === readPrimitive, `JSON primitive ${primitive} should round trip`);
        ok(
          readPrimitive === parsedPrimitive,
          `${readPrimitive} === ${parsedPrimitive} -- IOUtils.readJSON() equivalent to JSON.parse() for primitive`
        );
      }

      info("Testing IOUtils.readJSON() with a file that does not exist...");
      const notExistsFilename = PathUtils.join(PathUtils.tempDir, "test_ioutils_read_json_not_exists.tmp");
      ok(!await IOUtils.exists(notExistsFilename), `${notExistsFilename} should not exist`);
      await Assert.rejects(
        IOUtils.readJSON(notExistsFilename),
        /NotFoundError: Could not open the file at/,
        "IOUtils::readJSON rejects when file does not exist"
      );

      info("Testing IOUtils.readJSON() with a file that does not contain JSON");
      const invalidFilename = PathUtils.join(PathUtils.tempDir, "test_ioutils_read_json_invalid.tmp");
      await IOUtils.writeUTF8(invalidFilename, ":)");

      await Assert.rejects(
        IOUtils.readJSON(invalidFilename),
        /SyntaxError: JSON\.parse/,
        "IOUTils::readJSON rejects when the file contains invalid JSON"
      );

      await cleanup(filename, invalidFilename);
    });

    add_task(async function write_json() {
      const filename = PathUtils.join(PathUtils.tempDir, "test_ioutils_write_json.tmp");

      info("Testing IOUtils.writeJSON() with an object...");
      await IOUtils.writeJSON(filename, OBJECT);
      const readObject = await IOUtils.readJSON(filename);
      const readObjectStr = await IOUtils.readUTF8(filename);
      ok(ObjectUtils.deepEqual(OBJECT, readObject), "JSON objects should round-trip");
      ok(
        readObjectStr === JSON.stringify(OBJECT),
        "IOUtils.writeJSON() eqvuialent to JSON.stringify() for an object"
      );

      info("Testing IOUtils.writeJSON() with an array...");
      await IOUtils.writeJSON(filename, ARRAY);
      const readArray = await IOUtils.readJSON(filename);
      const readArrayStr = await IOUtils.readUTF8(filename);
      ok(ObjectUtils.deepEqual(ARRAY, readArray), "JSON arrays should round-trip");
      ok(
        readArrayStr === JSON.stringify(ARRAY),
        "IOUtils.writeJSON() equivalent to JSON.stringify() for an array"
      );

      info("Testing IOUtils.writeJSON() with primitives...");
      for (const primitive of PRIMITIVES) {
        await IOUtils.writeJSON(filename, primitive);
        const readPrimitive = await IOUtils.readJSON(filename);
        const readPrimitiveStr = await IOUtils.readUTF8(filename);
        ok(
          primitive === readPrimitive,
          `${primitive} === ${readPrimitive} -- IOUtils.writeJSON() should round trip primitive`
        );
        ok(
          readPrimitiveStr === JSON.stringify(primitive),
          `${readPrimitiveStr} === ${JSON.stringify(primitive)} -- IOUtils.writeJSON() equivalent to JSON.stringify for primitive`
        );
      }

      info("Testing IOUtils.writeJSON() with unserializable objects...");
      await Assert.rejects(
        IOUtils.writeJSON(filename, window),
        /TypeError: cyclic object value/,
        "IOUtils.writeJSON() cannot write cyclic objects"
      );

      await cleanup(filename);
    });

    add_task(async function test_append_json() {
      const filename = PathUtils.join(PathUtils.tempDir, "test_ioutils_append_json.tmp");

      await IOUtils.writeJSON(filename, OBJECT);

      await Assert.rejects(
        IOUtils.writeJSON(filename, OBJECT, {mode: "append"}),
        /NotSupportedError: IOUtils.writeJSON does not support appending to files/,
        "IOUtils.writeJSON() cannot append"
      );

      await cleanup(filename);
    });
  </script>
</head>

<body>
  <p id="display"></p>
  <div id="content" style="display: none"></div>
  <pre id="test"></pre>
</body>

</html>