diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f871d0..0c44164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. ## Next +* Fixed a bug in `EKSerializer` that prevented has one relationships from being properly serialized with non-nested keypaths. + ## [0.21.0](https://github.com/lucasmedeirosleite/EasyMapping/releases/tag/0.21.0) * Fixed potential buffer overflow when using scalar Objective-C properties(#155, #156). diff --git a/EasyMapping.xcodeproj/project.pbxproj b/EasyMapping.xcodeproj/project.pbxproj index 32bd1ec..af94bb7 100644 --- a/EasyMapping.xcodeproj/project.pbxproj +++ b/EasyMapping.xcodeproj/project.pbxproj @@ -125,6 +125,7 @@ /* Begin PBXFileReference section */ 3E1FB69B1EBE334A007CB0F4 /* EKObjectModelTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EKObjectModelTestCase.swift; path = Tests/EasyMappingTests/EKObjectModelTestCase.swift; sourceTree = ""; }; 3E1FB69D1EBE36D0007CB0F4 /* EKManagedObjectModelTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EKManagedObjectModelTestCase.swift; path = Tests/EasyMappingTests/EKManagedObjectModelTestCase.swift; sourceTree = ""; }; + 3E1FB6A01EBF95D9007CB0F4 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; }; 3E9A90E71EB24789006305D1 /* UniversalFramework_Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UniversalFramework_Base.xcconfig; sourceTree = ""; }; 3E9A90E81EB24789006305D1 /* UniversalFramework_Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UniversalFramework_Framework.xcconfig; sourceTree = ""; }; 3E9A90E91EB24789006305D1 /* UniversalFramework_Test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UniversalFramework_Test.xcconfig; sourceTree = ""; }; @@ -280,6 +281,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3E1FB69F1EBF95B9007CB0F4 /* Docs */ = { + isa = PBXGroup; + children = ( + 3E1FB6A01EBF95D9007CB0F4 /* CHANGELOG.md */, + ); + name = Docs; + sourceTree = ""; + }; 3E9A90EA1EB24809006305D1 /* Source */ = { isa = PBXGroup; children = ( @@ -495,6 +504,7 @@ 52D6D9721BEFF229002C0205 = { isa = PBXGroup; children = ( + 3E1FB69F1EBF95B9007CB0F4 /* Docs */, 3E9A912A1EB24827006305D1 /* Example */, 3E9A91291EB2481E006305D1 /* Tests */, 3E9A90EA1EB24809006305D1 /* Source */, diff --git a/Sources/EasyMapping/EKSerializer.m b/Sources/EasyMapping/EKSerializer.m index d2527e4..669bbd6 100644 --- a/Sources/EasyMapping/EKSerializer.m +++ b/Sources/EasyMapping/EKSerializer.m @@ -103,9 +103,8 @@ +(NSDictionary *)serializeObject:(id)object withMapping:(EKManagedObjectMapping if (hasOneObject) { NSDictionary *hasOneRepresentation = [self serializeObject:hasOneObject - withMapping:(EKManagedObjectMapping *)[[relationship objectClass] objectMapping] + withMapping:(EKManagedObjectMapping *)[relationship mappingForObject:hasOneObject] fromContext:context]; - if (relationship.nonNestedKeyPaths) { for (NSString * key in hasOneRepresentation.allKeys) diff --git a/Tests/EasyMappingTests/EKSerializerTestCase.swift b/Tests/EasyMappingTests/EKSerializerTestCase.swift index c528ea6..d38fe2c 100644 --- a/Tests/EasyMappingTests/EKSerializerTestCase.swift +++ b/Tests/EasyMappingTests/EKSerializerTestCase.swift @@ -119,6 +119,28 @@ class EKSerializerTestCase: XCTestCase { XCTAssertEqual(car?["year"] as? String, "2013") } + func testSerializesManagedObjectWithRootPath() { + ManagedPhone.register(ManagedMappingProvider.phoneMapping()) + ManagedCar.register(ManagedMappingProvider.carMapping()) + ManagedPerson.register(ManagedMappingProvider.personMapping()) + defer { + ManagedCar.register(nil) + ManagedPerson.register(nil) + ManagedPhone.register(nil) + } + + let info = FixtureLoader.dictionary(fromFileNamed: "Person.json") + let person = EKManagedObjectMapper.object(fromExternalRepresentation: info, with: ManagedMappingProvider.personMapping(), in: Storage.shared.context) as? ManagedPerson + + let serialized = EKSerializer.serializeObject(person!.car!, with: ManagedMappingProvider.carWithRootKeyMapping(), from: Storage.shared.context) + + let data = serialized["data"] as? [String:Any] + let car = data?["car"] as? [String:Any] + + XCTAssertEqual(car?["model"] as? String, "i30") + XCTAssertEqual(car?["year"] as? String, "2013") + } + func testSerializerShouldSerializeNestedKeypaths() { let sut = EKSerializer.serializeObject(Car.i30, with: MappingProvider.carNestedAttributesMapping()) @@ -292,4 +314,53 @@ class EKSerializerRelationshipsTestCase: XCTestCase { XCTAssertEqual(sut["email"] as? String, "lucastoc@gmail.com") XCTAssertEqual(sut["gender"] as? String, "male") } + + func testSerializationOfNonNestedManagedObjects() { + ManagedCar.register(ManagedMappingProvider.carMapping()) + ManagedPhone.register(ManagedMappingProvider.phoneMapping()) + ManagedPerson.register(ManagedMappingProvider.personMapping()) + defer { + ManagedCar.register(nil) + ManagedPhone.register(nil) + ManagedPerson.register(nil) + } + let info = FixtureLoader.dictionary(fromFileNamed: "Person.json") + let person = EKManagedObjectMapper.object(fromExternalRepresentation: info, + with: ManagedMappingProvider.personMapping(), + in: Storage.shared.context) as? ManagedPerson + let sut = EKSerializer.serializeObject(person!, with: ManagedMappingProvider.personNonNestedMapping(), from: Storage.shared.context) + + XCTAssertEqual(sut["carId"] as? Int, 3) + XCTAssertEqual(sut["carModel"] as? String, "i30") + XCTAssertEqual(sut["carYear"] as? String, "2013") + + XCTAssertEqual(sut["name"] as? String, "Lucas") + XCTAssertEqual(sut["email"] as? String, "lucastoc@gmail.com") + XCTAssertEqual(sut["gender"] as? String, "male") + } + + func testSerializeCollectionOfHasManyObjects() { + ManagedCar.register(ManagedMappingProvider.carMapping()) + ManagedPhone.register(ManagedMappingProvider.phoneMapping()) + ManagedPerson.register(ManagedMappingProvider.personMapping()) + defer { + ManagedCar.register(nil) + ManagedPhone.register(nil) + ManagedPerson.register(nil) + } + let info = FixtureLoader.dictionary(fromFileNamed: "Person.json") + let person = EKManagedObjectMapper.object(fromExternalRepresentation: info, + with: ManagedMappingProvider.personMapping(), + in: Storage.shared.context) as? ManagedPerson + let sut = EKSerializer.serializeObject(person!, + with: ManagedMappingProvider.personMapping(), + from: Storage.shared.context) + + guard let phones = sut["phones"] as? [[String:Any]] else { XCTFail(); return } + + XCTAssertEqual(phones.count, 2) + let numbers = phones.map { $0["number"] as? String } + XCTAssert(numbers.contains(where: { $0 == "1111-1111"})) + XCTAssert(numbers.contains(where: { $0 == "2222-222" })) + } }