Skip to content

Commit

Permalink
Merge pull request #695 from haritowa/master
Browse files Browse the repository at this point in the history
Forward Mapping Context for Immutable Mapping
  • Loading branch information
tristanhimmelman committed Dec 11, 2016
2 parents 5d821dc + 7700472 commit de25cc2
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 5 deletions.
6 changes: 3 additions & 3 deletions Sources/ImmutableMappable.swift
Expand Up @@ -92,7 +92,7 @@ public extension Map {
guard let JSONObject = currentValue else {
throw MapError(key: key, currentValue: currentValue, reason: "Found unexpected nil value", file: file, function: function, line: line)
}
return try Mapper<T>().mapOrFail(JSONObject: JSONObject)
return try Mapper<T>(context: context).mapOrFail(JSONObject: JSONObject)
}

// MARK: [BaseMappable]
Expand All @@ -104,7 +104,7 @@ public extension Map {
throw MapError(key: key, currentValue: currentValue, reason: "Cannot cast to '[Any]'", file: file, function: function, line: line)
}
return try jsonArray.enumerated().map { i, JSONObject -> T in
return try Mapper<T>().mapOrFail(JSONObject: JSONObject)
return try Mapper<T>(context: context).mapOrFail(JSONObject: JSONObject)
}
}

Expand Down Expand Up @@ -132,7 +132,7 @@ public extension Map {
}
var value: [String: T] = [:]
for (key, json) in jsonDictionary {
value[key] = try Mapper<T>().mapOrFail(JSONObject: json)
value[key] = try Mapper<T>(context: context).mapOrFail(JSONObject: json)
}
return value
}
Expand Down
246 changes: 244 additions & 2 deletions Tests/ObjectMapperTests/MapContextTests.swift
Expand Up @@ -41,15 +41,17 @@ class MapContextTests: XCTestCase {
super.tearDown()
}

func testMappingWithContext() {
// MARK: - BaseMappable
// MARK: Single
func testMappingWithContext() {
let JSON = ["name": "Tristan"]
let context = Context(shouldMap: true)

let person = Mapper<Person>(context: context).map(JSON: JSON)

XCTAssertNotNil(person)
XCTAssertNotNil(person?.name)
}
}

func testMappingWithContextViaMappableExtension() {
let JSON = ["name": "Tristan"]
Expand All @@ -70,6 +72,179 @@ class MapContextTests: XCTestCase {
XCTAssertNil(person?.name)
}

// MARK: Nested
func testNestedMappingWithContext() {
let JSON = ["person": ["name": "Tristan"]]
let context = Context(shouldMap: true)

let nestedPerson = Mapper<NestedPerson>(context: context).map(JSON: JSON)

XCTAssertNotNil(nestedPerson)
XCTAssertNotNil(nestedPerson?.person?.name)
}

func testNestedMappingWithContextViaMappableExtension() {
let JSON = ["person": ["name": "Tristan"]]
let context = Context(shouldMap: true)

let nestedPerson = NestedPerson(JSON: JSON, context: context)

XCTAssertNotNil(nestedPerson)
XCTAssertNotNil(nestedPerson?.person?.name)
}

func testNestedMappingWithoutContext() {
let JSON = ["person": ["name": "Tristan"]]

let nestedPerson = Mapper<NestedPerson>().map(JSON: JSON)

XCTAssertNotNil(nestedPerson)
XCTAssertNil(nestedPerson?.person?.name)
}

// MARK: Array
func testArrayMappingWithContext() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]
let context = Context(shouldMap: true)

let person = Mapper<PersonList>(context: context).map(JSON: JSON)

XCTAssertNotNil(person)
XCTAssertNotNil(person?.persons)
}

func testArrayMappingWithContextViaMappableExtension() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]
let context = Context(shouldMap: true)

let person = PersonList(JSON: JSON, context: context)

XCTAssertNotNil(person)
XCTAssertNotNil(person?.persons)
}

func testArrayMappingWithoutContext() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]

let person = Mapper<PersonList>().map(JSON: JSON)

XCTAssertNotNil(person)
XCTAssertNil(person?.persons)
}

// MARK: ImmutableMappable
// MARK: Single
func testImmatableMappingWithContext() {
let JSON = ["name": "Anton"]
let context = ImmutableContext(isDeveloper: true)

let person = try? Mapper<ImmutablePerson>(context: context).map(JSON: JSON)

XCTAssertNotNil(person)

XCTAssertEqual(person?.isDeveloper ?? !context.isDeveloper, context.isDeveloper)
}

func testImmatableMappingWithContextViaMappableExtension() {
let JSON = ["name": "Anton"]
let context = ImmutableContext(isDeveloper: true)

let person = try? ImmutablePerson(JSON: JSON, context: context)

XCTAssertNotNil(person)
XCTAssertEqual(person?.isDeveloper ?? !context.isDeveloper, context.isDeveloper)
}

func testImmatableMappingWithoutContext() {
let JSON = ["name": "Anton"]

do {
let _ = try Mapper<ImmutablePerson>().map(JSON: JSON)
} catch ImmutablePersonMappingError.contextAbsense {
// Empty
} catch {
XCTFail()
}
}

// MARK: Nested
func testNestedImmutableMappingWithContext() {
let JSON = ["person": ["name": "Anton"]]
let context = ImmutableContext(isDeveloper: true)

let nestedPerson = try? Mapper<ImmutableNestedPerson>(context: context).map(JSON: JSON)

XCTAssertNotNil(nestedPerson)
XCTAssertEqual(nestedPerson?.person.isDeveloper ?? !context.isDeveloper, context.isDeveloper)
}

func testNestedImmutableMappingWithContextViaMappableExtension() {
let JSON = ["person": ["name": "Anton"]]
let context = ImmutableContext(isDeveloper: true)

let nestedPerson = try? ImmutableNestedPerson(JSON: JSON, context: context)

XCTAssertNotNil(nestedPerson)
XCTAssertEqual(nestedPerson?.person.isDeveloper ?? !context.isDeveloper, context.isDeveloper)
}

func testNestedImmutableMappingWithoutContext() {
let JSON = ["person": ["name": "Anton"]]

do {
let _ = try Mapper<ImmutableNestedPerson>().map(JSON: JSON)
} catch ImmutablePersonMappingError.contextAbsense {
return
} catch {
XCTFail()
}

XCTFail()
}

// MARK: Array
func testArrayImmutableMappingWithContext() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]
let context = ImmutableContext(isDeveloper: true)

let personList = try? Mapper<ImmutablePersonList>(context: context).map(JSON: JSON)

XCTAssertNotNil(personList)

personList?.persons.forEach { person in
XCTAssertEqual(person.isDeveloper, context.isDeveloper)
}
}

func testArrayImmutableMappingWithContextViaMappableExtension() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]
let context = ImmutableContext(isDeveloper: true)

let personList = try? ImmutablePersonList(JSON: JSON, context: context)

XCTAssertNotNil(personList)

personList?.persons.forEach { person in
XCTAssertEqual(person.isDeveloper, context.isDeveloper)
}
}

func testArrayImmutableMappingWithoutContext() {
let JSON = ["persons": [["name": "Tristan"], ["name": "Anton"]]]

do {
let _ = try Mapper<ImmutablePersonList>().map(JSON: JSON)
} catch ImmutablePersonMappingError.contextAbsense {
return
} catch {
XCTFail()
}

XCTFail()
}

// MARK: - Nested Types
// MARK: BaseMappable
struct Context: MapContext {
var shouldMap = false

Expand All @@ -91,4 +266,71 @@ class MapContextTests: XCTestCase {
}
}
}

class NestedPerson: Mappable {
var person: Person?

required init?(map: Map){

}

func mapping(map: Map) {
if (map.context as? Context)?.shouldMap == true {
person <- map["person"]
}
}
}

class PersonList: Mappable {
var persons: [Person]?

required init?(map: Map){

}

func mapping(map: Map) {
if (map.context as? Context)?.shouldMap == true {
persons <- map["persons"]
}
}
}

// MARK: ImmutableMappable
struct ImmutableContext: MapContext {
let isDeveloper: Bool
}

enum ImmutablePersonMappingError: Error {
case contextAbsense
}

struct ImmutablePerson: ImmutableMappable {
let name: String
let isDeveloper: Bool

init(map: Map) throws {
guard let context = map.context as? ImmutableContext else {
throw ImmutablePersonMappingError.contextAbsense
}

name = try map.value("name")
isDeveloper = context.isDeveloper
}
}

struct ImmutableNestedPerson: ImmutableMappable {
let person: ImmutablePerson

init(map: Map) throws {
person = try map.value("person")
}
}

struct ImmutablePersonList: ImmutableMappable {
let persons: [ImmutablePerson]

init(map: Map) throws {
persons = try map.value("persons")
}
}
}

0 comments on commit de25cc2

Please sign in to comment.