summaryrefslogtreecommitdiffstats
path: root/dom/json/test/unit/test_encode.js
blob: 88907efa31fda68e060b1d1a1d0698605119247e (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
var Ci = Components.interfaces;
var Cc = Components.classes;

var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);

var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
var workingDir = dirSvc.get("TmpD", Ci.nsIFile);

var outputName = "json-test-output";
var outputDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
outputDir.initWithFile(workingDir);
outputDir.append(outputName);

if (!outputDir.exists()) {
  outputDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o777);
} else if (!outputDir.isDirectory()) {
  do_throw(outputName + " is not a directory?")
}

function testStringEncode()
{
  var obj1 = {a:1};
  var obj2 = {foo:"bar"};
  do_check_eq(nativeJSON.encode(obj1), '{"a":1}');
  do_check_eq(nativeJSON.encode(obj2), '{"foo":"bar"}');

  do_check_eq(nativeJSON.encode(), null);

  // useless roots are dropped
  do_check_eq(nativeJSON.encode(null), null);
  do_check_eq(nativeJSON.encode(""), null);
  do_check_eq(nativeJSON.encode(undefined), null);
  do_check_eq(nativeJSON.encode(5), null);
  do_check_eq(nativeJSON.encode(function(){}), null);
  do_check_eq(nativeJSON.encode(dump), null);

  // All other testing should occur in js/src/tests/ecma_5/JSON/ using
  // the otherwise-exactly-identical JSON.stringify.
}

function testToJSON() {
  var obj1 = {a:1};
  var obj2 = {foo:"bar"};
  do_check_eq(nativeJSON.encode({toJSON: () => obj1}), '{"a":1}');
  do_check_eq(nativeJSON.encode({toJSON: () => obj2}), '{"foo":"bar"}');
  
  do_check_eq(nativeJSON.encode({toJSON: () => null}), null);
  do_check_eq(nativeJSON.encode({toJSON: () => ""}), null);
  do_check_eq(nativeJSON.encode({toJSON: () => undefined }), null);
  do_check_eq(nativeJSON.encode({toJSON: () => 5}), null);
  do_check_eq(nativeJSON.encode({toJSON: () => function(){}}), null);
  do_check_eq(nativeJSON.encode({toJSON: () => dump}), null);
}

function testThrowingToJSON() {
  var obj1 = {
    "b": 1,
    "c": 2,
    toJSON: function() { throw("uh oh"); }
  };
  try {
    var y = nativeJSON.encode(obj1);
    throw "didn't throw";
  } catch (ex) {
    do_check_eq(ex, "uh oh");
  }

  var obj2 = {
    "b": 1,
    "c": 2,
    get toJSON() { throw("crash and burn"); }
  };
  try {
    var y = nativeJSON.encode(obj2);
    throw "didn't throw";
  } catch (ex) {
    do_check_eq(ex, "crash and burn");
  }
}

function testOutputStreams() {
  function writeToFile(obj, charset, writeBOM) {
    var jsonFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
    jsonFile.initWithFile(outputDir);
    jsonFile.append("test.json");
    jsonFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
    var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
    try {
      stream.init(jsonFile, 0x04 | 0x08 | 0x20, 0o600, 0); // write, create, truncate
      nativeJSON.encodeToStream(stream, charset, writeBOM, obj);
    } finally {
      stream.close();
    }
    return jsonFile;
  }

  var pairs = [
    ["{}", {}],
    ['{"foo":"bar"}', {"foo":"bar"}],
    ['{"null":null}', {"null":null}],
    ['{"five":5}', {"five":5}],
    ['{"true":true}', {"true":true}],
    ['{"x":{"y":"z"}}', {"x":{"y":"z"}}],
    ['{"w":{"x":{"y":"z"}}}', {"w":{"x":{"y":"z"}}}],
    ["[]", []],
    ['[1,2,3]', [1,2,3]],
    ['[1,null,3]',[1,,3]],
  ];
  for (var i = 0; i < pairs.length; i++)
  {
    var pair = pairs[i];
    if (pair[1] && (typeof pair[1] == "object")) {
      var utf8File = writeToFile(pair[1], "UTF-8", false);
      var utf16LEFile = writeToFile(pair[1], "UTF-16LE", false);
      var utf16BEFile = writeToFile(pair[1], "UTF-16BE", false);

      // all ascii with no BOMs, so this will work
      do_check_eq(utf16LEFile.fileSize / 2, utf8File.fileSize);
      do_check_eq(utf16LEFile.fileSize, utf16BEFile.fileSize);
    }
  }

  // check BOMs
  // the clone() calls are there to work around -- bug 410005
  var f = writeToFile({},"UTF-8", true).clone();
  do_check_eq(f.fileSize, 5);
  var f = writeToFile({},"UTF-16LE", true).clone();
  do_check_eq(f.fileSize, 6);
  var f = writeToFile({},"UTF-16BE", true).clone();
  do_check_eq(f.fileSize, 6);
  
  outputDir.remove(true);
}

function run_test()
{
  testStringEncode();
  testToJSON();
  testThrowingToJSON();
  
  testOutputStreams();
  
}