Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// META: script=resources/nfc-helpers.js
// NDEFRecord constructor
test(() => {
assert_equals(NDEFRecord.length, 1);
assert_throws_js(TypeError, () => new NDEFRecord());
}, 'NDEFRecord constructor without init dict');
test(() => {
assert_throws_js(
TypeError, () => new NDEFRecord(null),
'NDEFRecordInit#recordType is a required field.');
}, 'NDEFRecord constructor with null init dict');
test(() => {
assert_throws_js(
TypeError,
() => new NDEFRecord({id: test_record_id, data: test_text_data}),
'NDEFRecordInit#recordType is a required field.');
}, 'NDEFRecord constructor without NDEFRecordInit#recordType field');
test(() => {
assert_throws_js(
TypeError,
() =>
new NDEFRecord(createRecord('empty', test_text_data, test_record_id)),
'id does not apply for empty record type.');
}, 'NDEFRecord constructor with empty record type and id');
test(() => {
assert_throws_js(
TypeError,
() => new NDEFRecord(
createRecord('empty', test_text_data, test_record_id, 'text/plain')),
'mediaType does not apply for empty record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(
createRecord('text', test_text_data, test_record_id, 'text/plain')),
'mediaType does not apply for text record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(
createRecord('url', test_url_data, test_record_id, 'text/plain')),
'mediaType does not apply for url record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord(
'absolute-url', test_url_data, test_record_id, 'text/plain')),
'mediaType does not apply for absolute-url record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord(
'unknown', test_buffer_data, test_record_id,
'application/octet-stream')),
'mediaType does not apply for unknown record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord(
'foo.example.com:bar', test_buffer_data, test_record_id,
'application/octet-stream')),
'mediaType does not apply for external record type.');
}, 'NDEFRecord constructor should only accept mediaType for mime record type');
test(
() => {
{
const record = new NDEFRecord(createRecord('text', test_text_data));
assert_equals(record.id, null, 'id');
} {const record =
new NDEFRecord(createRecord('text', test_text_data, ''));
assert_equals(record.id, '', 'id');} {
const dummy_id = 'https://dummy_host/mypath/myid';
const record =
new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');
} {const dummy_id = 'http://dummy_host/mypath/myid';
const record =
new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');} {
const dummy_id = 'mypath/myid';
const record =
new NDEFRecord(createRecord('text', test_text_data, dummy_id));
assert_equals(record.id, dummy_id, 'id');
}
},
'NDEFRecord constructor with custom record ids');
test(() => {
const record = new NDEFRecord(createRecord('empty'));
assert_equals(record.recordType, 'empty', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, null, 'id');
assert_equals(record.encoding, null, 'encoding');
assert_equals(record.lang, null, 'lang');
assert_equals(record.data, null, 'data');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with empty record type');
test(() => {
const record = new NDEFRecord(createTextRecord(test_text_data));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and string data');
test(() => {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(test_text_data);
const record = new NDEFRecord(createTextRecord(uint8Array.buffer));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and arrayBuffer data');
test(() => {
const encoder = new TextEncoder();
const uint8Array = encoder.encode(test_text_data);
const record = new NDEFRecord(createTextRecord(uint8Array));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
// By default, 'utf-8'.
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'en', 'lang');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with text record type and arrayBufferView data');
test(() => {
assert_throws_js(
TypeError,
() =>
new NDEFRecord(createTextRecord(test_text_data, 'random-encoding')));
assert_throws_js(
TypeError,
() => new NDEFRecord(createTextRecord(test_text_data, 'utf-16')));
// Only 'utf-8' is OK for a DOMString data source.
const record =
new NDEFRecord(createTextRecord(test_text_data, 'utf-8', 'fr'));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original text');
assert_throws_js(
TypeError,
() => new NDEFRecord(createTextRecord(
encodeTextToArrayBuffer(test_text_data, 'utf-8'),
'random-encoding')));
// The encoding list valid for a BufferSource data source.
const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le'];
for (const encoding of encodings) {
const record = new NDEFRecord(createTextRecord(
encodeTextToArrayBuffer(test_text_data, encoding), encoding, 'fr'));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.encoding, encoding, 'encoding');
assert_equals(record.lang, 'fr', 'lang');
const decoder = new TextDecoder(record.encoding);
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original text. encoding: ' +
encoding);
}
}, 'NDEFRecord constructor with text record type, encoding, and lang');
test(t => {
const previous_lang = document.querySelector('html').getAttribute('lang');
const test_lang = 'fr';
document.querySelector('html').setAttribute('lang', test_lang);
t.add_cleanup(() => {
document.querySelector('html').setAttribute('lang', previous_lang);
});
const record = new NDEFRecord(createTextRecord(test_text_data));
assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_equals(record.encoding, 'utf-8', 'encoding');
assert_equals(record.lang, test_lang, 'lang');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
}, 'NDEFRecord constructor with text record type and custom document language');
test(() => {
const record = new NDEFRecord(createUrlRecord(test_url_data));
assert_equals(record.recordType, 'url', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with url record type');
test(() => {
const record = new NDEFRecord(createUrlRecord(test_url_data, true));
assert_equals(record.recordType, 'absolute-url', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with absolute-url record type');
test(() => {
assert_throws_js(
TypeError,
() => new NDEFRecord(createMimeRecord('A string is not a BufferSource')),
'Only BufferSource is allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(createMimeRecord(buffer));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.mediaType, 'application/octet-stream', 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(createMimeRecord(buffer_view));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}
}, 'NDEFRecord constructor with mime record type and stream data');
test(() => {
const record = new NDEFRecord(createMimeRecordFromJson(test_json_data));
assert_equals(record.recordType, 'mime', 'recordType');
assert_equals(record.mediaType, 'application/json', 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_object_equals(
JSON.parse(new TextDecoder().decode(record.data)), test_json_data,
'data has the same content with the original json');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}, 'NDEFRecord constructor with mime record type and json data');
test(() => {
assert_throws_js(
TypeError,
() =>
new NDEFRecord(createUnknownRecord('A string is not a BufferSource')),
'Only BufferSource is allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(createUnknownRecord(buffer));
assert_equals(record.recordType, 'unknown', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(createUnknownRecord(buffer_view));
assert_equals(record.recordType, 'unknown', 'recordType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_throws_dom(
'NotSupportedError', () => record.toRecords(),
'Only smart-poster, external type and local type records could have embedded records.');
}
}, 'NDEFRecord constructor with unknown record type');
test(() => {
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord(
'foo.eXamPle.com:bAr*-',
'A string is not a BufferSource or NDEFMessageInit')),
'Only BufferSource and NDEFMessageInit are allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
const record = new NDEFRecord(
createRecord('foo.eXamPle.com:bAr*-', buffer, test_record_id));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_equals(
record.toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
const record = new NDEFRecord(
createRecord('foo.eXamPle.com:bAr*-', buffer_view, test_record_id));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, test_record_id, 'id');
assert_array_equals(
new Uint8Array(record.data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_equals(
record.toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed NDEFMessageInit.
{
const payload_message = createMessage([createTextRecord(test_text_data)]);
const record = new NDEFRecord(createRecord(
'foo.eXamPle.com:bAr*-', payload_message, 'dummy_record_id'));
assert_equals(record.recordType, 'foo.eXamPle.com:bAr*-', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, 'dummy_record_id', 'id');
const embedded_records = record.toRecords();
assert_equals(embedded_records.length, 1, 'Only one embedded record.');
// The only one embedded record has correct content.
assert_equals(embedded_records[0].recordType, 'text', 'recordType');
assert_equals(embedded_records[0].mediaType, null, 'mediaType');
assert_equals(embedded_records[0].id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(embedded_records[0].data), test_text_data,
'data has the same content with the original dictionary');
}
}, 'NDEFRecord constructor with external record type');
test(() => {
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord(':xyz', test_buffer_data)),
'The local type record must be embedded in the payload of another record (smart-poster, external, or local)');
// The following test cases use an external type record embedding our target
// local type record.
const local_record =
createRecord(':xyz', undefined /* data */, 'dummy_id_for_local_type');
const payload_message = createMessage([local_record]);
const external_record_embedding_local_record =
createRecord('example.com:foo', payload_message);
local_record.data = 'A string is not a BufferSource or NDEFMessageInit';
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'Only BufferSource and NDEFMessageInit are allowed to be the record data.');
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
// Feed ArrayBuffer.
{
local_record.data = buffer;
const record = new NDEFRecord(external_record_embedding_local_record);
const embedded_records = record.toRecords();
assert_equals(
embedded_records.length, 1, 'Only the one embedded local record.');
// The embedded local record is actually from |local_record|.
assert_equals(embedded_records[0].recordType, ':xyz', 'recordType');
assert_equals(embedded_records[0].mediaType, null, 'mediaType');
assert_equals(embedded_records[0].id, 'dummy_id_for_local_type', 'id');
assert_array_equals(
new Uint8Array(embedded_records[0].data.buffer), [1, 2, 3, 4],
'data has the same content with the original buffer');
assert_equals(
embedded_records[0].toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed ArrayBufferView.
{
let buffer_view = new Uint8Array(buffer, 1);
local_record.data = buffer_view;
const record = new NDEFRecord(external_record_embedding_local_record);
const embedded_records = record.toRecords();
assert_equals(
embedded_records.length, 1, 'Only the one embedded local record.');
// The embedded local record is actually from |local_record|.
assert_equals(embedded_records[0].recordType, ':xyz', 'recordType');
assert_equals(embedded_records[0].mediaType, null, 'mediaType');
assert_equals(embedded_records[0].id, 'dummy_id_for_local_type', 'id');
assert_array_equals(
new Uint8Array(embedded_records[0].data.buffer), [2, 3, 4],
'data has the same content with the original buffer view');
assert_equals(
embedded_records[0].toRecords(), null,
'toRecords() returns null if the payload is not an NDEF message.');
}
// Feed NDEFMessageInit.
{
const payload_message = createMessage([createTextRecord(test_text_data)]);
local_record.data = payload_message;
const record = new NDEFRecord(external_record_embedding_local_record);
const embedded_records = record.toRecords();
assert_equals(
embedded_records.length, 1, 'Only the one embedded local record.');
// The embedded local record is actually from |local_record|.
assert_equals(embedded_records[0].recordType, ':xyz', 'recordType');
assert_equals(embedded_records[0].mediaType, null, 'mediaType');
assert_equals(embedded_records[0].id, 'dummy_id_for_local_type', 'id');
// The embedded local record embeds another text record that's from
// |payload_message|.
const embedded_records_in_local_record = embedded_records[0].toRecords();
assert_equals(
embedded_records_in_local_record.length, 1,
'Only one embedded record.');
// The only one embedded record has correct content.
assert_equals(
embedded_records_in_local_record[0].recordType, 'text', 'recordType');
assert_equals(
embedded_records_in_local_record[0].mediaType, null, 'mediaType');
assert_equals(embedded_records_in_local_record[0].id, test_record_id, 'id');
const decoder = new TextDecoder();
assert_equals(
decoder.decode(embedded_records_in_local_record[0].data),
test_text_data,
'data has the same content with the original dictionary');
}
}, 'NDEFRecord constructor with local record type');
test(() => {
let buffer = new ArrayBuffer(4);
new Uint8Array(buffer).set([1, 2, 3, 4]);
const encoder = new TextEncoder();
const uri_record = createUrlRecord(test_url_data);
const title_record = createTextRecord(test_text_data, 'utf-8', 'en');
const type_record = createRecord(':t', encoder.encode('image/gif'));
const size_record = createRecord(':s', new Uint32Array([4096]));
const action_record = createRecord(':act', new Uint8Array([3]));
const icon_record = createRecord('mime', buffer, test_record_id, 'image/gif');
const payload_message = createMessage([
uri_record, title_record, type_record, size_record, action_record,
icon_record
]);
const smart_poster_record =
createRecord('smart-poster', payload_message, 'dummy_record_id');
const record = new NDEFRecord(smart_poster_record);
assert_equals(record.recordType, 'smart-poster', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, 'dummy_record_id', 'id');
const embedded_records = record.toRecords();
assert_equals(embedded_records.length, 6, 'length');
const decoder = new TextDecoder();
let embedded_record_types = [];
for (let record of embedded_records) {
embedded_record_types.push(record.recordType);
switch (record.recordType) {
case 'url':
assert_equals(record.mediaType, null, 'uri record\'s mediaType');
assert_equals(record.id, test_record_id, 'uri record\'s id');
assert_equals(
decoder.decode(record.data), test_url_data, 'uri record\'s data');
break;
case 'text':
assert_equals(record.mediaType, null, 'title record\'s mediaType');
assert_equals(record.id, test_record_id, 'title record\'s id');
assert_equals(record.encoding, 'utf-8', 'title record\'s encoding');
assert_equals(record.lang, 'en', 'title record\'s lang');
assert_equals(
decoder.decode(record.data), test_text_data,
'title record\'s data');
break;
case ':t':
assert_equals(record.mediaType, null, 'type record\'s mediaType');
assert_equals(record.id, null, 'type record\'s id');
assert_equals(
decoder.decode(record.data), 'image/gif', 'type record\'s data');
break;
case ':s':
assert_equals(record.mediaType, null, 'size record\'s mediaType');
assert_equals(record.id, null, 'size record\'s id');
assert_equals(
record.data.byteLength, 4, 'byteLength of size record\'s data');
assert_equals(
new Uint32Array(record.data.buffer)[0], 4096,
'value of size record\'s data');
break;
case ':act':
assert_equals(record.mediaType, null, 'action record\'s mediaType');
assert_equals(record.id, null, 'action record\'s id');
assert_equals(
record.data.byteLength, 1, 'byteLength of action record\'s data');
assert_equals(
new Uint8Array(record.data.buffer)[0], 3,
'value of action record\'s data');
break;
case 'mime':
assert_equals(
record.mediaType, 'image/gif', 'icon record\'s mediaType');
assert_equals(record.id, test_record_id, 'icon record\'s id');
assert_array_equals(
new Uint8Array(record.data.buffer), [1, 2, 3, 4],
'icon record\'s mediaType');
break;
default:
assert_unreached('Unknown recordType');
}
}
assert_array_equals(
embedded_record_types.sort(), [':act', ':s', ':t', 'mime', 'text', 'url'],
'smart-poster record\'s contained record types');
}, 'NDEFRecord constructor with smart-poster record type');
test(() => {
const uri_record = createUrlRecord(test_url_data);
const smart_poster_record = createRecord(
'smart-poster', createMessage([uri_record]), 'dummy_record_id');
const record = new NDEFRecord(smart_poster_record);
assert_equals(record.recordType, 'smart-poster', 'recordType');
assert_equals(record.mediaType, null, 'mediaType');
assert_equals(record.id, 'dummy_record_id', 'id');
const embedded_records = record.toRecords();
// smart-poster record only contains a uri record.
assert_equals(embedded_records.length, 1, 'length');
const decoder = new TextDecoder();
assert_equals(
embedded_records[0].recordType, 'url', 'uri record\'s recordType');
assert_equals(embedded_records[0].mediaType, null, 'uri record\'s mediaType');
assert_equals(embedded_records[0].id, test_record_id, 'uri record\'s id');
assert_equals(
decoder.decode(embedded_records[0].data), test_url_data,
'uri record\'s data');
}, 'NDEFRecord constructor with smart-poster record type that contains only a mandatory uri record');
test(() => {
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord('EMptY')),
'Unknown record type.');
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord('TeXt', test_text_data)),
'Unknown record type.');
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord('uRL', test_url_data)),
'Unknown record type.');
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord('Mime', test_buffer_data)),
'Unknown record type.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('sMart-PosTER', test_url_data)),
'Unknown record type.');
}, 'NDEFRecord constructor with record type string being treated as case sensitive');
test(() => {
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('example.com:hellö', test_buffer_data)),
'The external type must be an ASCII string.');
// Length of the external type is 255, OK.
const record = new NDEFRecord(createRecord(
[...Array(251)].map(_ => 'a').join('') + ':xyz', test_buffer_data));
// Exceeding 255, Throws.
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord(
[...Array(252)].map(_ => 'a').join('') + ':xyz', test_buffer_data)),
'The external type should not be longer than 255.');
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord('xyz', test_buffer_data)),
'The external type must have a \':\'.');
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord(':xyz', test_buffer_data)),
'The domain should not be empty.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('example.com:', test_buffer_data)),
'The type should not be empty.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('example.com:xyz[', test_buffer_data)),
'The type should not contain \'[\'.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('example.com:xyz~', test_buffer_data)),
'The type should not contain \'~\'.');
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('example.com:xyz/', test_buffer_data)),
'The type should not contain \'/\'.');
}, 'NDEFRecord constructor with invalid external record type');
test(() => {
const encoder = new TextEncoder();
const uri_record = createUrlRecord(test_url_data);
const title_record = createTextRecord(test_text_data, 'utf-8', 'en');
const type_record = createRecord(':t', encoder.encode('image/gif'));
const size_record = createRecord(':s', new Uint32Array([4096]));
const action_record = createRecord(':act', new Uint8Array([0]));
const icon_record =
createRecord('mime', test_buffer_data, test_record_id, 'image/gif');
const invalid_data_list = [
{
data: 'A string is not a NDEFMessageInit',
message: 'A string is not allowed.'
},
{data: test_buffer_data, message: 'An ArrayBuffer is not allowed.'}, {
data: createMessage(
[title_record, type_record, size_record, action_record, icon_record]),
message: 'Must contain a URI record.'
},
{
data: createMessage([
uri_record, title_record, type_record, size_record, action_record,
icon_record, uri_record
]),
message: 'Must not contain more than one uri record.'
},
{
data: createMessage([
uri_record, title_record, type_record, size_record, action_record,
icon_record, type_record
]),
message: 'Must not contain more than one type record.'
},
{
data: createMessage([
uri_record, title_record, type_record, size_record, action_record,
icon_record, size_record
]),
message: 'Must not contain more than one size record.'
},
{
data: createMessage([
uri_record, title_record, type_record, size_record, action_record,
icon_record, action_record
]),
message: 'Must not contain more than one action record.'
},
{
data: createMessage([
uri_record, title_record, type_record, action_record, icon_record,
createRecord(':s', new Uint8Array([1]))
]),
message:
'Size record must have payload as 4-byte 32 bit unsigned integer.'
},
{
data: createMessage([
uri_record, title_record, type_record, size_record, icon_record,
createRecord(':act', new Uint32Array([0]))
]),
message:
'Action record must have payload as 1-byte 8 bit unsigned integer.'
}
];
invalid_data_list.forEach(entry => {
assert_throws_js(
TypeError,
() => new NDEFRecord(createRecord('smart-poster', entry.data)),
entry.message);
});
}, 'NDEFRecord constructor for smart-poster record with invalid embedded records.');
test(() => {
assert_throws_js(
TypeError, () => new NDEFRecord(createRecord(':xyz', test_buffer_data)),
'The local type record must be embedded in the payload of another record (smart-poster, external, or local)');
// The following test cases use an external type record embedding our target
// local type record.
const local_record = createRecord(':xyz', test_buffer_data);
const payload_message = createMessage([local_record]);
const external_record_embedding_local_record =
createRecord('example.com:foo', payload_message);
// OK.
new NDEFRecord(external_record_embedding_local_record);
local_record.recordType = ':xyZ123';
new NDEFRecord(external_record_embedding_local_record);
local_record.recordType = ':123XYz';
new NDEFRecord(external_record_embedding_local_record);
local_record.recordType = ':hellö';
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'The local type must be an ASCII string.');
// Length of the local type excluding the prefix ':' is 255, OK.
local_record.recordType = ':' + [...Array(255)].map(_ => 'a').join('');
const record_255 = new NDEFRecord(external_record_embedding_local_record);
// Exceeding 255, Throws.
local_record.recordType = ':' + [...Array(256)].map(_ => 'a').join('');
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'The local type excluding the prefix \':\' should not be longer than 255.');
local_record.recordType = 'xyz';
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'The local type must start with a \':\'.');
local_record.recordType = ':Xyz';
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'The local type must have a lower case letter or digit following the prefix \':\'.');
local_record.recordType = ':-xyz';
assert_throws_js(
TypeError, () => new NDEFRecord(external_record_embedding_local_record),
'The local type must have a lower case letter or digit following the prefix \':\'.');
}, 'NDEFRecord constructor with various local record types');