diff --git a/lib/ndef.dart b/lib/ndef.dart index e2e1a44..84bf5ca 100644 --- a/lib/ndef.dart +++ b/lib/ndef.dart @@ -38,7 +38,7 @@ List decodeRawNdefMessage(Uint8List data, /// This is most useful in mobile environment because the APIs will give you these information in a separate manner. NDEFRecord decodePartialNdefMessage( TypeNameFormat tnf, Uint8List type, Uint8List payload, - {required Uint8List id}) { + {Uint8List? id}) { var decoded = NDEFRecord.doDecode(tnf, type, payload, id: id); return decoded; } diff --git a/lib/utilities.dart b/lib/utilities.dart index da0d392..62013f2 100644 --- a/lib/utilities.dart +++ b/lib/utilities.dart @@ -77,12 +77,12 @@ class ByteUtils { } static Uint8List hexStringToBytes(String hex) { - // Delete blank space + // if there are some blank space in ${hex}, this will delete blank space in it. hex = hex.splitMapJoin(" ", onMatch: (Match match) { return ""; }); if (hex.length % 2 != 0) { - throw "Hex string length must be even integer, got ${hex.length}"; + throw ArgumentError("Hex string length must be even integer, got ${hex.length}"); } var result = []; for (int i = 0; i < hex.length; i += 2) { diff --git a/test/common.dart b/test/common.dart new file mode 100644 index 0000000..d5328c7 --- /dev/null +++ b/test/common.dart @@ -0,0 +1,23 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; + +import 'package:ndef/ndef.dart'; +import 'package:ndef/utilities.dart'; + +void testParse(List hexStrings, List> messages) { + for (int i = 0; i < hexStrings.length; i++) { + List decoded = decodeRawNdefMessage(hexStrings[i].toBytes()); + assert(decoded.length == messages[i].length); + for (int j = 0; j < decoded.length; j++) { + assert(decoded[j].isEqual(messages[i][j])); + } + } +} + +void testGenerate(List hexStrings, List> messages) { + for (int i = 0; i < hexStrings.length; i++) { + assert(encodeNdefMessage(messages[i]).toHexString() == hexStrings[i]); + } +} diff --git a/test/ndef_test.dart b/test/ndef_test.dart deleted file mode 100644 index 903bac9..0000000 --- a/test/ndef_test.dart +++ /dev/null @@ -1,305 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; - -import 'package:ndef/ndef.dart'; -import 'package:ndef/record/bluetooth.dart'; -import 'package:ndef/record/wellknown.dart'; -import 'package:ndef/utilities.dart'; - -void testParse(List hexStrings, List> messages) { - for (int i = 0; i < hexStrings.length; i++) { - var decoded = decodeRawNdefMessage(hexStrings[i].toBytes()); - assert(decoded.length == messages[i].length); - for (int j = 0; j < decoded.length; j++) { - assert(decoded[j].isEqual(messages[i][j])); - } - } -} - -void testGenerate(List hexStrings, List> messages) { - for (int i = 0; i < hexStrings.length; i++) { - assert(encodeNdefMessage(messages[i]).toHexString() == hexStrings[i]); - } -} - -void main() { - test('ndef message with uri type', () { - // TODO: fill in tests - List hexStrings = [ - "91011655046769746875622e636f6d2f6e6663696d2f6e64656651010b55046769746875622e636f6d", - ]; - - List> messages = [ - [ - UriRecord.fromString("https://github.com/nfcim/ndef"), - UriRecord.fromString("https://github.com") - ], - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('ndef message with text type', () { - List hexStrings = [ - "d1010f5402656e48656c6c6f20576f726c6421", - "d101145485656d6f6a69fffe3dd801de3dd802de3ed828dd" - ]; - - List> messages = [ - [TextRecord(language: 'en', text: 'Hello World!')], - [ - TextRecord( - language: 'emoji', text: '๐Ÿ˜๐Ÿ˜‚๐Ÿคจ', encoding: TextEncoding.UTF16) - ], - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('ndef message with signature type', () { - List hexStrings = [ - "d10306536967200002000000", - "d1034d536967200b0200473045022100a410c28fd9437fd24f6656f121e62bcc5f65e36257f5faadf68e3e83d40d481a0220335b1dff8d6fe722fcf7018be9684d2de5670b256fdfc02aa25bdae16f624b8000", - ]; - - List> messages = [ - [SignatureRecord()], - [ - SignatureRecord( - signatureType: 'ECDSA-P256', - signature: ByteUtils.hexStringToBytes( - "3045022100a410c28fd9437fd24f6656f121e62bcc5f65e36257f5faadf68e3e83d40d481a0220335b1dff8d6fe722fcf7018be9684d2de5670b256fdfc02aa25bdae16f624b80")) - ], - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('ndef message with device information type', () { - List hexStrings = [ - "d1023b446900056e6663696d01096e666344657669636502076e66634e616d6503106361ae18d5b011ea9d0840a3ccfd09570405312e302e30ff054e4643494d", - ]; - - List> messages = [ - [ - DeviceInformationRecord( - vendorName: "nfcim", - modelName: "nfcDevice", - uniqueName: "nfcName", - uuid: "6361ae18-d5b0-11ea-9d08-40a3ccfd0957", - versionString: "1.0.0", - undefinedData: [ - DataElement.fromString(255, "NFCIM"), - ]) - ], - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('ndef message with smart poster type', () { - List hexStrings = [ - "d10249537091011655046769746875622e636f6d2f6e6663696d2f6e6465661101075402656e6e64656611030161637400120909696d6167652f706e676120706963747572655101047300002710", - "d1020f5370d1010b55046769746875622e636f6d", - ]; - - List> messages = [ - [ - SmartPosterRecord( - title: "ndef", - uri: "https://github.com/nfcim/ndef", - action: Action.exec, - icon: {"image/png": Uint8List.fromList(utf8.encode("a picture"))}, - size: 10000), - // typeInfo: null), - ], - [ - SmartPosterRecord(uri: "https://github.com"), - ] - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('ndef message with handover type', () { - List hexStrings = [ - 'd10201487211', - '910211487212910202637212345102046163010131005a030201612f62310001', - '91021248731391020461630101310051030265727201ff5a030201612f62310001', - '91020a486d13d102046163010161005a0a0301746578742f706c61696e61000102', - '91021148721291020263721234510204616301013100590205014863310203612f62' - ]; - - List> messages = [ - [ - HandoverRequestRecord(versionString: "1.1"), - ], - [ - HandoverRequestRecord( - versionString: "1.2", - collisionResolutionNumber: 0x1234, - alternativeCarrierRecordList: [ - AlternativeCarrierRecord( - carrierPowerState: CarrierPowerState.active, - carrierDataReference: latin1.encode('1')) - ]), - MimeRecord( - decodedType: 'a/b', - id: latin1.encode('1'), - payload: ByteUtils.hexStringToBytes('0001')) - ], - [ - HandoverSelectRecord( - error: ErrorRecord( - errorNum: 1, errorData: ByteUtils.intToBytes(255, 1)), - alternativeCarrierRecordList: [ - AlternativeCarrierRecord( - carrierPowerState: CarrierPowerState.active, - carrierDataReference: latin1.encode('1')) - ]), - MimeRecord( - decodedType: 'a/b', - id: latin1.encode('1'), - payload: ByteUtils.hexStringToBytes('0001')) - ], - [ - HandoverMediationRecord( - versionString: '1.3', - alternativeCarrierRecordList: [ - AlternativeCarrierRecord( - carrierPowerState: CarrierPowerState.active, - carrierDataReference: latin1.encode('a')) - ]), - MimeRecord( - decodedType: 'text/plain', - id: latin1.encode('a'), - payload: ByteUtils.hexStringToBytes('000102')) - ], - [ - HandoverRequestRecord( - versionString: "1.2", - collisionResolutionNumber: 0x1234, - alternativeCarrierRecordList: [ - AlternativeCarrierRecord( - carrierPowerState: CarrierPowerState.active, - carrierDataReference: latin1.encode('1')) - ]), - HandoverCarrierRecord( - carrierTnf: TypeNameFormat.media, - carrierType: 'a/b', - carrierData: Uint8List(0), - id: latin1.encode('1')) - ] - ]; - - for (int i = 0; i < hexStrings.length; i++) { - var decoded = - decodeRawNdefMessage(ByteUtils.hexStringToBytes(hexStrings[i])); - assert(decoded.length == messages[i].length); - for (int j = 0; j < decoded.length; j++) { - assert(decoded[j].isEqual(messages[i][j])); - } - } - for (int i = 0; i < hexStrings.length; i++) { - var decoded = decodeRawNdefMessage(encodeNdefMessage(messages[i])); - assert(decoded.length == messages[i].length); - for (int j = 0; j < decoded.length; j++) { - assert(decoded[j].isEqual(messages[i][j])); - } - } - }); - - test('ndef message with bluetooth type', () { - List hexStrings = [ - "d2200b6170706c69636174696f6e2f766e642e626c7565746f6f74682e65702e6f6f620b0006050403020102ff61", - ]; - - List> messages = [ - [ - BluetoothEasyPairingRecord( - address: EPAddress(address: "06:05:04:03:02:01"), - attributes: { - EIRType.ManufacturerSpecificData: Uint8List.fromList([97]) - }) - ], - ]; - - testParse(hexStrings, messages); - testGenerate(hexStrings, messages); - }); - - test('utilities test', () { - assert(ByteUtils.bytesEqual(null, null) == true); - assert(ByteUtils.bytesEqual( - Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2])) == - false); - assert(ByteUtils.bytesEqual( - Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2, 4])) == - false); - assert(ByteUtils.bytesEqual( - Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2, 3])) == - true); - assert(ByteUtils.bytesEqual(Uint8List.fromList([1, 2, 3]), null) == false); - - var bytes = Uint8List(0); - assert(bytes.toHexString() == ""); - assert(Uint8List.fromList([]).toHexString() == ""); - }); - - test('blank record construction', () { - var record = NDEFRecord(); - assert(record.tnf == TypeNameFormat.empty); - assert(record.decodedType == null); - assert(record.type == null); - assert(record.fullType == null); - assert(record.minPayloadLength == 0); - assert(record.maxPayloadLength == null); - assert(record.payload == null); - - var uriRecord = UriRecord(); - assert(uriRecord.tnf == TypeNameFormat.nfcWellKnown); - assert(uriRecord.decodedType == 'U'); - assert(ByteUtils.bytesEqual(uriRecord.type, Uint8List.fromList([85]))); - assert(uriRecord.fullType == "urn:nfc:wkt:U"); - assert(uriRecord.minPayloadLength == 1); - assert(uriRecord.maxPayloadLength == null); - assert(uriRecord.prefix == null); - assert(uriRecord.iriString == null); - assert(uriRecord.uriString == null); - assert(uriRecord.uri == null); - assert(uriRecord.payload == null); - - var textRecord = TextRecord(); - assert(textRecord.encoding == TextEncoding.UTF8); - assert(textRecord.encodingString == "UTF-8"); - assert(textRecord.language == null); - assert(textRecord.text == null); - - var wellKnownRecord = WellKnownRecord(); - assert(wellKnownRecord.tnf == TypeNameFormat.nfcWellKnown); - assert(wellKnownRecord.payload == null); - assert(wellKnownRecord.id == null); - }); - - // TODO: exception test (urgent task) - test( - 'exception test', - () => expect(() { - UriRecord record = UriRecord(); - record.prefix = "test"; - }, throwsArgumentError)); - - test('manual test', () { - print(decodeRawNdefMessage(ByteUtils.hexStringToBytes( - "d2200b6170706c69636174696f6e2f766e642e626c7565746f6f74682e65702e6f6f620b0006050403020102ff61"))); - }); - - // TODO: more tests -} diff --git a/test/records/bluetooth_test.dart b/test/records/bluetooth_test.dart new file mode 100644 index 0000000..9c7eb0b --- /dev/null +++ b/test/records/bluetooth_test.dart @@ -0,0 +1,30 @@ +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/bluetooth.dart'; + +import '../common.dart'; + +void main() { + group('decode and encode', () { + test('bluetooth record', () { + List hexStrings = [ + "d2200b6170706c69636174696f6e2f766e642e626c7565746f6f74682e65702e6f6f620b0006050403020102ff61", + ]; + + List> messages = [ + [ + BluetoothEasyPairingRecord( + address: EPAddress(address: "06:05:04:03:02:01"), + attributes: { + EIRType.ManufacturerSpecificData: Uint8List.fromList([97]) + }) + ], + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); +} diff --git a/test/records/device_information_test.dart b/test/records/device_information_test.dart new file mode 100644 index 0000000..96cb5a9 --- /dev/null +++ b/test/records/device_information_test.dart @@ -0,0 +1,90 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/ndef.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/deviceinfo.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test('device information record', () { + List hexStrings = [ + "d1023b446900056e6663696d01096e666344657669636502076e66634e616d6503106361ae18d5b011ea9d0840a3ccfd09570405312e302e30ff054e4643494d", + ]; + + List> messages = [ + [ + DeviceInformationRecord( + vendorName: "nfcim", + modelName: "nfcDevice", + uniqueName: "nfcName", + uuid: "6361ae18-d5b0-11ea-9d08-40a3ccfd0957", + versionString: "1.0.0", + undefinedData: [ + DataElement.fromString(255, "NFCIM"), + ]) + ], + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); + + group('ndef message with device information type', () { + DeviceInformationRecord deviceInfoRecord = DeviceInformationRecord( + vendorName: "nfcim", + modelName: "nfcDevice", + uniqueName: "nfcName", + uuid: "6361ae18-d5b0-11ea-9d08-40a3ccfd0957", + versionString: "1.0.0", + undefinedData: [ + DataElement.fromString(255, "NFCIM"), + ]); + + test('test the all parts of a record', () { + expect(deviceInfoRecord.id, equals(null)); + + String hexStringUsedInExpect1 = + "00056e6663696d01096e666344657669636502076e66634e616d6503106361ae18d5b011ea9d0840a3ccfd09570405312e302e30ff054e4643494d"; + expect( + deviceInfoRecord.payload, equals(hexStringUsedInExpect1.toBytes())); + + expect(deviceInfoRecord.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(deviceInfoRecord.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(deviceInfoRecord.type, equals([68, 105])); + expect(deviceInfoRecord.fullType, equals('urn:nfc:wkt:Di')); + expect(deviceInfoRecord.decodedType, equals('Di')); + + expect( + deviceInfoRecord.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Di ')); + expect(deviceInfoRecord.maxPayloadLength, equals(null)); + expect(deviceInfoRecord.minPayloadLength, equals(2)); + }); + + test('test some exceptions', () { + DeviceInformationRecord deviceInfoRecord = DeviceInformationRecord( + vendorName: null, + modelName: "nfcDevice", + uniqueName: "nfcName", + uuid: "6361ae18-d5b0-11ea-9d08-40a3ccfd0957", + versionString: "1.0.0", + undefinedData: [ + DataElement.fromString(255, "NFCIM"), + ]); + + expect(() { + deviceInfoRecord.payload; + }, throwsArgumentError); + + expect(() { + String hexStringUsedInExpect2 = + "01096e666344657669636502076e66634e616d6503106361ae18d5b011ea9d0840a3ccfd09570405312e302e30ff054e4643494d"; + deviceInfoRecord.payload = hexStringUsedInExpect2.toBytes(); + }, throwsArgumentError); + }); + }); +} diff --git a/test/records/handover_test.dart b/test/records/handover_test.dart new file mode 100644 index 0000000..a217340 --- /dev/null +++ b/test/records/handover_test.dart @@ -0,0 +1,403 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/ndef.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/handover.dart'; +import 'package:ndef/record/mime.dart'; +import 'package:ndef/utilities.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test('handover record', () { + List hexStrings = [ + 'd10201487211', + '910211487212910202637212345102046163010131005a030201612f62310001', + '91021248731391020461630101310051030265727201ff5a030201612f62310001', + '91020a486d13d102046163010161005a0a0301746578742f706c61696e61000102', + '91021148721291020263721234510204616301013100590205014863310203612f62' + ]; + + List> messages = [ + [ + HandoverRequestRecord(versionString: "1.1"), + ], + [ + HandoverRequestRecord( + versionString: "1.2", + collisionResolutionNumber: 0x1234, + alternativeCarrierRecordList: [ + AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.active, + carrierDataReference: latin1.encode('1')) + ]), + MimeRecord( + decodedType: 'a/b', + id: latin1.encode('1'), + payload: ByteUtils.hexStringToBytes('0001')) + ], + [ + HandoverSelectRecord( + error: ErrorRecord( + errorNum: 1, errorData: ByteUtils.intToBytes(255, 1)), + alternativeCarrierRecordList: [ + AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.active, + carrierDataReference: latin1.encode('1')) + ]), + MimeRecord( + decodedType: 'a/b', + id: latin1.encode('1'), + payload: ByteUtils.hexStringToBytes('0001')) + ], + [ + HandoverMediationRecord( + versionString: '1.3', + alternativeCarrierRecordList: [ + AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.active, + carrierDataReference: latin1.encode('a')) + ]), + MimeRecord( + decodedType: 'text/plain', + id: latin1.encode('a'), + payload: ByteUtils.hexStringToBytes('000102')) + ], + [ + HandoverRequestRecord( + versionString: "1.2", + collisionResolutionNumber: 0x1234, + alternativeCarrierRecordList: [ + AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.active, + carrierDataReference: latin1.encode('1')) + ]), + HandoverCarrierRecord( + carrierTnf: TypeNameFormat.media, + carrierType: 'a/b', + carrierData: Uint8List(0), + id: latin1.encode('1')) + ] + ]; + + // testParse(hexStrings, messages); + // testGenerate(hexStrings, messages); + // int num = 1; + // // ignore: unrelated_type_equality_checks + // assert(encodeNdefMessage(messages[num]).toHexString() == hexStrings[num]); + + // Problem! is here!!! + // print(encodeNdefMessage(messages[0]).toHexString()); + // print(hexStrings[0]); + // print(encodeNdefMessage(messages[1]).toHexString()); + // print(hexStrings[1]); + // print(decodeRawNdefMessage(hexStrings[1].toBytes())); + // print(encodeNdefMessage(messages[2]).toHexString()); + // print(hexStrings[2]); + // print(encodeNdefMessage(messages[3]).toHexString()); + // print(hexStrings[3]); + + print(encodeNdefMessage(messages[4]).toHexString()); + print(hexStrings[4]); + print(decodeRawNdefMessage(hexStrings[4].toBytes())); + }); + + group('ndef message with handover type', () { + test('AlternativeCarrierRecord Test', () { + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + expect(acr.auxDataReferenceList, equals([])); + expect(acr.carrierDataReference, equals([48])); + expect(acr.carrierPowerState, equals(CarrierPowerState.inactive)); + expect(AlternativeCarrierRecord.classMinPayloadLength, equals(2)); + expect(AlternativeCarrierRecord.classType, equals('ac')); + }); + + test('CollisionResolutionRecord Test', () { + // Randomly generate number + var rng = new Random(10); + var randomNum123 = rng.nextInt(100); + + CollisionResolutionRecord crr = + new CollisionResolutionRecord(randomNumber: randomNum123); + expect(crr.maxPayloadLength, equals(2)); + expect(crr.minPayloadLength, equals(2)); + + expect(crr.randomNumber, equals(75)); + expect( + crr.basicInfoString, + equals( + "id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=cr ")); + + expect(crr.decodedType, equals('cr')); + expect(crr.runtimeType, equals(CollisionResolutionRecord)); + expect(crr.fullType, equals('urn:nfc:wkt:cr')); + expect(crr.type, equals([99, 114])); + + expect(crr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(crr.flags.runtimeType, equals(NDEFRecordFlags)); + expect(crr.payload, equals([0, 75])); + }); + + test('ErrorRecord Test', () { + int errorNum123 = 1; + List errorData123 = [1, 2, 3, 4, 5, 6, 7, 8]; + ErrorRecord er = new ErrorRecord( + errorNum: errorNum123, errorData: Uint8List.fromList(errorData123)); + + expect(er.minPayloadLength, equals(1)); + + expect(er.errorData, equals([1, 2, 3, 4, 5, 6, 7, 8])); + expect(er.errorNum, equals(1)); + expect(er.errorReason, equals(ErrorReason.temporarilyOutOfMemory)); + expect( + er.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=err ')); + + expect(er.decodedType, equals('err')); + expect(er.runtimeType, equals(ErrorRecord)); + expect(er.fullType, equals('urn:nfc:wkt:err')); + expect(er.type, equals([101, 114, 114])); + + expect(er.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(er.flags.runtimeType, equals(NDEFRecordFlags)); + }); + + test('HandoverRecord Test', () { + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + + List listAcr = [acr]; + HandoverRecord hr = + new HandoverRecord(alternativeCarrierRecordList: listAcr); + + expect(hr.minPayloadLength, equals(1)); + + String allRecordListToString = hr.allRecordList.toString(); + expect( + allRecordListToString, + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + String alternativeCarrierRecordListToString = + hr.alternativeCarrierRecordList.toString(); + expect( + alternativeCarrierRecordListToString, + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect(hr.unknownRecordList, equals([])); + + expect(hr.flags.runtimeType, equals(NDEFRecordFlags)); + expect(hr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect( + hr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=null ')); + + expect(hr.runtimeType, equals(HandoverRecord)); + }); + + test('HandoverRequestRecord Test', () { + // CollisionResolutionRecord + // Randomly generate number + var rng = new Random(10); + var randomNum123 = rng.nextInt(100); + + // AlternativeCarrierRecord + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + + List listAcr = [acr]; + HandoverRequestRecord hrr = new HandoverRequestRecord( + collisionResolutionNumber: randomNum123, + alternativeCarrierRecordList: listAcr); + + expect(hrr.minPayloadLength, equals(1)); + + expect(hrr.collisionResolutionNumber, equals(75)); + + String allRecordListToString = hrr.allRecordList.toString(); + expect( + allRecordListToString, + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[], CollisionResolutionRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=cr randomNumber=75]')); + expect(hrr.unknownRecordList, equals([])); + String alternativeCarrierRecordListToString = + hrr.alternativeCarrierRecordList.toString(); + expect( + alternativeCarrierRecordListToString, + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + String collisionResolutionRecordListToString = + hrr.collisionResolutionRecordList.toString(); + expect( + collisionResolutionRecordListToString, + equals( + '[CollisionResolutionRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=cr randomNumber=75]')); + + expect( + hrr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Hr ')); + expect(hrr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(hrr.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(hrr.decodedType, equals('Hr')); + expect(hrr.fullType, equals('urn:nfc:wkt:Hr')); + expect(hrr.type, equals([72, 114])); + expect(hrr.runtimeType, equals(HandoverRequestRecord)); + }); + + test('HandoverSelectRecord Test', () { + //TODO: waiting for handling the errorRecord(); + // AlternativeCarrierRecord + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + + List listAcr = [acr]; + + // ErrorRecord + int errorNum123 = 1; + List errorData123 = [1, 2, 3, 4, 5, 6, 7, 8]; + ErrorRecord er = new ErrorRecord( + errorNum: errorNum123, errorData: Uint8List.fromList(errorData123)); + HandoverSelectRecord hsr = new HandoverSelectRecord( + error: er, alternativeCarrierRecordList: listAcr); + + expect(hsr.minPayloadLength, equals(1)); + + expect( + hsr.error.toString(), + equals( + 'ErrorRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=err error=temporarily out of memory, may retry after 72623859790382856 milliseconds')); + + expect( + hsr.alternativeCarrierRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect( + hsr.allRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[], ErrorRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=err error=temporarily out of memory, may retry after 72623859790382856 milliseconds]')); + expect( + hsr.errorRecordList.toString(), + equals( + '[ErrorRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=err error=temporarily out of memory, may retry after 72623859790382856 milliseconds]')); + + expect(hsr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect( + hsr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Hs ')); + expect(hsr.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(hsr.type, equals([72, 115])); + expect(hsr.fullType, equals('urn:nfc:wkt:Hs')); + expect(hsr.decodedType, equals('Hs')); + expect(hsr.runtimeType, equals(HandoverSelectRecord)); + }); + + test('HandoverMediationRecord Test', () { + // AlternativeCarrierRecord + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + + List listAcr = [acr]; + + HandoverMediationRecord hmr = + new HandoverMediationRecord(alternativeCarrierRecordList: listAcr); + + expect(hmr.minPayloadLength, equals(1)); + + expect( + hmr.alternativeCarrierRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect( + hmr.allRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect(hmr.unknownRecordList, equals([])); + + expect(hmr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(hmr.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(hmr.type, equals([72, 109])); + expect(hmr.decodedType, equals('Hm')); + expect(hmr.fullType, equals('urn:nfc:wkt:Hm')); + expect(hmr.runtimeType, equals(HandoverMediationRecord)); + }); + + test('HandoverInitiateRecord Test', () { + // AlternativeCarrierRecord + AlternativeCarrierRecord acr = new AlternativeCarrierRecord( + carrierPowerState: CarrierPowerState.inactive, + carrierDataReference: latin1.encode('0')); + + List listAcr = [acr]; + + HandoverInitiateRecord hir = + new HandoverInitiateRecord(alternativeCarrierRecordList: listAcr); + + expect(hir.minPayloadLength, equals(1)); + + expect( + hir.allRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect( + hir.alternativeCarrierRecordList.toString(), + equals( + '[AlternativeCarrierRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=ac carrierPowerState=CarrierPowerState.inactive carrierDataReference=[48] auxDataReferences=[]]')); + expect(hir.unknownRecordList, equals([])); + + expect(hir.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect( + hir.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Hi ')); + expect(hir.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(hir.type, equals([72, 105])); + expect(hir.fullType, equals('urn:nfc:wkt:Hi')); + expect(hir.decodedType, equals('Hi')); + expect(hir.runtimeType, equals(HandoverInitiateRecord)); + }); + }); + + test('HandoverCarrierRecord Test', () { + List carrierDataList = [1, 2, 3]; + HandoverCarrierRecord hcr = new HandoverCarrierRecord( + carrierTnf: TypeNameFormat.nfcWellKnown, + carrierType: 'carrierTypeTest', + carrierData: Uint8List.fromList(carrierDataList)); + + expect(hcr.minPayloadLength, equals(1)); + + expect(hcr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(hcr.flags.runtimeType, equals(NDEFRecordFlags)); + + expect(hcr.type, equals([72, 99])); + expect(hcr.decodedType, equals('Hc')); + expect(hcr.fullType, equals('urn:nfc:wkt:Hc')); + expect(hcr.runtimeType, equals(HandoverCarrierRecord)); + expect(hcr.carrierType, equals('carrierTypeTest')); + + expect(hcr.carrierData, equals([1, 2, 3])); + expect(hcr.carrierTnf, equals(TypeNameFormat.nfcWellKnown)); + expect( + hcr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Hc ')); + }); + }); +} diff --git a/test/records/signature_test.dart b/test/records/signature_test.dart new file mode 100644 index 0000000..a28fa20 --- /dev/null +++ b/test/records/signature_test.dart @@ -0,0 +1,63 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/signature.dart'; +import 'package:ndef/utilities.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test('signature record', () { + List hexStrings = [ + "d10306536967200002000000", + "d1034d536967200b0200473045022100a410c28fd9437fd24f6656f121e62bcc5f65e36257f5faadf68e3e83d40d481a0220335b1dff8d6fe722fcf7018be9684d2de5670b256fdfc02aa25bdae16f624b8000", + ]; + + List> messages = [ + [SignatureRecord()], + [ + SignatureRecord( + signatureType: 'ECDSA-P256', + signature: ByteUtils.hexStringToBytes( + "3045022100a410c28fd9437fd24f6656f121e62bcc5f65e36257f5faadf68e3e83d40d481a0220335b1dff8d6fe722fcf7018be9684d2de5670b256fdfc02aa25bdae16f624b80")) + ], + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); + + group('ndef message with signature type', () { + test('SignatureRecord Test', () { + SignatureRecord sr = new SignatureRecord( + signatureType: 'ECDSA-P256', + signature: ByteUtils.hexStringToBytes( + "3045022100a410c28fd9437fd24f6656f121e62bcc5f65e36257f5faadf68e3e83d40d481a0220335b1dff8d6fe722fcf7018be9684d2de5670b256fdfc02aa25bdae16f624b80")); + + expect(sr.minPayloadLength, equals(6)); + + expect(sr.certificateFormat, equals('X.509')); + expect(sr.certificateFormatIndex, equals(0)); + expect(sr.certificateStore, equals([])); + expect(sr.certificateURI, equals('')); + expect(sr.hashTypeIndex, equals(2)); + + expect(sr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(sr.flags.runtimeType, equals(NDEFRecordFlags)); + expect(sr.signatureURI, equals('')); + expect( + sr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=Sig ')); + + expect(sr.type, equals([83, 105, 103])); + expect(sr.fullType, equals('urn:nfc:wkt:Sig')); + expect(sr.hashType, equals('SHA-256')); + expect(sr.runtimeType, equals(SignatureRecord)); + expect(sr.decodedType, equals('Sig')); + expect(sr.signatureType, equals('ECDSA-P256')); + expect(sr.signatureTypeIndex, equals(11)); + }); + }); +} diff --git a/test/records/smartposter_test.dart b/test/records/smartposter_test.dart new file mode 100644 index 0000000..1b68548 --- /dev/null +++ b/test/records/smartposter_test.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/smartposter.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test('smartposter record', () { + List hexStrings = [ + "d10249537091011655046769746875622e636f6d2f6e6663696d2f6e6465661101075402656e6e64656611030161637400120909696d6167652f706e676120706963747572655101047300002710", + "d1020f5370d1010b55046769746875622e636f6d", + ]; + + List> messages = [ + [ + SmartPosterRecord( + title: "ndef", + uri: "https://github.com/nfcim/ndef", + action: Action.exec, + icon: {"image/png": Uint8List.fromList(utf8.encode("a picture"))}, + size: 10000), + // typeInfo: null), + ], + [ + SmartPosterRecord(uri: "https://github.com"), + ] + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); + + group('ndef message with smart poster type', () { + SmartPosterRecord smartPosterRecord1 = SmartPosterRecord( + title: "ndef", + uri: "https://github.com/nfcim/ndef", + action: Action.exec, + icon: {"image/png": Uint8List.fromList(utf8.encode("a picture"))}, + size: 10000); + + SmartPosterRecord smartPosterRecord2 = + SmartPosterRecord(uri: "https://github.com"); + }); +} diff --git a/test/records/text_test.dart b/test/records/text_test.dart new file mode 100644 index 0000000..acedb66 --- /dev/null +++ b/test/records/text_test.dart @@ -0,0 +1,52 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/text.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test("text record", () { + List hexStrings = [ + "d1010f5402656e48656c6c6f20576f726c6421", + "d101145485656d6f6a69fffe3dd801de3dd802de3ed828dd" + ]; + + List> messages = [ + [TextRecord(language: 'en', text: 'Hello World!')], + [ + TextRecord( + language: 'emoji', text: '๐Ÿ˜๐Ÿ˜‚๐Ÿคจ', encoding: TextEncoding.UTF16) + ], + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); + + group('ndef message with text type', () { + test('TextRecord Test', () { + TextRecord tr = new TextRecord(language: 'emoji', text: 'Hello World!'); + + expect(tr.minPayloadLength, equals(1)); + + expect(tr.text, equals('Hello World!')); + expect(tr.language, equals('emoji')); + expect(tr.encoding, equals(TextEncoding.UTF8)); + expect(tr.encodingString, equals('UTF-8')); + + expect(tr.type, equals([84])); + expect(tr.fullType, equals('urn:nfc:wkt:T')); + expect(tr.decodedType, equals('T')); + expect(tr.runtimeType, equals(TextRecord)); + + expect(tr.tnf, equals(TypeNameFormat.nfcWellKnown)); + expect(tr.flags.runtimeType, equals(NDEFRecordFlags)); + expect( + tr.basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=T ')); + }); + }); +} diff --git a/test/records/uri_test.dart b/test/records/uri_test.dart new file mode 100644 index 0000000..ca77a79 --- /dev/null +++ b/test/records/uri_test.dart @@ -0,0 +1,84 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/ndef.dart'; +import 'package:ndef/record.dart'; +import 'package:ndef/record/uri.dart'; + +import '../common.dart'; + +void main() { + group('encode and decode', () { + test('uri record', () { + final urlName = "https://github.com/nfcim/ndef"; + final urlName2 = "https://github.com"; + + List hexStrings = [ + "91011655046769746875622e636f6d2f6e6663696d2f6e64656651010b55046769746875622e636f6d", + ]; + + List> messages = [ + [UriRecord.fromString(urlName), UriRecord.fromString(urlName2)], + ]; + + testParse(hexStrings, messages); + testGenerate(hexStrings, messages); + }); + }); + + group('ndef message with uri type', () { + final urlName = "https://github.com/nfcim/ndef"; + + test('test the all parts of a record', () { + expect(UriRecord.fromString(urlName).id, equals(null)); + expect(UriRecord.fromString(urlName).uri, equals(Uri.parse(urlName))); + + expect(UriRecord.fromString(urlName).uriString, equals(urlName)); + expect(UriRecord.fromString(urlName).iriString, equals(urlName)); + + List hexStringsTest = [ + "046769746875622e636f6d2f6e6663696d2f6e646566", + ]; + expect(UriRecord.fromString(urlName).payload, + equals(hexStringsTest[0].toBytes())); + expect(UriRecord.fromString(urlName).tnf, + equals(TypeNameFormat.nfcWellKnown)); + expect(UriRecord.fromString(urlName).flags.runtimeType, + equals(NDEFRecordFlags)); + + var comparisonValue; + for (int i = 0; i < UriRecord.prefixMap.length; i++) { + if (UriRecord.prefixMap[i] == UriRecord.fromString(urlName).prefix) { + comparisonValue = UriRecord.prefixMap[i]; + } + } + var actualValue = UriRecord.fromString(urlName).prefix; + expect(UriRecord.fromString(urlName).prefix, equals(comparisonValue)); + expect(UriRecord.fromString(urlName).content, + equals(urlName.replaceAll("$actualValue", ""))); + + expect(UriRecord.fromString(urlName).type, equals([85])); + expect(UriRecord.fromString(urlName).fullType, equals('urn:nfc:wkt:U')); + expect(UriRecord.fromString(urlName).decodedType, equals('U')); + expect(UriRecord.fromString(urlName).runtimeType, equals(UriRecord)); + + expect( + UriRecord.fromString(urlName).basicInfoString, + equals( + 'id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=U ')); + expect(UriRecord.fromString(urlName).maxPayloadLength, equals(null)); + expect(UriRecord.fromString(urlName).minPayloadLength, equals(1)); + + expect(UriRecord.fromString(urlName).idString, equals('(empty)')); + expect( + UriRecord.fromString(urlName).toString(), + equals( + 'UriRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=U uri=https://github.com/nfcim/ndef')); + }); + + test('test some exceptions', () { + final urlWrongPrefix = "http://github.com/nfcim/ndef"; + expect(() { + UriRecord.fromString(urlWrongPrefix).prefix = "htttp://"; + }, throwsArgumentError); + }); + }); +} diff --git a/test/utilities_test.dart b/test/utilities_test.dart new file mode 100644 index 0000000..fef1592 --- /dev/null +++ b/test/utilities_test.dart @@ -0,0 +1,27 @@ +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:ndef/utilities.dart'; + +void main() { + group('decode and encode', () { + test('main function', () { + assert(ByteUtils.bytesEqual(null, null) == true); + assert(ByteUtils.bytesEqual( + Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2])) == + false); + assert(ByteUtils.bytesEqual( + Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2, 4])) == + false); + assert(ByteUtils.bytesEqual( + Uint8List.fromList([1, 2, 3]), Uint8List.fromList([1, 2, 3])) == + true); + assert( + ByteUtils.bytesEqual(Uint8List.fromList([1, 2, 3]), null) == false); + + var bytes = Uint8List(0); + assert(bytes.toHexString() == ""); + assert(Uint8List.fromList([]).toHexString() == ""); + }); + }); +}