<commit_before>import Quick
import Nimble
@testable import KeyedMapper

fileprivate struct SubModel: Mappable {
    fileprivate enum Key: String, JSONKey {
        case stringProperty
    }

    fileprivate let stringProperty: String
    
    fileprivate init(map: KeyedMapper<SubModel>) throws {
        try self.stringProperty = map.from(.stringProperty)
    }
}

fileprivate struct Model: Mappable {
    fileprivate enum Key: String, JSONKey {
        case mappableProperty
    }
    
    fileprivate let mappableProperty: SubModel
    
    fileprivate init(map: KeyedMapper<Model>) throws {
        try self.mappableProperty = map.from(.mappableProperty)
    }
}

fileprivate struct ModelWithArrayProperty: Mappable {
    fileprivate enum Key: String, JSONKey {
        case arrayMappableProperty
    }

    fileprivate let arrayMappableProperty: [SubModel]

    fileprivate init(map: KeyedMapper<ModelWithArrayProperty>) throws {
        try self.arrayMappableProperty = map.from(.arrayMappableProperty)
    }
}


fileprivate struct ModelWithTwoDArrayProperty: Mappable {
    fileprivate enum Key: String, JSONKey {
        case twoDArrayMappableProperty
    }

    fileprivate let twoDArrayMappableProperty: [[SubModel]]

    fileprivate init(map: KeyedMapper<ModelWithTwoDArrayProperty>) throws {
        try self.twoDArrayMappableProperty = map.from(.twoDArrayMappableProperty)
    }
}

class KeyedMapper_MappableSpec: QuickSpec {
    override func spec() {
        describe("from<T: Mappable> -> T") {
            context("when the value in the JSON is not an Dictionary") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    
                    do {
                        let _: SubModel = try mapper.from(.mappableProperty)
                    } catch let error as MapperError {
                        expect(error) == MapperError.typeMismatch(field: Model.Key.mappableProperty.stringValue, forType: Model.self, value: expectedValue, expectedType: NSDictionary.self)
                    } catch {
                        XCTFail("Error thrown from KeyedMapper<T: Mappable>.from was not a MapperError")
                    }
                }
            }
            
            context("when the value in the JSON is an Dictionary") {
                it("should map correctly") {
                    let expectedValue = ["stringProperty" : ""]
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel = try! mapper.from(.mappableProperty)
                    
                    expect(model).toNot(beNil())
                }
            }
        }
        
        describe("from<T: Mappable> -> [T]") {
            context("when the value in the JSON is not an array of Dictionaries") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["arrayMappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithArrayProperty.self)
                    let field = ModelWithArrayProperty.Key.arrayMappableProperty
                    
                    do {
                        let _: [SubModel] = try mapper.from(field)
                    } catch let error as MapperError {
                        expect(error) == MapperError.typeMismatch(field: field.stringValue, forType: ModelWithArrayProperty.self, value: expectedValue, expectedType: [NSDictionary].self)
                    } catch {
                        XCTFail("Error thrown from KeyedMapper<T: Mappable>.from was not a MapperError")
                    }
                }
            }
            
            context("when the value in the JSON is an array of Dictionaries") {
                it("should map correctly") {
                    let expectedValue = [["stringProperty" : ""]]
                    let dict: NSDictionary = ["arrayMappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithArrayProperty.self)
                    let models: [SubModel] = try! mapper.from(.arrayMappableProperty)
                    
                    expect(models).toNot(beNil())
                    expect(models.count) == expectedValue.count
                }
            }
        }
        
        describe("optionalFrom<T: Mappable> -> T?") {
            context("when the value in the JSON is not an Dictionary") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel? = mapper.optionalFrom(.mappableProperty)
                    
                    expect(model).to(beNil())
                }
            }
            
            context("when the value in the JSON is an Dictionary") {
                it("should map correctly") {
                    let expectedValue = ["stringProperty" : ""]
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel? = mapper.optionalFrom(.mappableProperty)<commit_msg>Added tests for from<T: Mappable> -> [[T]].<commit_after>import Quick
import Nimble
@testable import KeyedMapper

fileprivate struct SubModel: Mappable {
    fileprivate enum Key: String, JSONKey {
        case stringProperty
    }

    fileprivate let stringProperty: String
    
    fileprivate init(map: KeyedMapper<SubModel>) throws {
        try self.stringProperty = map.from(.stringProperty)
    }
}

fileprivate struct Model: Mappable {
    fileprivate enum Key: String, JSONKey {
        case mappableProperty
    }
    
    fileprivate let mappableProperty: SubModel
    
    fileprivate init(map: KeyedMapper<Model>) throws {
        try self.mappableProperty = map.from(.mappableProperty)
    }
}

fileprivate struct ModelWithArrayProperty: Mappable {
    fileprivate enum Key: String, JSONKey {
        case arrayMappableProperty
    }

    fileprivate let arrayMappableProperty: [SubModel]

    fileprivate init(map: KeyedMapper<ModelWithArrayProperty>) throws {
        try self.arrayMappableProperty = map.from(.arrayMappableProperty)
    }
}


fileprivate struct ModelWithTwoDArrayProperty: Mappable {
    fileprivate enum Key: String, JSONKey {
        case twoDArrayMappableProperty
    }

    fileprivate let twoDArrayMappableProperty: [[SubModel]]

    fileprivate init(map: KeyedMapper<ModelWithTwoDArrayProperty>) throws {
        try self.twoDArrayMappableProperty = map.from(.twoDArrayMappableProperty)
    }
}

class KeyedMapper_MappableSpec: QuickSpec {
    override func spec() {
        describe("from<T: Mappable> -> T") {
            context("when the value in the JSON is not an Dictionary") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    
                    do {
                        let _: SubModel = try mapper.from(.mappableProperty)
                    } catch let error as MapperError {
                        expect(error) == MapperError.typeMismatch(field: Model.Key.mappableProperty.stringValue, forType: Model.self, value: expectedValue, expectedType: NSDictionary.self)
                    } catch {
                        XCTFail("Error thrown from KeyedMapper<T: Mappable>.from was not a MapperError")
                    }
                }
            }
            
            context("when the value in the JSON is an Dictionary") {
                it("should map correctly") {
                    let expectedValue = ["stringProperty" : ""]
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel = try! mapper.from(.mappableProperty)
                    
                    expect(model).toNot(beNil())
                }
            }
        }
        
        describe("from<T: Mappable> -> [T]") {
            context("when the value in the JSON is not an array of Dictionaries") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["arrayMappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithArrayProperty.self)
                    let field = ModelWithArrayProperty.Key.arrayMappableProperty
                    
                    do {
                        let _: [SubModel] = try mapper.from(field)
                    } catch let error as MapperError {
                        expect(error) == MapperError.typeMismatch(field: field.stringValue, forType: ModelWithArrayProperty.self, value: expectedValue, expectedType: [NSDictionary].self)
                    } catch {
                        XCTFail("Error thrown from KeyedMapper<T: Mappable>.from was not a MapperError")
                    }
                }
            }
            
            context("when the value in the JSON is an array of Dictionaries") {
                it("should map correctly") {
                    let expectedValue = [["stringProperty" : ""]]
                    let dict: NSDictionary = ["arrayMappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithArrayProperty.self)
                    let models: [SubModel] = try! mapper.from(.arrayMappableProperty)
                    
                    expect(models).toNot(beNil())
                    expect(models.count) == expectedValue.count
                }
            }
        }

        describe("from<T: Mappable> -> [[T]]") {
            context("when the value in the JSON is not a two d array of Dictionaries") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let field = ModelWithTwoDArrayProperty.Key.twoDArrayMappableProperty
                    let dict: NSDictionary = [field.rawValue : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithTwoDArrayProperty.self)

                    do {
                        let _: [[SubModel]] = try mapper.from(field)
                    } catch let error as MapperError {
                        expect(error) == MapperError.typeMismatch(field: field.stringValue, forType: ModelWithTwoDArrayProperty.self, value: expectedValue, expectedType: [[NSDictionary]].self)
                    } catch {
                        XCTFail("Error thrown from KeyedMapper<T: Mappable>.from was not a MapperError")
                    }
                }
            }

            context("when the value in the JSON is an array of Dictionaries") {
                it("should map correctly") {
                    let expectedValue = [[SubModel.Key.stringProperty.rawValue : ""]]
                    let dict: NSDictionary = [ModelWithTwoDArrayProperty.Key.twoDArrayMappableProperty.rawValue : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: ModelWithTwoDArrayProperty.self)
                    let models: [SubModel] = try! mapper.from(.twoDArrayMappableProperty)

                    expect(models).toNot(beNil())
                    expect(models.count) == expectedValue.count
                }
            }
        }
        
        describe("optionalFrom<T: Mappable> -> T?") {
            context("when the value in the JSON is not an Dictionary") {
                it("should throw a typeMismatch error") {
                    let expectedValue = 2
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel? = mapper.optionalFrom(.mappableProperty)
                    
                    expect(model).to(beNil())
                }
            }
            
            context("when the value in the JSON is an Dictionary") {
                it("should map correctly") {
                    let expectedValue = ["stringProperty" : ""]
                    let dict: NSDictionary = ["mappableProperty" : expectedValue]
                    let mapper = KeyedMapper(JSON: dict, type: Model.self)
                    let model: SubModel? = mapper.optionalFrom(.mappableProperty)
{'fraction_non_alphanumeric': 0.08213079521031624, 'fraction_numerical': 0.0005373042677310408, 'mean_word_length': 1.7354608440058787, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1566249', 'n_tokens_mistral': 3381, 'n_tokens_neox': 3191, 'n_words': 834}