• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<meta charset=utf-8>
3<title>File constructor</title>
4<link rel=help href="http://dev.w3.org/2006/webapi/FileAPI/#dfn-file">
5<script src="/resources/testharness.js"></script>
6<script src="/resources/testharnessreport.js"></script>
7<div id="log"></div>
8<script>
9const to_string_obj = { toString: () => 'a string' };
10const to_string_throws = { toString: () => { throw new Error('expected'); } };
11
12test(function() {
13  assert_true("File" in window, "window should have a File property.");
14}, "File interface object exists");
15
16test(t => {
17  assert_throws_js(TypeError, () => new File(),
18                   'Bits argument is required');
19  assert_throws_js(TypeError, () => new File([]),
20                   'Name argument is required');
21}, 'Required arguments');
22
23function test_first_argument(arg1, expectedSize, testName) {
24  test(function() {
25    var file = new File(arg1, "dummy");
26    assert_true(file instanceof File);
27    assert_equals(file.name, "dummy");
28    assert_equals(file.size, expectedSize);
29    assert_equals(file.type, "");
30    // assert_false(file.isClosed); XXX: File.isClosed doesn't seem to be implemented
31    assert_not_equals(file.lastModified, "");
32  }, testName);
33}
34
35test_first_argument([], 0, "empty fileBits");
36test_first_argument(["bits"], 4, "DOMString fileBits");
37test_first_argument(["��������"], 16, "Unicode DOMString fileBits");
38test_first_argument([new String('string object')], 13, "String object fileBits");
39test_first_argument([new Blob()], 0, "Empty Blob fileBits");
40test_first_argument([new Blob(["bits"])], 4, "Blob fileBits");
41test_first_argument([new File([], 'world.txt')], 0, "Empty File fileBits");
42test_first_argument([new File(["bits"], 'world.txt')], 4, "File fileBits");
43test_first_argument([new ArrayBuffer(8)], 8, "ArrayBuffer fileBits");
44test_first_argument([new Uint8Array([0x50, 0x41, 0x53, 0x53])], 4, "Typed array fileBits");
45test_first_argument(["bits", new Blob(["bits"]), new Blob(), new Uint8Array([0x50, 0x41]),
46                     new Uint16Array([0x5353]), new Uint32Array([0x53534150])], 16, "Various fileBits");
47test_first_argument([12], 2, "Number in fileBits");
48test_first_argument([[1,2,3]], 5, "Array in fileBits");
49test_first_argument([{}], 15, "Object in fileBits"); // "[object Object]"
50test_first_argument([document.body], 24, "HTMLBodyElement in fileBits"); // "[object HTMLBodyElement]"
51test_first_argument([to_string_obj], 8, "Object with toString in fileBits");
52test_first_argument({[Symbol.iterator]() {
53  let i = 0;
54  return {next: () => [
55    {done:false, value:'ab'},
56    {done:false, value:'cde'},
57    {done:true}
58  ][i++]};
59}}, 5, 'Custom @@iterator');
60
61[
62  'hello',
63  0,
64  null
65].forEach(arg => {
66  test(t => {
67    assert_throws_js(TypeError, () => new File(arg, 'world.html'),
68                     'Constructor should throw for invalid bits argument');
69  }, `Invalid bits argument: ${JSON.stringify(arg)}`);
70});
71
72test(t => {
73  assert_throws_js(Error, () => new File([to_string_throws], 'name.txt'),
74                   'Constructor should propagate exceptions');
75}, 'Bits argument: object that throws');
76
77
78function test_second_argument(arg2, expectedFileName, testName) {
79  test(function() {
80    var file = new File(["bits"], arg2);
81    assert_true(file instanceof File);
82    assert_equals(file.name, expectedFileName);
83  }, testName);
84}
85
86test_second_argument("dummy", "dummy", "Using fileName");
87test_second_argument("dummy/foo", "dummy/foo",
88                     "No replacement when using special character in fileName");
89test_second_argument(null, "null", "Using null fileName");
90test_second_argument(1, "1", "Using number fileName");
91test_second_argument('', '', "Using empty string fileName");
92test_second_argument(document.body, '[object HTMLBodyElement]', "Using object fileName");
93
94// testing the third argument
95[
96  {type: 'text/plain', expected: 'text/plain'},
97  {type: 'text/plain;charset=UTF-8', expected: 'text/plain;charset=utf-8'},
98  {type: 'TEXT/PLAIN', expected: 'text/plain'},
99  {type: '��������/����������', expected: ''},
100  {type: 'ascii/nonprintable\u001F', expected: ''},
101  {type: 'ascii/nonprintable\u007F', expected: ''},
102  {type: 'nonascii\u00EE', expected: ''},
103  {type: 'nonascii\u1234', expected: ''},
104  {type: 'nonparsable', expected: 'nonparsable'}
105].forEach(testCase => {
106  test(t => {
107    var file = new File(["bits"], "dummy", { type: testCase.type});
108    assert_true(file instanceof File);
109    assert_equals(file.type, testCase.expected);
110  }, `Using type in File constructor: ${testCase.type}`);
111});
112test(function() {
113  var file = new File(["bits"], "dummy", { lastModified: 42 });
114  assert_true(file instanceof File);
115  assert_equals(file.lastModified, 42);
116}, "Using lastModified");
117test(function() {
118  var file = new File(["bits"], "dummy", { name: "foo" });
119  assert_true(file instanceof File);
120  assert_equals(file.name, "dummy");
121}, "Misusing name");
122test(function() {
123  var file = new File(["bits"], "dummy", { unknownKey: "value" });
124  assert_true(file instanceof File);
125  assert_equals(file.name, "dummy");
126}, "Unknown properties are ignored");
127
128[
129  123,
130  123.4,
131  true,
132  'abc'
133].forEach(arg => {
134  test(t => {
135    assert_throws_js(TypeError, () => new File(['bits'], 'name.txt', arg),
136                     'Constructor should throw for invalid property bag type');
137  }, `Invalid property bag: ${JSON.stringify(arg)}`);
138});
139
140[
141  null,
142  undefined,
143  [1,2,3],
144  /regex/,
145  function() {}
146].forEach(arg => {
147  test(t => {
148    assert_equals(new File(['bits'], 'name.txt', arg).size, 4,
149                  'Constructor should accept object-ish property bag type');
150  }, `Unusual but valid property bag: ${arg}`);
151});
152
153test(t => {
154  assert_throws_js(Error,
155                   () => new File(['bits'], 'name.txt', {type: to_string_throws}),
156                   'Constructor should propagate exceptions');
157}, 'Property bag propagates exceptions');
158
159</script>
160