diff --git a/.swift-version b/.swift-version deleted file mode 100644 index 389f774..0000000 --- a/.swift-version +++ /dev/null @@ -1 +0,0 @@ -4.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 693f5c9..4bca742 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -osx_image: xcode9 +osx_image: xcode10.3 language: objective-c install: @@ -10,7 +10,7 @@ script: - swiftlint -- xcodebuild test -project ParserCombinator.xcodeproj -scheme ParserCombinator-iOS -destination 'platform=iOS Simulator,OS=latest,name=iPhone 7' +- xcodebuild test -project ParserCombinator.xcodeproj -scheme ParserCombinator-iOS -destination 'platform=iOS Simulator,OS=latest,name=iPhone 8' - xcodebuild test -project ParserCombinator.xcodeproj -scheme ParserCombinator-macOS -destination 'platform=macOS,arch=x86_64' -- xcodebuild test -project ParserCombinator.xcodeproj -scheme ParserCombinator-tvOS -destination 'platform=tvOS Simulator,name=Apple TV 1080p' +- xcodebuild test -project ParserCombinator.xcodeproj -scheme ParserCombinator-tvOS -destination 'platform=tvOS Simulator,OS=latest,name=Apple TV 4K' - xcodebuild -project ParserCombinator.xcodeproj -scheme ParserCombinator-watchOS \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ed357e1..e19cf71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,3 +38,13 @@ * Swift 4 and Xcode 9 updates. * Swiftlint version update to 0.22.0 * Add failure messages to all XCFail test cases. + +## Version 2.0.0 + +### *Released 2019-08-18* + +* Swift 5 and Xcode 10.3 updates. +* Swiftlint version update to 0.34.0 +* Remove string copies using Swift 5 string updates. +* Remove some typealiases masking Swift types for transparency. +* Increase unit test readability. diff --git a/ParserCombinator.podspec b/ParserCombinator.podspec index f52c6ed..aabd0ce 100644 --- a/ParserCombinator.podspec +++ b/ParserCombinator.podspec @@ -6,10 +6,10 @@ Pod::Spec.new do |s| s.name = 'ParserCombinator' - s.version = '1.1.0' + s.version = '2.0.0' s.summary = 'Exquisitely simple functional parsing in Swift.' s.description = <<-DESC -A simple parser combinator, created in Swift. Functional parser combinators can be extremely useful but can also be difficult to understand. ParserCombinator attempts to strip this back and create a simple and user friendly way to parse strings into other objects. Technical terms, like mooned, are avoided or explained if necessary and docs are provided in plain English, with examples. +A simple parser combinator, created in Swift. Functional parser combinators can be extremely useful but can also be difficult to understand. ParserCombinator attempts to strip this back and create a simple and user friendly way to parse complex strings into other objects. Technical terms, like 'monad', are avoided or explained if necessary and docs are provided in plain English, with examples. DESC s.homepage = 'https://github.com/tigerpixel/ParserCombinator' @@ -22,6 +22,7 @@ A simple parser combinator, created in Swift. Functional parser combinators can s.watchos.deployment_target = '2.0' s.osx.deployment_target = '10.9' s.tvos.deployment_target = '9.0' + s.swift_version = '5.0' s.source_files = 'Source/**/*.swift' end diff --git a/ParserCombinator.xcodeproj/project.pbxproj b/ParserCombinator.xcodeproj/project.pbxproj index 46b27d1..9f50f7a 100644 --- a/ParserCombinator.xcodeproj/project.pbxproj +++ b/ParserCombinator.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 0C12421E1E7B1AA400457CBA /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421A1E7B1AA400457CBA /* Parser.swift */; }; 0C12421F1E7B1AA400457CBA /* Parser+Run.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421B1E7B1AA400457CBA /* Parser+Run.swift */; }; 0C1242201E7B1AA400457CBA /* ParseResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421C1E7B1AA400457CBA /* ParseResult.swift */; }; - 0C1242211E7B1AA400457CBA /* TokenStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421D1E7B1AA400457CBA /* TokenStream.swift */; }; 0C1242231E7B1B0D00457CBA /* ParseResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1242141E7B1A8200457CBA /* ParseResultTests.swift */; }; 0C1242241E7B1B1000457CBA /* Parser+CombinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1242151E7B1A8200457CBA /* Parser+CombinatorTests.swift */; }; 0C131CC41E8320E000C60A38 /* ParserTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C131CC21E831E9600C60A38 /* ParserTestHelper.swift */; }; @@ -64,18 +63,15 @@ 0C26E0EB1E7BDA0300779771 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421A1E7B1AA400457CBA /* Parser.swift */; }; 0C26E0EC1E7BDA0300779771 /* Parser+Run.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421B1E7B1AA400457CBA /* Parser+Run.swift */; }; 0C26E0ED1E7BDA0300779771 /* ParseResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421C1E7B1AA400457CBA /* ParseResult.swift */; }; - 0C26E0EE1E7BDA0300779771 /* TokenStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421D1E7B1AA400457CBA /* TokenStream.swift */; }; 0C26E0EF1E7BDA2800779771 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421A1E7B1AA400457CBA /* Parser.swift */; }; 0C26E0F01E7BDA2800779771 /* Parser+Run.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421B1E7B1AA400457CBA /* Parser+Run.swift */; }; 0C26E0F11E7BDA2800779771 /* ParseResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421C1E7B1AA400457CBA /* ParseResult.swift */; }; - 0C26E0F21E7BDA2800779771 /* TokenStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421D1E7B1AA400457CBA /* TokenStream.swift */; }; 0C26E0F71E7BDA4B00779771 /* ParserCombinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C07C29E1E5251BA00A921A8 /* ParserCombinator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0C26E0F81E7BDA5800779771 /* ParserCombinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C07C29E1E5251BA00A921A8 /* ParserCombinator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0C26E1071E7BDB2500779771 /* ParserCombinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C07C29E1E5251BA00A921A8 /* ParserCombinator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0C26E1081E7BDB3B00779771 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421A1E7B1AA400457CBA /* Parser.swift */; }; 0C26E1091E7BDB3B00779771 /* Parser+Run.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421B1E7B1AA400457CBA /* Parser+Run.swift */; }; 0C26E10A1E7BDB3B00779771 /* ParseResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421C1E7B1AA400457CBA /* ParseResult.swift */; }; - 0C26E10B1E7BDB3B00779771 /* TokenStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C12421D1E7B1AA400457CBA /* TokenStream.swift */; }; 0C26E10C1E7BE73A00779771 /* ParseResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1242141E7B1A8200457CBA /* ParseResultTests.swift */; }; 0C26E10D1E7BE73A00779771 /* Parser+CombinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1242151E7B1A8200457CBA /* Parser+CombinatorTests.swift */; }; 0C26E10E1E7BE77700779771 /* ParseResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C1242141E7B1A8200457CBA /* ParseResultTests.swift */; }; @@ -134,7 +130,6 @@ 0C12421A1E7B1AA400457CBA /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = ""; }; 0C12421B1E7B1AA400457CBA /* Parser+Run.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Parser+Run.swift"; sourceTree = ""; }; 0C12421C1E7B1AA400457CBA /* ParseResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseResult.swift; sourceTree = ""; }; - 0C12421D1E7B1AA400457CBA /* TokenStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenStream.swift; sourceTree = ""; }; 0C1242251E7B1B8400457CBA /* ParserCombinator.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ParserCombinator.podspec; sourceTree = ""; }; 0C131CC21E831E9600C60A38 /* ParserTestHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParserTestHelper.swift; sourceTree = ""; }; 0C131CC71E8330AE00C60A38 /* StringParsers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringParsers.swift; sourceTree = ""; }; @@ -258,7 +253,6 @@ 0C3C65B41E85B96D009ED072 /* Parser+Combinators.swift */, 0C131CDE1E84A99B00C60A38 /* ParserOperators.swift */, 0C12421C1E7B1AA400457CBA /* ParseResult.swift */, - 0C12421D1E7B1AA400457CBA /* TokenStream.swift */, 0C1437901E7CC990006E3D06 /* ConvienienceParsers */, 0C14378E1E7CC94E006E3D06 /* FoundationExtensions */, ); @@ -512,53 +506,54 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0820; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1030; ORGANIZATIONNAME = "Tigerpixel Ltd"; TargetAttributes = { 0C07C29A1E5251BA00A921A8 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; 0C07C2A31E5251BB00A921A8 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; 0C26E09B1E7BD82800779771 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Manual; }; 0C26E0A31E7BD82900779771 = { CreatedOnToolsVersion = 8.2.1; DevelopmentTeam = X9VLH29SKZ; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; 0C26E0B71E7BD84C00779771 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; 0C26E0BF1E7BD84D00779771 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; 0C26E0FE1E7BDAEC00779771 = { CreatedOnToolsVersion = 8.2.1; - LastSwiftMigration = 0900; + LastSwiftMigration = 1030; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 0C07C2951E5251BA00A921A8 /* Build configuration list for PBXProject "ParserCombinator" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 0C07C2911E5251BA00A921A8; productRefGroup = 0C07C29C1E5251BA00A921A8 /* Products */; @@ -631,7 +626,7 @@ /* Begin PBXShellScriptBuildPhase section */ 0C1242271E7B303900457CBA /* ShellScript */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputPaths = ( @@ -640,7 +635,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -655,7 +650,6 @@ 0C12421F1E7B1AA400457CBA /* Parser+Run.swift in Sources */, 0C131CDF1E84A99B00C60A38 /* ParserOperators.swift in Sources */, 0C1242201E7B1AA400457CBA /* ParseResult.swift in Sources */, - 0C1242211E7B1AA400457CBA /* TokenStream.swift in Sources */, 0C14377D1E7CC179006E3D06 /* CharacterParsers.swift in Sources */, 0C131CD61E84937B00C60A38 /* NumberParsers.swift in Sources */, 0C3C65B51E85B96D009ED072 /* Parser+Combinators.swift in Sources */, @@ -692,7 +686,6 @@ 0C26E0EC1E7BDA0300779771 /* Parser+Run.swift in Sources */, 0C131CE11E84A99B00C60A38 /* ParserOperators.swift in Sources */, 0C26E0ED1E7BDA0300779771 /* ParseResult.swift in Sources */, - 0C26E0EE1E7BDA0300779771 /* TokenStream.swift in Sources */, 0C14377F1E7CC179006E3D06 /* CharacterParsers.swift in Sources */, 0C131CD81E84937B00C60A38 /* NumberParsers.swift in Sources */, 0C3C65B71E85B96D009ED072 /* Parser+Combinators.swift in Sources */, @@ -730,7 +723,6 @@ 0C3C65C71E85C7D2009ED072 /* Parser+Combinators.swift in Sources */, 0C131CE21E84A99B00C60A38 /* ParserOperators.swift in Sources */, 0C26E0F11E7BDA2800779771 /* ParseResult.swift in Sources */, - 0C26E0F21E7BDA2800779771 /* TokenStream.swift in Sources */, 0C1437801E7CC179006E3D06 /* CharacterParsers.swift in Sources */, 0C131CD91E84937B00C60A38 /* NumberParsers.swift in Sources */, ); @@ -766,7 +758,6 @@ 0C26E1091E7BDB3B00779771 /* Parser+Run.swift in Sources */, 0C131CE01E84A99B00C60A38 /* ParserOperators.swift in Sources */, 0C26E10A1E7BDB3B00779771 /* ParseResult.swift in Sources */, - 0C26E10B1E7BDB3B00779771 /* TokenStream.swift in Sources */, 0C14377E1E7CC179006E3D06 /* CharacterParsers.swift in Sources */, 0C131CD71E84937B00C60A38 /* NumberParsers.swift in Sources */, 0C3C65B61E85B96D009ED072 /* Parser+Combinators.swift in Sources */, @@ -798,6 +789,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -807,6 +799,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -814,6 +807,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -858,6 +852,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -867,6 +862,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -874,6 +870,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -926,8 +923,7 @@ PRODUCT_NAME = ParserCombinator; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -949,8 +945,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.tigerpixel.ParserCombinator; PRODUCT_NAME = ParserCombinator; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -963,8 +958,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.tigerpixel.ParserCombinatorTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -977,8 +971,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.tigerpixel.ParserCombinatorTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -1002,8 +995,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1027,8 +1019,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -1045,8 +1036,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.tigerpixel.ParserCombinator-macOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1063,8 +1053,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.tigerpixel.ParserCombinator-macOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -1085,8 +1074,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1109,8 +1097,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1126,8 +1113,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.tigerpixel.ParserCombinator-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Debug; @@ -1142,8 +1129,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.tigerpixel.ParserCombinator-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.1; }; name = Release; @@ -1165,8 +1152,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; @@ -1189,8 +1175,7 @@ PRODUCT_NAME = ParserCombinator; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; diff --git a/ParserCombinator.xcodeproj/xcshareddata/xcschemes/ParserCombinator-iOS.xcscheme b/ParserCombinator.xcodeproj/xcshareddata/xcschemes/ParserCombinator-iOS.xcscheme index f5eca3c..fb0d696 100644 --- a/ParserCombinator.xcodeproj/xcshareddata/xcschemes/ParserCombinator-iOS.xcscheme +++ b/ParserCombinator.xcodeproj/xcshareddata/xcschemes/ParserCombinator-iOS.xcscheme @@ -1,6 +1,6 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.1.0 + 2.0.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSHumanReadableCopyright diff --git a/README.md b/README.md index 3a35b0f..c7209c7 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Pull requests for improvements are welcome. There are no external requirements for this project, just Swift. - iOS 8.0+ / macOS 10.9+ / tvOS 9.0+ / watchOS 2.0+ -- Xcode 9.0+ -- Swift 4.0+ +- Xcode 10.3+ +- Swift 5.0+ For previous versions of Xcode and Swift please see prior releases. @@ -34,7 +34,7 @@ For previous versions of Xcode and Swift please see prior releases. ### Cocoapods -ParserCombinator is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile: +ParserCombinator is available through [CocoaPods](https://cocoapods.org/pods/ParserCombinator). To install it, simply add the following line to your Podfile: ```ruby pod "ParserCombinator" diff --git a/Source/CharacterParsers.swift b/Source/CharacterParsers.swift index c192e9b..d153132 100644 --- a/Source/CharacterParsers.swift +++ b/Source/CharacterParsers.swift @@ -33,7 +33,10 @@ public func character(condition: @escaping (Character) -> Bool) -> Parser Parser { - returns: The parser which will only allow the given characters to pass, all others will fail. */ public func character(isInString string: String) -> Parser { - return character { string.characters.contains($0) } + return character { string.contains($0) } } // MARK: Pre-made pasers using the character parser function for common sets of characters. @@ -117,7 +120,7 @@ public let whitespaceOrNewline = character(isInCharacterSet: .whitespacesAndNewl // MARK: Pre-made pasers using the character parser function for single everyday characters. /// Only the comma character will pass, all others will fail. -public let comma = character(isEqualTo:",") +public let comma = character(isEqualTo: ",") /// Only the full-stop character will pass, all others will fail. -public let fullstop = character(isEqualTo:".") +public let fullstop = character(isEqualTo: ".") diff --git a/Source/ParseResult.swift b/Source/ParseResult.swift index a537adf..9bd3502 100644 --- a/Source/ParseResult.swift +++ b/Source/ParseResult.swift @@ -17,7 +17,7 @@ public enum ParseResult { - case success(result: Output, tail: TokenStream) + case success(result: Output, tail: Substring) case failure(details: ParseFailure) } @@ -55,9 +55,8 @@ public extension ParseResult { public enum ParseFailure: Equatable { case insufficiantTokens - case unexpectedToken(token: TokenStream, tail: TokenStream) + case unexpectedToken(token: Character, tail: Substring) case custom(message: String) - } /** @@ -73,7 +72,7 @@ public func == (left: ParseFailure, right: ParseFailure) -> Bool { case (.insufficiantTokens, .insufficiantTokens): return true case (.unexpectedToken(let leftToken, let leftTail), .unexpectedToken(let rightToken, let rightTail)): - return String(leftToken) == String(rightToken) && String(leftTail) == String(rightTail) + return leftToken == rightToken && leftTail == rightTail case (.custom(let leftMesage), .custom(let rightMessage)): return leftMesage == rightMessage default: diff --git a/Source/Parser+Run.swift b/Source/Parser+Run.swift index 8048a11..fc91fe7 100644 --- a/Source/Parser+Run.swift +++ b/Source/Parser+Run.swift @@ -23,7 +23,7 @@ public extension Parser { */ func run(withInput input: String) -> ParseResult { - return parse(input.characters) + return parse(Substring(input)) } /** @@ -39,7 +39,7 @@ public extension Parser { func runAndResolve(withInput input: String) -> Output? { - guard case .success(let result, _) = parse(input.characters) else { + guard case .success(let result, _) = parse(Substring(input)) else { return nil } diff --git a/Source/Parser.swift b/Source/Parser.swift index 62f584f..c040842 100644 --- a/Source/Parser.swift +++ b/Source/Parser.swift @@ -15,8 +15,7 @@ public struct Parser { ///A function that specifices the consuming of zero or more tokens and resolving them into a result. - let parse: (TokenStream) -> ParseResult - + let parse: (Substring) -> ParseResult } public extension Parser { @@ -54,5 +53,5 @@ public extension Parser { public func pure(_ input: Output) -> Parser { - return Parser { .success(result: input, tail: $0) } + return Parser { ParseResult.success(result: input, tail: $0) } } diff --git a/Source/TokenStream.swift b/Source/TokenStream.swift deleted file mode 100644 index 624d6ad..0000000 --- a/Source/TokenStream.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// TokenStream.swift -// ParserCombinator -// -// Created by Liam on 15/02/2017. -// Copyright © 2017 Tigerpixel Ltd. All rights reserved. -// - -/** - A parser operates on the Strings character view for efficiency. - - The type is regularly used and so a typealias is required. - - In parser terms each character is a token. - */ - -public typealias TokenStream = String.CharacterView - -extension Character { - - func tokenized() -> TokenStream { - return String(self).characters - } - -} diff --git a/Tests/ParserCombinatorTests/CharacterParserTests+PremadeParsers.swift b/Tests/ParserCombinatorTests/CharacterParserTests+PremadeParsers.swift index 4be282e..5bc45a9 100644 --- a/Tests/ParserCombinatorTests/CharacterParserTests+PremadeParsers.swift +++ b/Tests/ParserCombinatorTests/CharacterParserTests+PremadeParsers.swift @@ -19,42 +19,42 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "b") { XCTAssertEqual("b", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "AB") { XCTAssertEqual("A", results.result) - XCTAssertEqual("B", String(results.tail)) + XCTAssertEqual("B", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "A1234") { XCTAssertEqual("A", results.result) - XCTAssertEqual("1234", String(results.tail)) + XCTAssertEqual("1234", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "1234") { - XCTAssertEqual("1", String(unexpected.token)) - XCTAssertEqual("234", String(unexpected.tail)) + XCTAssertEqual("1", unexpected.token) + XCTAssertEqual("234", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "1") { - XCTAssertEqual("1", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("1", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -68,35 +68,35 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual("a", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "ab") { XCTAssertEqual("a", results.result) - XCTAssertEqual("b", String(results.tail)) + XCTAssertEqual("b", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "aBCD") { XCTAssertEqual("a", results.result) - XCTAssertEqual("BCD", String(results.tail)) + XCTAssertEqual("BCD", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "Abcd") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("bcd", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("bcd", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "A") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -110,35 +110,35 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "AB") { XCTAssertEqual("A", results.result) - XCTAssertEqual("B", String(results.tail)) + XCTAssertEqual("B", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "Abcd") { XCTAssertEqual("A", results.result) - XCTAssertEqual("bcd", String(results.tail)) + XCTAssertEqual("bcd", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "aBCD") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("BCD", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("BCD", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "a") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -152,42 +152,42 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "1") { XCTAssertEqual("1", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "A1") { XCTAssertEqual("A", results.result) - XCTAssertEqual("1", String(results.tail)) + XCTAssertEqual("1", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "A#$%") { XCTAssertEqual("A", results.result) - XCTAssertEqual("#$%", String(results.tail)) + XCTAssertEqual("#$%", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "#BCD") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("BCD", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("BCD", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "#") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -201,28 +201,28 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "1") { XCTAssertEqual("1", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "1#$%") { XCTAssertEqual("1", results.result) - XCTAssertEqual("#$%", String(results.tail)) + XCTAssertEqual("#$%", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "#123") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("123", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("123", unexpected.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "A") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -237,28 +237,28 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: " ") { XCTAssertEqual(" ", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: " #$%") { XCTAssertEqual(" ", results.result) - XCTAssertEqual("#$%", String(results.tail)) + XCTAssertEqual("#$%", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "# ") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual(" ", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual(" ", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "A") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -271,28 +271,28 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: "\n") { XCTAssertEqual("\n", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "\n#$%") { XCTAssertEqual("\n", results.result) - XCTAssertEqual("#$%", String(results.tail)) + XCTAssertEqual("#$%", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "#\n") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("\n", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("\n", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "A") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -306,35 +306,35 @@ extension CharacterParserTests { if case .success(let results) = parserUnderTest.run(withInput: " ") { XCTAssertEqual(" ", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "\n") { XCTAssertEqual("\n", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "\n#$%") { XCTAssertEqual("\n", results.result) - XCTAssertEqual("#$%", String(results.tail)) + XCTAssertEqual("#$%", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "#\n ") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("\n ", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("\n ", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "A") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/Tests/ParserCombinatorTests/CharacterParserTests+SpecialCharacters.swift b/Tests/ParserCombinatorTests/CharacterParserTests+SpecialCharacters.swift index ee0127f..d2bdb4a 100644 --- a/Tests/ParserCombinatorTests/CharacterParserTests+SpecialCharacters.swift +++ b/Tests/ParserCombinatorTests/CharacterParserTests+SpecialCharacters.swift @@ -17,35 +17,35 @@ extension CharacterParserTests { if case .success(let results) = comma.run(withInput: ",") { XCTAssertEqual(",", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = comma.run(withInput: ",,") { XCTAssertEqual(",", results.result) - XCTAssertEqual(",", String(results.tail)) + XCTAssertEqual(",", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = comma.run(withInput: ",has a comma") { XCTAssertEqual(",", results.result) - XCTAssertEqual("has a comma", String(results.tail)) + XCTAssertEqual("has a comma", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: comma, with: "not a comma") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ot a comma", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ot a comma", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: comma, with: "1,") { - XCTAssertEqual("1", String(unexpected.token)) - XCTAssertEqual(",", String(unexpected.tail)) + XCTAssertEqual("1", unexpected.token) + XCTAssertEqual(",", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -58,35 +58,35 @@ extension CharacterParserTests { if case .success(let results) = fullstop.run(withInput: ".") { XCTAssertEqual(".", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = fullstop.run(withInput: "..") { XCTAssertEqual(".", results.result) - XCTAssertEqual(".", String(results.tail)) + XCTAssertEqual(".", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = fullstop.run(withInput: ".has a full stop") { XCTAssertEqual(".", results.result) - XCTAssertEqual("has a full stop", String(results.tail)) + XCTAssertEqual("has a full stop", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "not a full stop") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ot a full stop", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ot a full stop", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "1.") { - XCTAssertEqual("1", String(unexpected.token)) - XCTAssertEqual(".", String(unexpected.tail)) + XCTAssertEqual("1", unexpected.token) + XCTAssertEqual(".", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/Tests/ParserCombinatorTests/CharacterParserTests.swift b/Tests/ParserCombinatorTests/CharacterParserTests.swift index 89c1108..17bcc86 100644 --- a/Tests/ParserCombinatorTests/CharacterParserTests.swift +++ b/Tests/ParserCombinatorTests/CharacterParserTests.swift @@ -19,35 +19,35 @@ class CharacterParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "AA") { XCTAssertEqual("A", results.result) - XCTAssertEqual("A", String(results.tail)) + XCTAssertEqual("A", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "Atail") { XCTAssertEqual("A", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "nottoken") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ottoken", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ottoken", unexpected.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: ",A") { - XCTAssertEqual(",", String(unexpected.token)) - XCTAssertEqual("A", String(unexpected.tail)) + XCTAssertEqual(",", unexpected.token) + XCTAssertEqual("A", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -63,35 +63,35 @@ class CharacterParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "1") { XCTAssertEqual("1", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "12") { XCTAssertEqual("1", results.result) - XCTAssertEqual("2", String(results.tail)) + XCTAssertEqual("2", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "1tail") { XCTAssertEqual("1", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "nottoken") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ottoken", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ottoken", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: ",1") { - XCTAssertEqual(",", String(unexpected.token)) - XCTAssertEqual("1", String(unexpected.tail)) + XCTAssertEqual(",", unexpected.token) + XCTAssertEqual("1", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -105,35 +105,35 @@ class CharacterParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "AA") { XCTAssertEqual("A", results.result) - XCTAssertEqual("A", String(results.tail)) + XCTAssertEqual("A", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "Atail") { XCTAssertEqual("A", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "nottoken") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ottoken", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ottoken", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: ",A") { - XCTAssertEqual(",", String(unexpected.token)) - XCTAssertEqual("A", String(unexpected.tail)) + XCTAssertEqual(",", unexpected.token) + XCTAssertEqual("A", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -147,42 +147,42 @@ class CharacterParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "B") { XCTAssertEqual("B", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "AB") { XCTAssertEqual("A", results.result) - XCTAssertEqual("B", String(results.tail)) + XCTAssertEqual("B", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "Atail") { XCTAssertEqual("A", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "nottoken") { - XCTAssertEqual("n", String(unexpected.token)) - XCTAssertEqual("ottoken", String(unexpected.tail)) + XCTAssertEqual("n", unexpected.token) + XCTAssertEqual("ottoken", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: ",A") { - XCTAssertEqual(",", String(unexpected.token)) - XCTAssertEqual("A", String(unexpected.tail)) + XCTAssertEqual(",", unexpected.token) + XCTAssertEqual("A", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -198,14 +198,14 @@ class CharacterParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "A") { XCTAssertEqual("A", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "Atail") { XCTAssertEqual("A", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } diff --git a/Tests/ParserCombinatorTests/NumberParserTests.swift b/Tests/ParserCombinatorTests/NumberParserTests.swift index 0d01d58..8716c67 100644 --- a/Tests/ParserCombinatorTests/NumberParserTests.swift +++ b/Tests/ParserCombinatorTests/NumberParserTests.swift @@ -17,35 +17,35 @@ class NumberParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "1") { XCTAssertEqual(1, results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "10") { XCTAssertEqual(10, results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "1023") { XCTAssertEqual(1023, results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "123d") { XCTAssertEqual(123, results.result) - XCTAssertEqual("d", String(results.tail)) + XCTAssertEqual("d", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "aBCD") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("BCD", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("BCD", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/Tests/ParserCombinatorTests/ParseResultTests.swift b/Tests/ParserCombinatorTests/ParseResultTests.swift index 451de4c..1cec828 100644 --- a/Tests/ParserCombinatorTests/ParseResultTests.swift +++ b/Tests/ParserCombinatorTests/ParseResultTests.swift @@ -15,21 +15,20 @@ class ParseResultTests: XCTestCase { XCTAssertEqual(ParseFailure.insufficiantTokens, .insufficiantTokens) XCTAssertEqual(ParseFailure.custom(message: "one"), .custom(message: "one")) - XCTAssertEqual(ParseFailure.unexpectedToken(token:"a".characters, tail: "b".characters), - .unexpectedToken(token:"a".characters, tail: "b".characters)) + XCTAssertEqual(ParseFailure.unexpectedToken(token: "a", tail: "b"), + .unexpectedToken(token:"a", tail: "b")) // Different types. XCTAssertNotEqual(ParseFailure.insufficiantTokens, .custom(message: "")) - XCTAssertNotEqual(ParseFailure.insufficiantTokens, .unexpectedToken(token:"a".characters, tail: "c".characters)) - XCTAssertNotEqual(ParseFailure.unexpectedToken(token:"a".characters, tail: "c".characters), - .custom(message: "")) + XCTAssertNotEqual(ParseFailure.insufficiantTokens, .unexpectedToken(token:"a", tail: "c")) + XCTAssertNotEqual(ParseFailure.unexpectedToken(token: "a", tail: "c"), .custom(message: "")) // Same unexpected token with different contents. - XCTAssertNotEqual(ParseFailure.unexpectedToken(token:"a".characters, tail: "b".characters), - .unexpectedToken(token:"c".characters, tail: "c".characters)) + XCTAssertNotEqual(ParseFailure.unexpectedToken(token: "a", tail: "b"), + .unexpectedToken(token:"c", tail: "c")) - XCTAssertNotEqual(ParseFailure.unexpectedToken(token:"a".characters, tail: "b".characters), - .unexpectedToken(token:"a".characters, tail: "c".characters)) + XCTAssertNotEqual(ParseFailure.unexpectedToken(token: "a", tail: "b"), + .unexpectedToken(token:"a", tail: "c")) // Same custom type with different message. XCTAssertNotEqual(ParseFailure.custom(message: "one"), .custom(message: "two")) diff --git a/Tests/ParserCombinatorTests/Parser+CombinatorTests.swift b/Tests/ParserCombinatorTests/Parser+CombinatorTests.swift index 08f3d20..92dc298 100644 --- a/Tests/ParserCombinatorTests/Parser+CombinatorTests.swift +++ b/Tests/ParserCombinatorTests/Parser+CombinatorTests.swift @@ -9,11 +9,13 @@ import XCTest @testable import ParserCombinator +private let testParseAToTrue = ParserTestHelper.characterAtoTrueParser() + class ParserPlusCombinatorTests: XCTestCase { func testFollowedByParser() { - let parserUnderTest = ParserTestHelper.aParser().followed(by: ParserTestHelper.aParser()) + let parserUnderTest = testParseAToTrue.followed(by: testParseAToTrue) if case .success(let results) = parserUnderTest.run(withInput: "aa") { XCTAssertEqual(true, results.result.0) @@ -49,25 +51,26 @@ class ParserPlusCombinatorTests: XCTestCase { func testMakeOptionalParser() { - let parserUnderTest = ParserTestHelper.aParser().optional + let parserUnderTest = testParseAToTrue.optional if case .success(let results) = parserUnderTest.run(withInput: "aaa") { XCTAssertEqual(true, results.result) - XCTAssertEqual("aa", String(results.tail)) + XCTAssertEqual("aa", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual(true, results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } + // Succeeds even if not present as is optional. if case .success(let results) = parserUnderTest.run(withInput: "") { XCTAssertEqual(nil, results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } @@ -75,46 +78,46 @@ class ParserPlusCombinatorTests: XCTestCase { func testOneOrManyMatchesParser() { - let parserUnderTest = ParserTestHelper.aParser().oneOrMany + let parserUnderTest = testParseAToTrue.oneOrMany if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual([true], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "abab") { XCTAssertEqual([true, false, true, false], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } - XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest)) + XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest, with: "")) } func testZeroOneOrManyMatchesParser() { - let parserUnderTest = ParserTestHelper.aParser().zeroOneOrMany + let parserUnderTest = testParseAToTrue.zeroOneOrMany if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual([true], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "abab") { XCTAssertEqual([true, false, true, false], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "") { XCTAssertEqual([], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } @@ -122,33 +125,33 @@ class ParserPlusCombinatorTests: XCTestCase { func testRepeatsGivenNumberOfTimesParser() { - let parserUnderTest = ParserTestHelper.aParser().repeats(times: 3) + let parserUnderTest = testParseAToTrue.repeats(times: 3) // The following two tests look for both different inputs and behaviour over multiple runs. (ie do counts reset) if case .success(let results) = parserUnderTest.run(withInput: "aba") { XCTAssertEqual([true, false, true], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "baa") { XCTAssertEqual([false, true, true], results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "ababa") { XCTAssertEqual([true, false, true], results.result) - XCTAssertEqual("ba", String(results.tail)) + XCTAssertEqual("ba", results.tail) } else { XCTFail("The parser should succeed") } XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest, with: "ab")) XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest, with: "a")) - XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest)) + XCTAssert(ParserTestHelper.hasInsufficiantTokens(parser: parserUnderTest, with: "")) } } diff --git a/Tests/ParserCombinatorTests/Parser+RunTests.swift b/Tests/ParserCombinatorTests/Parser+RunTests.swift index 33fbb6c..5029252 100644 --- a/Tests/ParserCombinatorTests/Parser+RunTests.swift +++ b/Tests/ParserCombinatorTests/Parser+RunTests.swift @@ -9,44 +9,32 @@ import XCTest @testable import ParserCombinator +private let testParseAToTrue = ParserTestHelper.characterAtoTrueParser() + class ParserPlusRunTests: XCTestCase { // MARK: Run and resolve result to optional. func testRunAndResolveParserWithSuccessMatch() { - let testParser = ParserTestHelper.aParser() - - let output = testParser.runAndResolve(withInput: "a") - - XCTAssertEqual(true, output) + XCTAssertEqual(true, testParseAToTrue.runAndResolve(withInput: "a")) } func testRunAndResolveParserWithSuccessMismatch() { - let testParser = ParserTestHelper.aParser() - - let output = testParser.runAndResolve(withInput: "b") - - XCTAssertEqual(false, output) + XCTAssertEqual(false, testParseAToTrue.runAndResolve(withInput: "b")) } func testRunAndResolveParserWithNoInputTokens() { - let testParser = ParserTestHelper.aParser() - - let output = testParser.runAndResolve(withInput: "") - - XCTAssertEqual(nil, output) + XCTAssertEqual(nil, testParseAToTrue.runAndResolve(withInput: "")) } // MARK: Run and manually resolve result. func testRunParserWithSuccessMatch() { - let testParser = ParserTestHelper.aParser() - - let parseResult = testParser.run(withInput: "a") + let parseResult = testParseAToTrue.run(withInput: "a") guard case .success(let result, let tail) = parseResult else { XCTFail("Expected success case received \(parseResult).") @@ -54,14 +42,12 @@ class ParserPlusRunTests: XCTestCase { } XCTAssertEqual(true, result) - XCTAssertEqual("", String(tail)) + XCTAssertEqual("", tail) } func testRunParserWithSuccessMismatch() { - let testParser = ParserTestHelper.aParser() - - let parseResult = testParser.run(withInput: "b") + let parseResult = testParseAToTrue.run(withInput: "b") guard case .success(let result, let tail) = parseResult else { XCTFail("Expected success case received \(parseResult).") @@ -69,14 +55,12 @@ class ParserPlusRunTests: XCTestCase { } XCTAssertEqual(false, result) - XCTAssertEqual("", String(tail)) + XCTAssertEqual("", tail) } func testRunParserWithNoInputTokens() { - let testParser = ParserTestHelper.aParser() - - let parseResult = testParser.run(withInput: "") + let parseResult = testParseAToTrue.run(withInput: "") guard case .failure(let reason) = parseResult else { XCTFail("Expected failure case received \(parseResult).") diff --git a/Tests/ParserCombinatorTests/ParserOperatorTests+Combinations.swift b/Tests/ParserCombinatorTests/ParserOperatorTests+Combinations.swift index e5b26e8..d95dd37 100644 --- a/Tests/ParserCombinatorTests/ParserOperatorTests+Combinations.swift +++ b/Tests/ParserCombinatorTests/ParserOperatorTests+Combinations.swift @@ -18,17 +18,17 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { func curriedFunction(first: Character) -> (Character?) -> (Character) -> String { return { second in { third in let secondOrEmpty: Character = second ?? Character("-") - return "fun" + String(first) + String(secondOrEmpty) + String(third) + return "fun" + String([first, secondOrEmpty, third]) } } } - let a = ParserTestHelper.characterOrFailureParser(with: "a") - let b = ParserTestHelper.optionalCharacterParser(with: "b") - let c = ParserTestHelper.characterOrFailureParser(with: "c") - let d = ParserTestHelper.characterOrFailureParser(with: "d") - let e = ParserTestHelper.characterOrFailureParser(with: "e") - let f = ParserTestHelper.characterOrFailureParser(with: "f") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") + let bChar = ParserTestHelper.optionalCharacterParser(with: "b") + let cChar = ParserTestHelper.characterOrFailureParser(with: "c") + let dChar = ParserTestHelper.characterOrFailureParser(with: "d") + let eChar = ParserTestHelper.characterOrFailureParser(with: "e") + let fChar = ParserTestHelper.characterOrFailureParser(with: "f") /* Parse "a" then optionally "b" into curriedFunction as the first 2 parameters. For the final parameter... @@ -37,7 +37,7 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { The function returns "fun" followed by the character params or "-" for optional nil*/ - return curriedFunction <^> a b <*> c <* d <|> e *> f + return curriedFunction <^> aChar bChar <*> cChar <* dChar <|> eChar *> fChar } // MARK: Test combinations of operators. @@ -50,14 +50,14 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "abcd") { XCTAssertEqual("funabc", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "acd") { XCTAssertEqual("funa-c", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } @@ -66,14 +66,14 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "abef") { XCTAssertEqual("funabf", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "aef") { XCTAssertEqual("funa-f", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } @@ -94,43 +94,43 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { // NOTE: It could be argued that an insufficient tokens response is more appropriate here. if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "abc") { - XCTAssertEqual("c", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("c", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "ac") { - XCTAssertEqual("c", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("c", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "abd") { - XCTAssertEqual("d", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("d", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "ad") { - XCTAssertEqual("d", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("d", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "abf") { - XCTAssertEqual("f", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("f", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "af") { - XCTAssertEqual("f", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("f", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -144,29 +144,29 @@ class ParserOperatorPlusCombinationsTests: XCTestCase { let parserUnderTest = createAllOperatorsParser() if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "axcd") { - XCTAssertEqual("x", String(unexpected.token)) - XCTAssertEqual("cd", String(unexpected.tail)) + XCTAssertEqual("x", unexpected.token) + XCTAssertEqual("cd", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "aacd") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("cd", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("cd", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "adcd") { - XCTAssertEqual("d", String(unexpected.token)) - XCTAssertEqual("cd", String(unexpected.tail)) + XCTAssertEqual("d", unexpected.token) + XCTAssertEqual("cd", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "a#ef") { - XCTAssertEqual("#", String(unexpected.token)) - XCTAssertEqual("ef", String(unexpected.tail)) + XCTAssertEqual("#", unexpected.token) + XCTAssertEqual("ef", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/Tests/ParserCombinatorTests/ParserOperatorTests.swift b/Tests/ParserCombinatorTests/ParserOperatorTests.swift index 53ca3bf..d79e746 100644 --- a/Tests/ParserCombinatorTests/ParserOperatorTests.swift +++ b/Tests/ParserCombinatorTests/ParserOperatorTests.swift @@ -9,39 +9,39 @@ import XCTest @testable import ParserCombinator +private func twice(character: Character) -> String { + return String([character, character]) +} + class ParserOperatorTests: XCTestCase { // MARK: Test the functionlity of single operators. func testSequentialApplicationOperator() { - func twice(character: Character) -> String { - return String(character) + String(character) - } - // A parser where the result is a function. let function = Parser { .success(result: twice, tail: $0) } - let a = ParserTestHelper.characterOrFailureParser(with: "a") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") - let parserUnderTest = function <*> a // Result of "function" parser with "a" applied to it. + let parserUnderTest = function <*> aChar // Result of "function" parser with "a" applied to it. if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "atail") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "cba") { - XCTAssertEqual("c", String(unexpected.token)) - XCTAssertEqual("ba", String(unexpected.tail)) + XCTAssertEqual("c", unexpected.token) + XCTAssertEqual("ba", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -53,7 +53,7 @@ class ParserOperatorTests: XCTestCase { func twice(character: Character?) -> String { if let character = character { - return String(character) + String(character) + return String([character, character]) } return "" @@ -61,27 +61,27 @@ class ParserOperatorTests: XCTestCase { // A parser where the result is a function. let function = Parser { .success(result: twice, tail: $0) } - let a: Parser = ParserTestHelper.optionalCharacterParser(with: "a") + let aChar: Parser = ParserTestHelper.optionalCharacterParser(with: "a") - let parserUnderTest = function a // Result of "function" parser with "a" applied to it. + let parserUnderTest = function aChar // Result of "function" parser with "a" applied to it. if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "atail") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "cba") { XCTAssertEqual("", results.result) - XCTAssertEqual("cba", String(results.tail)) + XCTAssertEqual("cba", results.tail) } else { XCTFail("The parser should succeed") } @@ -91,31 +91,27 @@ class ParserOperatorTests: XCTestCase { func testFMapCombinatorOperator() { - func twice(character: Character) -> String { - return String(character) + String(character) - } - - let a = ParserTestHelper.characterOrFailureParser(with: "a") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") - let parserUnderTest = twice <^> a // Result of "function" with "a" applied to it. + let parserUnderTest = twice <^> aChar // Result of "function" with "a" applied to it. if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "atail") { XCTAssertEqual("aa", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "cba") { - XCTAssertEqual("c", String(unexpected.token)) - XCTAssertEqual("ba", String(unexpected.tail)) + XCTAssertEqual("c", unexpected.token) + XCTAssertEqual("ba", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -123,35 +119,35 @@ class ParserOperatorTests: XCTestCase { func testOrOperator() { - let a = ParserTestHelper.characterOrFailureParser(with: "a") - let b = ParserTestHelper.characterOrFailureParser(with: "b") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") + let bChar = ParserTestHelper.characterOrFailureParser(with: "b") - let parserUnderTest = a <|> b // "a" or "b" + let parserUnderTest = aChar <|> bChar // "a" or "b" if case .success(let results) = parserUnderTest.run(withInput: "a") { XCTAssertEqual("a", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "b") { XCTAssertEqual("b", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "atail") { XCTAssertEqual("a", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "cba") { - XCTAssertEqual("c", String(unexpected.token)) - XCTAssertEqual("ba", String(unexpected.tail)) + XCTAssertEqual("c", unexpected.token) + XCTAssertEqual("ba", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -161,42 +157,42 @@ class ParserOperatorTests: XCTestCase { func testDiscardFirstOperator() { - let a = ParserTestHelper.characterOrFailureParser(with: "a") - let b = ParserTestHelper.characterOrFailureParser(with: "b") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") + let bChar = ParserTestHelper.characterOrFailureParser(with: "b") - let parserUnderTest = a *> b // Check "a" followed by "b", but then only return "b" + let parserUnderTest = aChar *> bChar // Check "a" followed by "b", but then only return "b" if case .success(let results) = parserUnderTest.run(withInput: "ab") { XCTAssertEqual("b", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "abtail") { XCTAssertEqual("b", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "aad") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("d", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("d", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "bad") { - XCTAssertEqual("b", String(unexpected.token)) - XCTAssertEqual("ad", String(unexpected.tail)) + XCTAssertEqual("b", unexpected.token) + XCTAssertEqual("ad", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "b") { - XCTAssertEqual("b", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("b", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -207,42 +203,42 @@ class ParserOperatorTests: XCTestCase { func testDiscardSecondOperator() { - let a = ParserTestHelper.characterOrFailureParser(with: "a") - let b = ParserTestHelper.characterOrFailureParser(with: "b") + let aChar = ParserTestHelper.characterOrFailureParser(with: "a") + let bChar = ParserTestHelper.characterOrFailureParser(with: "b") - let parserUnderTest = a <* b // Check "a" followed by "b", but then only return "a" + let parserUnderTest = aChar <* bChar // Check "a" followed by "b", but then only return "a" if case .success(let results) = parserUnderTest.run(withInput: "ab") { XCTAssertEqual("a", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "abtail") { XCTAssertEqual("a", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "aad") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("d", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("d", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "bad") { - XCTAssertEqual("b", String(unexpected.token)) - XCTAssertEqual("ad", String(unexpected.tail)) + XCTAssertEqual("b", unexpected.token) + XCTAssertEqual("ad", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: parserUnderTest, with: "b") { - XCTAssertEqual("b", String(unexpected.token)) - XCTAssertEqual("", String(unexpected.tail)) + XCTAssertEqual("b", unexpected.token) + XCTAssertEqual("", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/Tests/ParserCombinatorTests/ParserTestHelper.swift b/Tests/ParserCombinatorTests/ParserTestHelper.swift index de9a2ef..86f4ef8 100644 --- a/Tests/ParserCombinatorTests/ParserTestHelper.swift +++ b/Tests/ParserCombinatorTests/ParserTestHelper.swift @@ -17,7 +17,7 @@ struct ParserTestHelper { /* Checks for a value of "a" and moves on one character (token). "a" resolves Bool true, anything else that is a token resolves Bool false. No tokens fails.*/ - static func aParser() -> Parser { + static func characterAtoTrueParser() -> Parser { return Parser { stream in @@ -43,9 +43,8 @@ struct ParserTestHelper { } guard character == streamToken else { - let token = streamToken.tokenized() let tail = stream.dropFirst() - return .failure(details: .unexpectedToken(token: token, tail: tail)) + return .failure(details: .unexpectedToken(token: streamToken, tail: tail)) } // Need to drop first element so tht the parser moves on. return .success(result: character, tail: stream.dropFirst()) @@ -83,7 +82,7 @@ struct ParserTestHelper { } static func findUnexpectedToken(running parser: Parser, with tokens: String) - -> (token: TokenStream, tail: TokenStream)? { + -> (token: Character, tail: Substring)? { if case .failure(let reason) = parser.run(withInput: tokens), diff --git a/Tests/ParserCombinatorTests/ParserTests.swift b/Tests/ParserCombinatorTests/ParserTests.swift index ab458ee..d33242a 100644 --- a/Tests/ParserCombinatorTests/ParserTests.swift +++ b/Tests/ParserCombinatorTests/ParserTests.swift @@ -16,18 +16,18 @@ class ParserTests: XCTestCase { func testMapParser() { // Boolean result of mapped to the strings 'true' and 'false'. - let parserUnderTest = ParserTestHelper.aParser().map { $0 ? "true" : "false" } + let parserUnderTest = ParserTestHelper.characterAtoTrueParser().map { $0 ? "true" : "false" } if case .success(let results) = parserUnderTest.run(withInput: "aaa") { XCTAssertEqual("true", results.result) - XCTAssertEqual("aa", String(results.tail)) + XCTAssertEqual("aa", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "sss") { XCTAssertEqual("false", results.result) - XCTAssertEqual("ss", String(results.tail)) + XCTAssertEqual("ss", results.tail) } else { XCTFail("The parser should succeed") } @@ -41,7 +41,7 @@ class ParserTests: XCTestCase { if case .success(let results) = aParser.run(withInput: "tail") { XCTAssertEqual("a", results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } @@ -50,7 +50,7 @@ class ParserTests: XCTestCase { if case .success(let results) = oneParser.run(withInput: "tail") { XCTAssertEqual(1, results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } @@ -59,7 +59,7 @@ class ParserTests: XCTestCase { if case .success(let results) = oneFloatParser.run(withInput: "tail") { XCTAssertEqual(1.0, results.result) - XCTAssertEqual("tail", String(results.tail)) + XCTAssertEqual("tail", results.tail) } else { XCTFail("The parser should succeed") } diff --git a/Tests/ParserCombinatorTests/StringParserTests.swift b/Tests/ParserCombinatorTests/StringParserTests.swift index 0ea975c..6347687 100644 --- a/Tests/ParserCombinatorTests/StringParserTests.swift +++ b/Tests/ParserCombinatorTests/StringParserTests.swift @@ -17,21 +17,21 @@ class StringParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "ABC") { XCTAssertEqual("ABC", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "ABCd") { XCTAssertEqual("ABC", results.result) - XCTAssertEqual("d", String(results.tail)) + XCTAssertEqual("d", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "aBCD") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("BCD", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("BCD", unexpected.tail) } else { XCTFail("The parser should succeed") } @@ -45,21 +45,21 @@ class StringParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "abc") { XCTAssertEqual("abc", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "abcD") { XCTAssertEqual("abc", results.result) - XCTAssertEqual("D", String(results.tail)) + XCTAssertEqual("D", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "Abcd") { - XCTAssertEqual("A", String(unexpected.token)) - XCTAssertEqual("bcd", String(unexpected.tail)) + XCTAssertEqual("A", unexpected.token) + XCTAssertEqual("bcd", unexpected.tail) } else { XCTFail("The parser should succeed") } @@ -73,21 +73,21 @@ class StringParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "aB3") { XCTAssertEqual("aB3", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "aB3£") { XCTAssertEqual("aB3", results.result) - XCTAssertEqual("£", String(results.tail)) + XCTAssertEqual("£", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "£Ab3") { - XCTAssertEqual("£", String(unexpected.token)) - XCTAssertEqual("Ab3", String(unexpected.tail)) + XCTAssertEqual("£", unexpected.token) + XCTAssertEqual("Ab3", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } @@ -101,21 +101,21 @@ class StringParserTests: XCTestCase { if case .success(let results) = parserUnderTest.run(withInput: "123") { XCTAssertEqual("123", results.result) - XCTAssertEqual("", String(results.tail)) + XCTAssertEqual("", results.tail) } else { XCTFail("The parser should succeed") } if case .success(let results) = parserUnderTest.run(withInput: "123d") { XCTAssertEqual("123", results.result) - XCTAssertEqual("d", String(results.tail)) + XCTAssertEqual("d", results.tail) } else { XCTFail("The parser should succeed") } if let unexpected = ParserTestHelper.findUnexpectedToken(running: fullstop, with: "a123") { - XCTAssertEqual("a", String(unexpected.token)) - XCTAssertEqual("123", String(unexpected.tail)) + XCTAssertEqual("a", unexpected.token) + XCTAssertEqual("123", unexpected.tail) } else { XCTFail("The parser should find an unexpected token") } diff --git a/install_swiftlint.sh b/install_swiftlint.sh index 3bd548f..2b4b6ad 100755 --- a/install_swiftlint.sh +++ b/install_swiftlint.sh @@ -7,7 +7,7 @@ set -e SWIFTLINT_PKG_PATH="/tmp/SwiftLint.pkg" -SWIFTLINT_PKG_URL="https://github.com/realm/SwiftLint/releases/download/0.22.0/SwiftLint.pkg" +SWIFTLINT_PKG_URL="https://github.com/realm/SwiftLint/releases/download/0.34.0/SwiftLint.pkg" wget --output-document=$SWIFTLINT_PKG_PATH $SWIFTLINT_PKG_URL