Skip to content

Commit

Permalink
Filters with parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
djbe authored May 17, 2017
2 parents 53b90b7 + d956026 commit 4191eb1
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ _None_
* Removed the `join` filter, as it's now integrated in `Stencil` proper.
[David Jennes](https://github.com/djbe)
[#10](https://github.com/SwiftGen/StencilSwiftKit/pull/10)
* Refactored the `snakeToCamelCase` filter to now accept an (optional) boolean parameter to control the `noPrefix` behaviour.
[David Jennes](https://github.com/djbe)
[#41](https://github.com/SwiftGen/StencilSwiftKit/pull/41)

### New Features

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* [String filters](Documentation/filters-strings.md):
* `escapeReservedKeywords`: Escape keywods reserved in the Swift language, by wrapping them inside backticks so that the can be used as regular escape keywords in Swift code.
* `lowerFirstWord`
* `snakeToCamelCase` / `snakeToCamelCaseNoPrefix`
* `snakeToCamelCase`: Transforms text from snake_case to camelCase. By default it keeps leading underscores, unless a single optional argument is set to "true", "no" or "0".
* `camelToSnakeCase`: Transforms text from camelCase to snake_case. By default it converts to lower case, unless a single optional argument is set to "false", "no" or "0".
* `swiftIdentifier`: Transforms an arbitrary string into a valid Swift identifier (using only valid characters for a Swift identifier as defined in the Swift language reference)
* `titlecase`
Expand Down
1 change: 0 additions & 1 deletion Sources/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public extension Extension {
registerFilter("swiftIdentifier", filter: Filters.Strings.stringToSwiftIdentifier)
registerFilter("lowerFirstWord", filter: Filters.Strings.lowerFirstWord)
registerFilter("snakeToCamelCase", filter: Filters.Strings.snakeToCamelCase)
registerFilter("snakeToCamelCaseNoPrefix", filter: Filters.Strings.snakeToCamelCaseNoPrefix)
registerFilter("camelToSnakeCase", filter: Filters.Strings.camelToSnakeCase)
registerFilter("titlecase", filter: Filters.Strings.titlecase)
registerFilter("hexToInt", filter: Filters.Numbers.hexToInt)
Expand Down
41 changes: 24 additions & 17 deletions Sources/Filters+Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,37 @@ extension Filters {
return titlecase(string)
}

static func snakeToCamelCase(_ value: Any?) throws -> Any? {
guard let string = value as? String else { throw Filters.Error.invalidInputType }
guard let noPrefix = try snakeToCamelCaseNoPrefix(value) else {
return nil
}
var prefixUnderscores = ""
for scalar in string.unicodeScalars {
guard scalar == "_" else { break }
prefixUnderscores += "_"
}

return prefixUnderscores + ("\(noPrefix)")
}

static func snakeToCamelCaseNoPrefix(_ value: Any?) throws -> Any? {
/// Converts snake_case to camelCase. Takes an optional Bool argument for removing any resulting
/// leading '_' characters, which defaults to false
///
/// - Parameters:
/// - value: the value to be processed
/// - arguments: the arguments to the function; expecting zero or one boolean argument
/// - Returns: the camel case string
/// - Throws: FilterError.invalidInputType if the value parameter isn't a string
static func snakeToCamelCase(_ value: Any?, arguments: [Any?]) throws -> Any? {
let stripLeading = try Filters.parseBool(from: arguments, index: 0, required: false) ?? false
guard let string = value as? String else { throw Filters.Error.invalidInputType }

let unprefixed: String
if try containsAnyLowercasedChar(string) {
let comps = string.components(separatedBy: "_")
return comps.map { titlecase($0) }.joined(separator: "")
unprefixed = comps.map { titlecase($0) }.joined(separator: "")
} else {
let comps = try snakecase(string).components(separatedBy: "_")
return comps.map { $0.capitalized }.joined(separator: "")
unprefixed = comps.map { $0.capitalized }.joined(separator: "")
}

// only if passed true, strip the prefix underscores
var prefixUnderscores = ""
if !stripLeading {
for scalar in string.unicodeScalars {
guard scalar == "_" else { break }
prefixUnderscores += "_"
}
}

return prefixUnderscores + unprefixed
}

/// Converts camelCase to snake_case. Takes an optional Bool argument for making the string lower case,
Expand Down
13 changes: 9 additions & 4 deletions Tests/StencilSwiftKitTests/StringFiltersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ class StringFiltersTests: XCTestCase {
}
}

func testSnakeToCamelCase() throws {
func testSnakeToCamelCase_WithNoArgsDefaultsToFalse() throws {
let result = try Filters.Strings.snakeToCamelCase("__y_z!", arguments: []) as? String
XCTAssertEqual(result, "__YZ!")
}

func testSnakeToCamelCase_WithFalse() throws {
let expectations = [
"string": "String",
"String": "String",
Expand All @@ -97,12 +102,12 @@ class StringFiltersTests: XCTestCase {
]

for (input, expected) in expectations {
let result = try Filters.Strings.snakeToCamelCase(input) as? String
let result = try Filters.Strings.snakeToCamelCase(input, arguments: ["false"]) as? String
XCTAssertEqual(result, expected)
}
}

func testSnakeToCamelCaseNoPrefix() throws {
func testSnakeToCamelCase_WithTrue() throws {
let expectations = [
"string": "String",
"String": "String",
Expand All @@ -128,7 +133,7 @@ class StringFiltersTests: XCTestCase {
]

for (input, expected) in expectations {
let result = try Filters.Strings.snakeToCamelCaseNoPrefix(input) as? String
let result = try Filters.Strings.snakeToCamelCase(input, arguments: ["true"]) as? String
XCTAssertEqual(result, expected)
}
}
Expand Down

0 comments on commit 4191eb1

Please sign in to comment.