Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filters with parameters #41

Merged
merged 4 commits into from
May 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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