| <!DOCTYPE html> |
| <title>NDEFRecord constructor</title> |
| <link rel="help" href="https://w3c.github.io/web-nfc/#dom-ndefrecord"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/nfc-helpers.js"></script> |
| <script> |
| |
| test(() => { |
| assert_equals(NDEFRecord.length, 1); |
| assert_throws(new TypeError, () => new NDEFRecord()); |
| }, 'NDEFRecord constructor without init dict'); |
| |
| test(() => { |
| assert_throws(new TypeError, () => new NDEFRecord(null), |
| 'NDEFRecordInit#recordType is a required field.'); |
| }, 'NDEFRecord constructor with null init dict'); |
| |
| test(() => { |
| assert_throws(new 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(new 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(new TypeError, () => new NDEFRecord( |
| createRecord('empty', test_text_data, test_record_id, 'text/plain')), |
| 'mediaType does not apply for empty record type.'); |
| assert_throws(new TypeError, () => new NDEFRecord( |
| createRecord('text', test_text_data, test_record_id, 'text/plain')), |
| 'mediaType does not apply for text record type.'); |
| assert_throws(new TypeError, () => new NDEFRecord( |
| createRecord('url', test_url_data, test_record_id, 'text/plain')), |
| 'mediaType does not apply for url record type.'); |
| assert_throws(new 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(new TypeError, () => new NDEFRecord( |
| createRecord('unknown', test_buffer_data, test_record_id, 'application/octet-stream')), |
| 'mediaType does not apply for unknown record type.'); |
| assert_throws(new 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external type records could have embedded records.'); |
| }, 'NDEFRecord constructor with text record type and arrayBufferView data'); |
| |
| test(() => { |
| assert_throws(new TypeError, () => new NDEFRecord(createTextRecord( |
| test_text_data, 'random-encoding'))); |
| assert_throws(new 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(new 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external type records could have embedded records.'); |
| }, 'NDEFRecord constructor with absolute-url record type'); |
| |
| test(() => { |
| assert_throws(new 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external type records could have embedded records.'); |
| }, 'NDEFRecord constructor with mime record type and json data'); |
| |
| test(() => { |
| assert_throws(new 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external 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('NotSupportedError', () => record.toRecords(), |
| 'Only smart-poster records and external type records could have embedded records.'); |
| } |
| }, 'NDEFRecord constructor with unknown record type'); |
| |
| test(() => { |
| assert_throws(new 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(new TypeError, () => new NDEFRecord(createRecord('EMptY')), |
| 'Unknown record type.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord('TeXt', test_text_data)), |
| 'Unknown record type.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord('uRL', test_url_data)), |
| 'Unknown record type.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord('Mime', test_buffer_data)), |
| 'Unknown record type.'); |
| assert_throws(new 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(new 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(new TypeError, () => new NDEFRecord(createRecord( |
| [...Array(252)].map(_ => 'a').join('') + ':xyz', test_buffer_data)), |
| 'The external type should not be longer than 255.'); |
| |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| 'xyz', test_buffer_data)), 'The external type must have a \':\'.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| ':xyz', test_buffer_data)), 'The domain should not be empty.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| 'example.com:', test_buffer_data)), 'The type should not be empty.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| 'example.com:xyz[', test_buffer_data)), 'The type should not contain \'[\'.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| 'example.com:xyz~', test_buffer_data)), 'The type should not contain \'~\'.'); |
| assert_throws(new TypeError, () => new NDEFRecord(createRecord( |
| 'example.com:xyz/', test_buffer_data)), 'The type should not contain \'/\'.'); |
| }, 'NDEFRecord constructor with invalid external record type'); |
| |
| </script> |