-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #57 from aPureBase/quoting
Refactor cli argument parsing, support single quote assignments
- Loading branch information
Showing
8 changed files
with
124 additions
and
58 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
arkenv/src/main/kotlin/com/apurebase/arkenv/feature/cli/CliArgumentParser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.apurebase.arkenv.feature.cli | ||
|
||
/** | ||
* Parses the command line arguments. | ||
*/ | ||
internal class CliArgumentParser { | ||
private val allowedSurroundings = listOf("'", "\"") | ||
private val list = mutableListOf<String>() | ||
private var isReading = false | ||
|
||
/** | ||
* Parses the provided [arguments] and returns the accumulated results. | ||
* @param arguments List of raw command line string arguments to parse. | ||
*/ | ||
fun parseArguments(arguments: List<String>): List<String> { | ||
arguments.forEach(::parse) | ||
return list | ||
} | ||
|
||
private fun parse(value: String) { | ||
when { | ||
isReading -> list[list.lastIndex] = "${list.last()} $value" | ||
else -> list.add(value) | ||
} | ||
|
||
when { | ||
isReading && value.endsWith(allowedSurroundings) -> { | ||
list[list.lastIndex] = list.last().removeSurrounding(allowedSurroundings) | ||
isReading = false | ||
} | ||
!isReading && value.startsWith(allowedSurroundings) -> isReading = true | ||
} | ||
} | ||
|
||
private fun String.removeSurrounding(list: Iterable<CharSequence>): String = | ||
list.fold(this, String::removeSurrounding) | ||
|
||
private fun String.startsWith(list: Iterable<String>): Boolean = list.any(::startsWith) | ||
|
||
private fun String.endsWith(list: Iterable<CharSequence>): Boolean = list.any(::endsWith) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
arkenv/src/test/kotlin/com/apurebase/arkenv/feature/cli/CliArgumentParserTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.apurebase.arkenv.feature.cli | ||
|
||
import org.junit.jupiter.api.DynamicTest | ||
import org.junit.jupiter.api.TestFactory | ||
import strikt.api.expectThat | ||
import strikt.assertions.get | ||
import strikt.assertions.isEqualTo | ||
|
||
/** | ||
* Verify the behavior of the [CliArgumentParser]. | ||
*/ | ||
internal class CliArgumentParserTest { | ||
|
||
private data class TestCase(val name: String, val input: List<String>, val expected: String) | ||
|
||
private val testCases = listOf( | ||
TestCase("no quotes", listOf("hello", "world"), "hello"), | ||
TestCase("double quotes", listOf("\"hello", "world\""), "hello world"), | ||
TestCase("single quote inside value", listOf("D'vloper"), "D'vloper"), | ||
TestCase("single quoted", listOf("'test", "expected'"), "test expected"), | ||
TestCase("single quoted, containing singlq quote", listOf("'test", "ex'pected'"), "test ex'pected"), | ||
) | ||
|
||
@TestFactory | ||
fun parseArguments(): List<DynamicTest> = testCases.map { (name, input, expected) -> | ||
DynamicTest.dynamicTest(name) { | ||
// Arrange | ||
val parser = CliArgumentParser() | ||
|
||
// Act | ||
val actual = parser.parseArguments(input) | ||
|
||
// Assert | ||
expectThat(actual)[0] isEqualTo expected | ||
} | ||
} | ||
} |
22 changes: 14 additions & 8 deletions
22
arkenv/src/test/kotlin/com/apurebase/arkenv/feature/cli/CliFeatureTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,34 @@ | ||
package com.apurebase.arkenv.feature.cli | ||
|
||
import com.apurebase.arkenv.util.get | ||
import com.apurebase.arkenv.test.Nullable | ||
import com.apurebase.arkenv.test.expectThat | ||
import com.apurebase.arkenv.test.parse | ||
import com.apurebase.arkenv.util.get | ||
import org.junit.jupiter.api.Test | ||
import strikt.api.expectThat | ||
import strikt.assertions.isEqualTo | ||
|
||
/** | ||
* Verify the behavior of the [CliFeature]. | ||
*/ | ||
internal class CliFeatureTest { | ||
|
||
@Test fun `resolve undeclared get calls`() { | ||
val key = "--undeclared" | ||
val expected = "expected" | ||
Nullable().parse(key, expected).expectThat { | ||
get { get(key) }.isEqualTo(expected) | ||
} | ||
val configuration = Nullable().parse(key, expected) | ||
expectThat(configuration).get { get(key) } isEqualTo expected | ||
} | ||
|
||
@Test fun `resolve undeclared assignments`() { | ||
val key = "undeclared" | ||
val expected = "expected" | ||
Nullable().parse("$key=$expected").expectThat { | ||
get { get(key) }.isEqualTo(expected) | ||
} | ||
val configuration = Nullable().parse("$key=$expected") | ||
expectThat(configuration).get { get(key) } isEqualTo expected | ||
} | ||
|
||
@Test fun `single quote in value should parse entire string`() { | ||
val expected = "D'vloper" | ||
val configuration = Nullable().parse("-s", expected) | ||
expectThat(configuration).get { str } isEqualTo expected | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters