1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const { Blob, File } = require('buffer');
6const { inspect } = require('util');
7
8{
9  // ensure File extends Blob
10  assert.deepStrictEqual(Object.getPrototypeOf(File.prototype), Blob.prototype);
11}
12
13{
14  assert.throws(() => new File(), TypeError);
15  assert.throws(() => new File([]), TypeError);
16}
17
18{
19  const properties = ['name', 'lastModified'];
20
21  for (const prop of properties) {
22    const desc = Object.getOwnPropertyDescriptor(File.prototype, prop);
23    assert.notStrictEqual(desc, undefined);
24    // Ensure these properties are getters.
25    assert.strictEqual(desc.get?.name, `get ${prop}`);
26    assert.strictEqual(desc.set, undefined);
27    assert.strictEqual(desc.enumerable, true);
28    assert.strictEqual(desc.configurable, true);
29  }
30}
31
32{
33  const file = new File([], '');
34  assert.strictEqual(file[Symbol.toStringTag], 'File');
35  assert.strictEqual(File.prototype[Symbol.toStringTag], 'File');
36}
37
38{
39  assert.throws(() => File.prototype.name, TypeError);
40  assert.throws(() => File.prototype.lastModified, TypeError);
41}
42
43{
44  const keys = Object.keys(File.prototype).sort();
45  assert.deepStrictEqual(keys, ['lastModified', 'name']);
46}
47
48{
49  const file = new File([], 'dummy.txt.exe');
50  assert.strictEqual(file.name, 'dummy.txt.exe');
51  assert.strictEqual(file.size, 0);
52  assert.strictEqual(typeof file.lastModified, 'number');
53  assert(file.lastModified <= Date.now());
54}
55
56{
57  const emptyFile = new File([], 'empty.txt');
58  const blob = new Blob(['hello world']);
59
60  emptyFile.text.call(blob).then(common.mustCall((text) => {
61    assert.strictEqual(text, 'hello world');
62  }));
63}
64
65{
66  const toPrimitive = {
67    [Symbol.toPrimitive]() {
68      return 'NaN';
69    }
70  };
71
72  const invalidLastModified = [
73    null,
74    'string',
75    false,
76    toPrimitive,
77  ];
78
79  for (const lastModified of invalidLastModified) {
80    const file = new File([], '', { lastModified });
81    assert.strictEqual(file.lastModified, 0);
82  }
83}
84
85{
86  const file = new File([], '', { lastModified: undefined });
87  assert.notStrictEqual(file.lastModified, 0);
88}
89
90{
91  const toPrimitive = {
92    [Symbol.toPrimitive]() {
93      throw new TypeError('boom');
94    }
95  };
96
97  const throwValues = [
98    BigInt(3n),
99    toPrimitive,
100  ];
101
102  for (const lastModified of throwValues) {
103    assert.throws(() => new File([], '', { lastModified }), TypeError);
104  }
105}
106
107{
108  const valid = [
109    {
110      [Symbol.toPrimitive]() {
111        return 10;
112      }
113    },
114    new Number(10),
115    10,
116  ];
117
118  for (const lastModified of valid) {
119    assert.strictEqual(new File([], '', { lastModified }).lastModified, 10);
120  }
121}
122
123{
124  const file = new File([], '');
125  assert(inspect(file).startsWith('File { size: 0, type: \'\', name: \'\', lastModified:'));
126}
127
128{
129  function MyClass() {}
130  MyClass.prototype.lastModified = 10;
131
132  const file = new File([], '', new MyClass());
133  assert.strictEqual(file.lastModified, 10);
134}
135
136{
137  let counter = 0;
138  new File([], '', {
139    get lastModified() {
140      counter++;
141      return 10;
142    }
143  });
144  assert.strictEqual(counter, 1);
145}
146
147{
148  const getter = Object.getOwnPropertyDescriptor(File.prototype, 'name').get;
149
150  [
151    undefined,
152    null,
153    true,
154  ].forEach((invalidThis) => {
155    assert.throws(
156      () => getter.call(invalidThis),
157      TypeError
158    );
159  });
160}
161