diff --git a/Cartfile.resolved b/Cartfile.resolved index 810925c..0aa7665 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ -github "Quick/Nimble" "v8.0.1" -github "Quick/Quick" "v2.1.0" +github "Quick/Nimble" "v8.1.1" +github "Quick/Quick" "v3.0.0" diff --git a/Fakery.podspec b/Fakery.podspec index e9abc61..29831bd 100755 --- a/Fakery.podspec +++ b/Fakery.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Fakery" - s.version = "4.1.1" + s.version = "4.1.2" s.summary = "Swift fake data generator" s.homepage = "https://github.com/vadymmarkov/Fakery" s.license = { diff --git a/Fakery.xcodeproj/project.pbxproj b/Fakery.xcodeproj/project.pbxproj index 129db89..997ae22 100644 --- a/Fakery.xcodeproj/project.pbxproj +++ b/Fakery.xcodeproj/project.pbxproj @@ -61,6 +61,10 @@ AC88DC0B21531E2E007198E6 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC88DC0A21531E2E007198E6 /* Date.swift */; }; AC88DC0E215330A4007198E6 /* DateSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC88DC0C215330A3007198E6 /* DateSpec.swift */; }; AC88DC0F215330A4007198E6 /* DateSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC88DC0C215330A3007198E6 /* DateSpec.swift */; }; + BA095628249CFAB8000DDFF4 /* FakerFromPathSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA095626249CFA9A000DDFF4 /* FakerFromPathSpec.swift */; }; + BA095629249CFAB8000DDFF4 /* FakerFromPathSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA095626249CFA9A000DDFF4 /* FakerFromPathSpec.swift */; }; + BA09562A249CFB39000DDFF4 /* en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = BCFFA14E1BF9F912005A3BC1 /* en-GB.json */; }; + BA09562B249CFB3A000DDFF4 /* en-GB.json in Resources */ = {isa = PBXBuildFile; fileRef = BCFFA14E1BF9F912005A3BC1 /* en-GB.json */; }; BC4477911BFA450D00E8FB15 /* Faker.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCFFA1681BF9F912005A3BC1 /* Faker.swift */; }; BC4477921BFA451400E8FB15 /* Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCFFA16A1BF9F912005A3BC1 /* Address.swift */; }; BC4477931BFA451600E8FB15 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCFFA16B1BF9F912005A3BC1 /* App.swift */; }; @@ -302,6 +306,7 @@ 90D66FB222833A3100545C90 /* Hobbit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hobbit.swift; sourceTree = ""; }; AC88DC0A21531E2E007198E6 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; AC88DC0C215330A3007198E6 /* DateSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSpec.swift; sourceTree = ""; }; + BA095626249CFA9A000DDFF4 /* FakerFromPathSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakerFromPathSpec.swift; sourceTree = ""; }; BC827FA81BFA3CE1005F09A4 /* Fakery.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Fakery.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BC827FB11BFA3CE1005F09A4 /* Fakery-macOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Fakery-macOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; BCF0DF3A1BF9F77E00427DB4 /* Fakery.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Fakery.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -582,6 +587,7 @@ children = ( D59B6CED1D99C5FD007CB072 /* ConfigSpec.swift */, D59B6CF11D99C5FD007CB072 /* FakerSpec.swift */, + BA095626249CFA9A000DDFF4 /* FakerFromPathSpec.swift */, D59B6CEE1D99C5FD007CB072 /* Data */, D59B6CF21D99C5FD007CB072 /* Generators */, ); @@ -853,6 +859,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BA09562B249CFB3A000DDFF4 /* en-GB.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -893,6 +900,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BA09562A249CFB39000DDFF4 /* en-GB.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1043,6 +1051,7 @@ D59B6D381D99C82E007CB072 /* NameSpec.swift in Sources */, D59B6D2F1D99C82E007CB072 /* ProviderSpec.swift in Sources */, 504F66ED22AE523A00F9CDB3 /* HouseSpec.swift in Sources */, + BA095629249CFAB8000DDFF4 /* FakerFromPathSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1113,6 +1122,7 @@ D59B6D281D99C82D007CB072 /* NameSpec.swift in Sources */, D59B6D1F1D99C82D007CB072 /* ProviderSpec.swift in Sources */, 504F66EC22AE523A00F9CDB3 /* HouseSpec.swift in Sources */, + BA095628249CFAB8000DDFF4 /* FakerFromPathSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/Fakery/Data/Parser.swift b/Sources/Fakery/Data/Parser.swift index 6ca545c..475ea2b 100644 --- a/Sources/Fakery/Data/Parser.swift +++ b/Sources/Fakery/Data/Parser.swift @@ -23,6 +23,16 @@ public final class Parser { loadData(forLocale: Config.defaultLocale) } } + + public init(locale: String = Config.defaultLocale, path: String) { + self.locale = locale + provider = Provider() + loadData(forLocale: locale, path: path) + + if locale != Config.defaultLocale { + loadData(forLocale: Config.defaultLocale, path: path) + } + } // MARK: - Parsing @@ -155,4 +165,16 @@ public final class Parser { data[locale] = localeJson } + + private func loadData(forLocale locale: String, path: String) { + guard let localeData = provider.dataForLocale(locale, path: path), + let parsedData = try? JSONSerialization.jsonObject(with: localeData, options: .allowFragments), + let json = parsedData as? [String: Any], + let localeJson = json[locale] else { + print("JSON file for '\(locale)' locale was not found.") + return + } + + data[locale] = localeJson + } } diff --git a/Sources/Fakery/Data/Provider.swift b/Sources/Fakery/Data/Provider.swift index 421f778..26418f8 100644 --- a/Sources/Fakery/Data/Provider.swift +++ b/Sources/Fakery/Data/Provider.swift @@ -32,16 +32,35 @@ public final class Provider { } } - if let path = path { - let fileURL = URL(fileURLWithPath: path) - - if let data = try? Data(contentsOf: fileURL) { - translation = data - translations[locale] = data - } + if let data = dataAtPath(path: path) { + translation = data + translations[locale] = data } } return translation } + + public func dataForLocale(_ locale: String, path: String) -> Data? { + var translation: Data? + + if let translationData = translations[locale] { + translation = translationData + } + else { + if let data = dataAtPath(path: path) { + translation = data + translations[locale] = data + } + } + return translation + } + + private func dataAtPath(path: String?) -> Data? { + if let path = path { + let fileURL = URL(fileURLWithPath: path) + return try? Data(contentsOf: fileURL) + } + return nil + } } diff --git a/Sources/Fakery/Faker.swift b/Sources/Fakery/Faker.swift index 58e912b..4dae6ce 100644 --- a/Sources/Fakery/Faker.swift +++ b/Sources/Fakery/Faker.swift @@ -60,4 +60,31 @@ public final class Faker { ham = Ham(parser: parser) house = House(parser: parser) } + + public init(locale: String = Config.defaultLocale, path: String) { + self.locale = locale + parser = Parser(locale: self.locale, path: path) + address = Address(parser: parser) + app = App(parser: parser) + zelda = Zelda(parser: parser) + business = Business(parser: parser) + cat = Cat(parser: parser) + company = Company(parser: parser) + commerce = Commerce(parser: parser) + gender = Gender(parser: parser) + internet = Internet(parser: parser) + lorem = Lorem(parser: parser) + name = Name(parser: parser) + phoneNumber = PhoneNumber(parser: parser) + team = Team(parser: parser) + number = Number() + bank = Bank(parser: parser) + date = Date() + hobbit = Hobbit(parser: parser) + car = Car(parser: parser) + programmingLanguage = ProgrammingLanguage(parser: parser) + vehicle = Vehicle(parser: parser) + ham = Ham(parser: parser) + house = House(parser: parser) + } } diff --git a/Tests/Fakery/FakerFromPathSpec.swift b/Tests/Fakery/FakerFromPathSpec.swift new file mode 100644 index 0000000..afad5e6 --- /dev/null +++ b/Tests/Fakery/FakerFromPathSpec.swift @@ -0,0 +1,126 @@ +import Quick +import Nimble +@testable import Fakery + +final class FakerFromPathSpec: QuickSpec { + override func spec() { + describe("Faker") { + var faker: Faker! + let testingLocale = "en-GB" + + beforeEach { + let testBundle = Bundle(for: type(of: self)) + let path = testBundle.path(forResource: testingLocale, ofType: "json") + faker = Faker(locale: testingLocale, path: path!) + } + + describe("#init") { + it("sets default values") { + expect(faker.locale).to(equal(testingLocale)) + expect(faker.parser.locale).to(equal(testingLocale)) + + expect(faker.address.parser).to(beIdenticalTo(faker.parser)) + expect(faker.app.parser).to(beIdenticalTo(faker.parser)) + expect(faker.zelda.parser).to(beIdenticalTo(faker.parser)) + expect(faker.business.parser).to(beIdenticalTo(faker.parser)) + expect(faker.commerce.parser).to(beIdenticalTo(faker.parser)) + expect(faker.gender.parser).to(beIdenticalTo(faker.parser)) + expect(faker.internet.parser).to(beIdenticalTo(faker.parser)) + expect(faker.lorem.parser).to(beIdenticalTo(faker.parser)) + expect(faker.name.parser).to(beIdenticalTo(faker.parser)) + expect(faker.phoneNumber.parser).to(beIdenticalTo(faker.parser)) + expect(faker.team.parser).to(beIdenticalTo(faker.parser)) + expect(faker.bank.parser).to(beIdenticalTo(faker.parser)) + expect(faker.programmingLanguage.parser).to(beIdenticalTo(faker.parser)) + expect(faker.vehicle.parser).to(beIdenticalTo(faker.parser)) + expect(faker.ham.parser).to(beIdenticalTo(faker.parser)) + expect(faker.house.parser).to(beIdenticalTo(faker.parser)) + } + } + + describe("#address") { + it("should be accessible") { + expect(faker.address).to(beAKindOf(Faker.Address.self)) + } + } + + describe("#app") { + it("should be accessible") { + expect(faker.app).to(beAKindOf(Faker.App.self)) + } + } + + describe("#zelda") { + it("should be accessible") { + expect(faker.zelda).to(beAKindOf(Faker.Zelda.self)) + } + } + + describe("#business") { + it("should be accessible") { + expect(faker.business).to(beAKindOf(Faker.Business.self)) + } + } + + describe("#commerce") { + it("should be accessible") { + expect(faker.commerce).to(beAKindOf(Faker.Commerce.self)) + } + } + + describe("#gender") { + it("should be accessible") { + expect(faker.gender).to(beAKindOf(Faker.Gender.self)) + } + } + + describe("#internet") { + it("should be accessible") { + expect(faker.internet).to(beAKindOf(Faker.Internet.self)) + } + } + + describe("#lorem") { + it("should be accessible") { + expect(faker.lorem).to(beAKindOf(Faker.Lorem.self)) + } + } + + describe("#name") { + it("should be accessible") { + expect(faker.name).to(beAKindOf(Faker.Name.self)) + } + } + + describe("#phoneNumber") { + it("should be accessible") { + expect(faker.phoneNumber).to(beAKindOf(Faker.PhoneNumber.self)) + } + } + + describe("#team") { + it("should be accessible") { + expect(faker.team).to(beAKindOf(Faker.Team.self)) + } + } + + describe("#bank") { + it("should be accessible") { + expect(faker.bank).to(beAKindOf(Faker.Bank.self)) + } + } + + describe("#programmingLanguage") { + it("should be accessible") { + expect(faker.programmingLanguage).to(beAKindOf(Faker.ProgrammingLanguage.self)) + } + } + + describe("#house") { + it("should be accessible") { + expect(faker.house).to(beAKindOf(Faker.House.self)) + } + } + } + } +}