Skip to content

Commit

Permalink
3.0.1
Browse files Browse the repository at this point in the history
alexdeem committed Jan 8, 2023
2 parents 011f791 + 19c2137 commit 084c1e8
Showing 17 changed files with 109 additions and 63 deletions.
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
timezone: "Australia/Sydney"
target-branch: "develop"

- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
timezone: "Australia/Sydney"
target-branch: "develop"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Swift
name: Build and Test

on:
push:
24 changes: 24 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Lint

on:
push:
branches: [ "master", "develop" ]
pull_request:
branches: [ "master", "develop" ]

jobs:
SwiftLint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: irgaly/setup-mint@v1
- name: SwiftLint
run: mint run swiftlint --strict
SwiftFormat:
runs-on: ubuntu-latest
needs: SwiftLint
steps:
- uses: actions/checkout@v3
- uses: irgaly/setup-mint@v1
- name: SwiftFormat Lint
run: mint run swiftformat --lint .
11 changes: 11 additions & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--swiftversion 5.7
--exclude .build

# rules
--disable redundantReturn
--disable andOperator
--disable wrapMultilineStatementBraces

# format options
--closingparen same-line
--nospaceoperators ..<, ...
9 changes: 2 additions & 7 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
disabled_rules:
- line_length
- function_body_length
- trailing_comma
- redundant_optional_initialization

opt_in_rules:

included:

excluded:

identifier_name:
min_length: 1
.build

cyclomatic_complexity:
warning: 12
error: 20
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

<a name="3.0.1"></a>
# [3.0.1](https://github.com/SwiftScream/URITemplate/compare/3.0.0...3.0.1) (2023-01-08)

- Add SwiftLint, SwiftFormat, Dependabot


<a name="3.0.0"></a>
# [3.0.0](https://github.com/SwiftScream/URITemplate/compare/2.1.0...3.0.0) (2023-01-02)

2 changes: 2 additions & 0 deletions Mintfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
realm/SwiftLint
nicklockwood/SwiftFormat
3 changes: 1 addition & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -29,5 +29,4 @@ let package = Package(
name: "ScreamURITemplateExample",
dependencies: ["ScreamURITemplate"]),
],
swiftLanguageVersions: [.v5]
)
swiftLanguageVersions: [.v5])
9 changes: 5 additions & 4 deletions Sources/ScreamURITemplate/Internal/Components.swift
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ extension Component {

internal struct LiteralComponent: Component {
let literal: Substring
init (_ string: Substring) {
init(_ string: Substring) {
literal = string
}

@@ -42,7 +42,7 @@ internal struct LiteralComponent: Component {

internal struct LiteralPercentEncodedTripletComponent: Component {
let literal: Substring
init (_ string: Substring) {
init(_ string: Substring) {
literal = string
}

@@ -56,12 +56,13 @@ internal struct ExpressionComponent: Component {
let variableList: [VariableSpec]
let templatePosition: String.Index

init (expressionOperator: ExpressionOperator, variableList: [VariableSpec], templatePosition: String.Index) {
init(expressionOperator: ExpressionOperator, variableList: [VariableSpec], templatePosition: String.Index) {
self.expressionOperator = expressionOperator
self.variableList = variableList
self.templatePosition = templatePosition
}

// swiftlint:disable:next cyclomatic_complexity
func expand(variables: [String: VariableValue]) throws -> String {
let configuration = expressionOperator.expansionConfiguration()
let expansions = try variableList.compactMap { variableSpec -> String? in
@@ -92,7 +93,7 @@ internal struct ExpressionComponent: Component {
} else {
throw FormatError.failure(reason: "Invalid Value Type")
}
} catch FormatError.failure(let reason) {
} catch let FormatError.failure(reason) {
throw URITemplate.Error.expansionFailure(position: templatePosition, reason: "Failed expanding variable \"\(variableSpec.name)\": \(reason)")
}
}
14 changes: 7 additions & 7 deletions Sources/ScreamURITemplate/Internal/Scanner.swift
Original file line number Diff line number Diff line change
@@ -25,8 +25,8 @@ internal struct Scanner {

public init(string: String) {
self.string = string
self.unicodeScalars = string.unicodeScalars
self.currentIndex = string.startIndex
unicodeScalars = string.unicodeScalars
currentIndex = string.startIndex
}

public var isComplete: Bool {
@@ -62,10 +62,10 @@ internal struct Scanner {
private mutating func scanExpressionOperator() throws -> ExpressionOperator {
let expressionOperator: ExpressionOperator
if expressionOperatorCharacterSet.contains(unicodeScalars[currentIndex]) {
guard let op = ExpressionOperator(rawValue: unicodeScalars[currentIndex]) else {
guard let `operator` = ExpressionOperator(rawValue: unicodeScalars[currentIndex]) else {
throw URITemplate.Error.malformedTemplate(position: currentIndex, reason: "Unsupported Operator")
}
expressionOperator = op
expressionOperator = `operator`
currentIndex = unicodeScalars.index(after: currentIndex)
} else {
expressionOperator = .simple
@@ -119,7 +119,7 @@ internal struct Scanner {
let secondIndex = remainingVariableName.index(after: index)
let thirdIndex = remainingVariableName.index(after: secondIndex)
if !hexCharacterSet.contains(unicodeScalars[secondIndex]) ||
!hexCharacterSet.contains(unicodeScalars[thirdIndex]) {
!hexCharacterSet.contains(unicodeScalars[thirdIndex]) {
throw URITemplate.Error.malformedTemplate(position: currentIndex, reason: "% must be percent-encoded in variable name")
}
let nextIndex = remainingVariableName.index(after: thirdIndex)
@@ -151,7 +151,7 @@ internal struct Scanner {
throw URITemplate.Error.malformedTemplate(position: currentIndex, reason: "Cannot parse prefix modifier length")
}
currentIndex = endIndex
return .prefix(length:length)
return .prefix(length: length)
default:
return .none
}
@@ -174,7 +174,7 @@ internal struct Scanner {
let thirdIndex = unicodeScalars.index(after: secondIndex)

if !hexCharacterSet.contains(unicodeScalars[secondIndex]) ||
!hexCharacterSet.contains(unicodeScalars[thirdIndex]) {
!hexCharacterSet.contains(unicodeScalars[thirdIndex]) {
throw URITemplate.Error.malformedTemplate(position: currentIndex, reason: "% must be percent-encoded in literal")
}

11 changes: 5 additions & 6 deletions Sources/ScreamURITemplate/Internal/ValueFormatting.swift
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
import Foundation

internal enum FormatError: Error {
//swiftlint:disable:next identifier_name superfluous_disable_command
case failure(reason: String)
}

@@ -30,7 +29,7 @@ internal extension StringProtocol {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String {
let modifiedValue: String
if let prefixLength = variableSpec.prefixLength() {
modifiedValue = String(self.prefix(prefixLength))
modifiedValue = String(prefix(prefixLength))
} else {
modifiedValue = String(self)
}
@@ -48,7 +47,7 @@ internal extension StringProtocol {
internal extension Array where Element: StringProtocol {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let separator = ","
let encodedExpansions = try self.map { element -> String in
let encodedExpansions = try map { element -> String in
return try percentEncode(string: String(element), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
}
if encodedExpansions.count == 0 {
@@ -66,7 +65,7 @@ internal extension Array where Element: StringProtocol {

func explodeForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let separator = expansionConfiguration.separator
let encodedExpansions = try self.map { element -> String in
let encodedExpansions = try map { element -> String in
let encodedElement = try percentEncode(string: String(element), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
if expansionConfiguration.named {
if encodedElement.isEmpty && expansionConfiguration.omittOrphanedEquals {
@@ -85,7 +84,7 @@ internal extension Array where Element: StringProtocol {

internal extension Dictionary where Key: StringProtocol, Value: StringProtocol {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let encodedExpansions = try self.map { key, value -> String in
let encodedExpansions = try map { key, value -> String in
let encodedKey = try percentEncode(string: String(key), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
let encodedValue = try percentEncode(string: String(value), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
return "\(encodedKey),\(encodedValue)"
@@ -102,7 +101,7 @@ internal extension Dictionary where Key: StringProtocol, Value: StringProtocol {

func explodeForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let separator = expansionConfiguration.separator
let encodedExpansions = try self.map { key, value -> String in
let encodedExpansions = try map { key, value -> String in
let encodedKey = try percentEncode(string: String(key), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
let encodedValue = try percentEncode(string: String(value), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet)
if expansionConfiguration.named && encodedValue.isEmpty && expansionConfiguration.omittOrphanedEquals {
3 changes: 1 addition & 2 deletions Sources/ScreamURITemplate/Internal/VariableSpec.swift
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ import Foundation

internal struct VariableSpec {
enum Modifier {
// swiftlint:disable:next identifier_name superfluous_disable_command
case prefix(length: Int)
case explode
case none
@@ -26,7 +25,7 @@ internal struct VariableSpec {
let modifier: Modifier

func prefixLength() -> Int? {
guard case .prefix(let length) = self.modifier else {
guard case let .prefix(length) = modifier else {
return nil
}
return length
4 changes: 1 addition & 3 deletions Sources/ScreamURITemplate/URITemplate.swift
Original file line number Diff line number Diff line change
@@ -21,10 +21,8 @@ extension Dictionary: VariableValue where Key: StringProtocol, Value: StringProt

public struct URITemplate {
public enum Error: Swift.Error {
// swiftlint:disable identifier_name superfluous_disable_command
case malformedTemplate(position: String.Index, reason: String)
case expansionFailure(position: String.Index, reason: String)
// swiftlint:enable identifier_name superfluous_disable_command
}

private let string: String
@@ -63,7 +61,7 @@ extension URITemplate: CustomStringConvertible {

extension URITemplate: ExpressibleByStringLiteral {
public init(stringLiteral value: StaticString) {
//swiftlint:disable:next force_try
// swiftlint:disable:next force_try
try! self.init(string: "\(value)")
}
}
2 changes: 0 additions & 2 deletions Tests/ScreamURITemplateTests/JSONValue.swift
Original file line number Diff line number Diff line change
@@ -16,14 +16,12 @@ import Foundation

public enum JSONValue: Decodable {
case null
//swiftlint:disable identifier_name superfluous_disable_command
case string(String)
case int(Int)
case double(Double)
case bool(Bool)
case object([String: JSONValue])
case array([JSONValue])
//swiftlint:enable identifier_name superfluous_disable_command

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
8 changes: 3 additions & 5 deletions Tests/ScreamURITemplateTests/TestFileTests.swift
Original file line number Diff line number Diff line change
@@ -12,11 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import XCTest
import ScreamURITemplate
import XCTest

class TestFileTests: XCTestCase {

private var templateString: String!
private var variables: [String: VariableValue]!
private var acceptableExpansions: [String]!
@@ -42,15 +41,15 @@ class TestFileTests: XCTestCase {
let template = try URITemplate(string: templateString)
_ = try template.process(variables: variables)
XCTFail("Did not throw")
} catch URITemplate.Error.malformedTemplate(let position, let reason) {
} catch let URITemplate.Error.malformedTemplate(position, reason) {
if failReason != nil {
XCTAssertEqual(failReason, reason)
}
if failPosition != nil {
let characters = templateString[..<position].count
XCTAssertEqual(failPosition, characters)
}
} catch URITemplate.Error.expansionFailure(let position, let reason) {
} catch let URITemplate.Error.expansionFailure(position, reason) {
if failReason != nil {
XCTAssertEqual(failReason, reason)
}
@@ -105,5 +104,4 @@ class TestFileTests: XCTestCase {

return fileTestSuite
}

}
37 changes: 19 additions & 18 deletions Tests/ScreamURITemplateTests/TestModels.swift
Original file line number Diff line number Diff line change
@@ -41,26 +41,26 @@ public struct TestCase {
extension JSONValue {
func toVariableValue() -> VariableValue? {
switch self {
case .int(let int):
case let .int(int):
return String(int)
case .double(let double):
case let .double(double):
return String(double)
case .string(let string):
case let .string(string):
return string
case .object(let object):
case let .object(object):
return object.mapValues { element -> String? in
switch element {
case .string(let string):
case let .string(string):
return string
default:
return nil
}
}.filter { $0.value != nil }
}.filter { $0.value != nil }
.mapValues { $0! }
case .array(let array):
case let .array(array):
return array.compactMap { element -> String? in
switch element {
case .string(let string):
case let .string(string):
return string
default:
return nil
@@ -73,24 +73,25 @@ extension JSONValue {
}

extension TestCase {
// swiftlint:disable:next cyclomatic_complexity
init?(_ data: [JSONValue]) {
if data.count < 2 {
return nil
}

guard let first = data.first, case .string(let template) = first else {
guard let first = data.first, case let .string(template) = first else {
return nil
}

let expansionsData = data[1]
switch expansionsData {
case .string(let string):
case let .string(string):
acceptableExpansions = [string]
shouldFail = false
case .array(let array):
case let .array(array):
acceptableExpansions = array.compactMap { value in
switch value {
case .string(let string):
case let .string(string):
return string
default:
return nil
@@ -104,16 +105,16 @@ extension TestCase {

self.template = template

var failPosition: Int? = nil
var failPosition: Int?
if data.count > 2 {
if case .int(let position) = data[2] {
if case let .int(position) = data[2] {
failPosition = position
}
}

var failReason: String? = nil
var failReason: String?
if data.count > 3 {
if case .string(let reason) = data[3] {
if case let .string(reason) = data[3] {
failReason = reason
}
}
@@ -130,10 +131,10 @@ public func parseTestFile(URL: URL) -> [TestGroup] {
return []
}

return testCollection.map { (testGroupName, testGroupData) in
return testCollection.map { testGroupName, testGroupData in
let variables = testGroupData.variables.mapValues { element in
return element.toVariableValue()
}.filter { return $0.value != nil}
}.filter { return $0.value != nil }
.mapValues { return $0! }

let testcases = testGroupData.testcases.compactMap { element in
10 changes: 4 additions & 6 deletions Tests/ScreamURITemplateTests/Tests.swift
Original file line number Diff line number Diff line change
@@ -12,11 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import XCTest
import ScreamURITemplate
import XCTest

class Tests: XCTestCase {

func testCustomStringConvertible() {
let template: URITemplate = "https://api.github.com/repos/{owner}/{repo}/collaborators/{username}"
XCTAssertEqual(template.description, "https://api.github.com/repos/{owner}/{repo}/collaborators/{username}")
@@ -58,7 +57,7 @@ class Tests: XCTestCase {
XCTAssertEqual(templateA1.hashValue, templateA2.hashValue)
XCTAssertEqual(templateB1.hashValue, templateB2.hashValue)
}

func testVariableNames() {
let template: URITemplate = "https://api.github.com/repos/{owner}/{repo}/collaborators/{username}"
let variableNames = template.variableNames
@@ -92,7 +91,7 @@ class Tests: XCTestCase {
}

func testInitPerformance() {
self.measure {
measure {
for _ in 1...5000 {
_ = try? URITemplate(string: "https://api.github.com/repos/{owner}/{repo}/collaborators/{username}")
}
@@ -105,11 +104,10 @@ class Tests: XCTestCase {
"repo": "URITemplate",
"username": "alexdeem"]

self.measure {
measure {
for _ in 1...5000 {
_ = try? template.process(variables: variables)
}
}
}

}

0 comments on commit 084c1e8

Please sign in to comment.