-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
7 changed files
with
355 additions
and
3 deletions.
There are no files selected for viewing
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
105 changes: 105 additions & 0 deletions
105
src/main/kotlin/net/love2hina/kotlin/sharon/SharonApplication.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,105 @@ | ||
package net.love2hina.kotlin.sharon | ||
|
||
import java.io.File | ||
import java.nio.file.Files | ||
import java.nio.file.Path | ||
import java.util.* | ||
import java.util.stream.Stream | ||
import kotlin.streams.asStream | ||
|
||
internal class SharonApplication(val args: Array<String>) { | ||
|
||
lateinit var pathOutputDir: Path | ||
private set | ||
|
||
val listFilePath = LinkedList<String>() | ||
|
||
lateinit var files: List<File> | ||
private set | ||
|
||
fun initialize() { | ||
parseArgs() | ||
checkArgs() | ||
listUpFiles() | ||
} | ||
|
||
private fun parseArgs() { | ||
val reg = Regex("^--(?<flag>\\w+)?$") | ||
var flagCurrent: String? = null | ||
var flagAllFiles = false | ||
|
||
for (i in args) { | ||
var matchFlag: MatchResult? = null | ||
|
||
if (!flagAllFiles) { | ||
matchFlag = reg.find(i) | ||
|
||
if ((matchFlag != null) && (flagCurrent != null)) { | ||
// 異常なフラグ連続指定 | ||
throw IllegalArgumentException("フラグの値が指定されていません。 --$flagCurrent") | ||
} | ||
else if (matchFlag != null) { | ||
// フラグ | ||
val groups = (matchFlag.groups as MatchNamedGroupCollection) | ||
when (val flag = groups["flag"]?.value) { | ||
null -> { | ||
flagAllFiles = true | ||
flagCurrent = null | ||
} | ||
else -> { | ||
flagCurrent = flag | ||
} | ||
} | ||
} | ||
else if (flagCurrent != null) { | ||
// フラグの値 | ||
when (flagCurrent) { | ||
"outdir" -> { pathOutputDir = Path.of(i) } | ||
else -> { | ||
throw IllegalArgumentException("不明なフラグ値です。 --$flagCurrent") | ||
} | ||
} | ||
|
||
flagCurrent = null | ||
} | ||
else { | ||
// ファイル | ||
listFilePath.add(i) | ||
} | ||
} | ||
else { | ||
// 常にファイルとして扱う | ||
listFilePath.add(i) | ||
} | ||
} | ||
} | ||
|
||
private fun checkArgs() { | ||
if (!::pathOutputDir.isInitialized) { | ||
throw IllegalArgumentException("出力ディレクトリの指定がありません。 --outdir") | ||
} | ||
} | ||
|
||
private fun listUpFiles() { | ||
files = listFilePath.asSequence().asStream().flatMap(this::mapToFile).toList() | ||
} | ||
|
||
private fun mapToFile(path: String): Stream<File> { | ||
val file = File(path) | ||
|
||
return if (file.isFile) { | ||
// 単一のファイル | ||
Stream.of(file) | ||
} | ||
else if (file.isDirectory) { | ||
// ディレクトリ | ||
Files.walk(file.toPath()) | ||
.filter { it.toString().endsWith(".java", true) } | ||
.map { it.toFile() } | ||
} | ||
else { | ||
throw IllegalArgumentException("指定がファイルでもディレクトリでもありません。 $path") | ||
} | ||
} | ||
|
||
} |
192 changes: 192 additions & 0 deletions
192
src/test/kotlin/net/love2hina/kotlin/sharon/SharonApplicationTest.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,192 @@ | ||
package net.love2hina.kotlin.sharon | ||
|
||
import net.love2hina.kotlin.sharon.TestUtils.pathProjectRoot | ||
import org.junit.jupiter.api.Assertions.* | ||
import org.junit.jupiter.api.* | ||
import org.junit.jupiter.api.extension.ExtendWith | ||
import org.junit.platform.commons.util.ReflectionUtils | ||
import org.mockito.junit.jupiter.MockitoExtension | ||
|
||
@ExtendWith(MockitoExtension::class) | ||
class SharonApplicationTest { | ||
|
||
@Test | ||
fun testInitialize() { | ||
val args = arrayOf( | ||
"--outdir", | ||
pathProjectRoot.resolve("out").toString(), | ||
pathProjectRoot.resolve("src/test/java").toString()) | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
// コール | ||
application.initialize() | ||
} | ||
|
||
@Test | ||
fun testParseArgs001() { | ||
val args = arrayOf( | ||
"--outdir", | ||
pathProjectRoot.resolve("out").toString(), | ||
pathProjectRoot.resolve("src/test/java1").toString(), | ||
"--", | ||
pathProjectRoot.resolve("src/test/java2").toString()) | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
// コール | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "parseArgs") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
|
||
// チェック | ||
assertEquals(pathProjectRoot.resolve("out"), application.pathOutputDir) | ||
assertEquals(2, application.listFilePath.size) | ||
val pathSrcFile = arrayOf( | ||
pathProjectRoot.resolve("src/test/java1").toString(), | ||
pathProjectRoot.resolve("src/test/java2").toString()) | ||
assertEquals(pathSrcFile[0], application.listFilePath[0]) | ||
assertEquals(pathSrcFile[1], application.listFilePath[1]) | ||
} | ||
|
||
@Test | ||
fun testParseArgs002() { | ||
val args = arrayOf( | ||
"--outdir", | ||
"--") | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
try { | ||
// コール | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "parseArgs") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
|
||
fail("例外が発生しない") | ||
} | ||
catch (e: IllegalArgumentException) { | ||
// 例外チェック | ||
assertEquals("フラグの値が指定されていません。 --outdir", e.message) | ||
} | ||
catch (e: Throwable) { | ||
fail(e) | ||
} | ||
} | ||
|
||
@Test | ||
fun testParseArgs003() { | ||
val args = arrayOf( | ||
"--dummy", | ||
"TEST") | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
try { | ||
// コール | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "parseArgs") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
|
||
fail("例外が発生しない") | ||
} | ||
catch (e: IllegalArgumentException) { | ||
// 例外チェック | ||
assertEquals("不明なフラグ値です。 --dummy", e.message) | ||
} | ||
catch (e: Throwable) { | ||
fail(e) | ||
} | ||
} | ||
|
||
@Test | ||
fun testCheckArgs001() { | ||
val args = Array(0) { "" } | ||
val path = pathProjectRoot.resolve("out") | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
// プロパティ設定 | ||
setProperty(application, "pathOutputDir", path) | ||
|
||
run { | ||
// コール | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "checkArgs") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
} | ||
} | ||
|
||
@Test | ||
fun testCheckArgs002() { | ||
val args = arrayOf( | ||
pathProjectRoot.resolve("out").toString()) | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
try { | ||
// コール | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "checkArgs") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
|
||
fail("例外が発生しない") | ||
} | ||
catch (e: IllegalArgumentException) { | ||
// 例外チェック | ||
assertEquals("出力ディレクトリの指定がありません。 --outdir", e.message) | ||
} | ||
catch (e: Throwable) { | ||
fail(e) | ||
} | ||
} | ||
|
||
@Test | ||
fun testListUpFiles001() { | ||
val args = Array(0) { "" } | ||
val pathSrcFile = pathProjectRoot.resolve("src/test/java/net/love2hina/kotlin/sharon/ParseTestTarget.java").toString() | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
// プロパティ設定 | ||
application.listFilePath.add(pathSrcFile) | ||
application.listFilePath.add(pathProjectRoot.resolve("src/test/java").toString()) | ||
|
||
run { | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "listUpFiles") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
} | ||
|
||
assertEquals(2, application.files.size) | ||
assertEquals(pathSrcFile, application.files[0].toString()) | ||
assertEquals(pathSrcFile, application.files[1].toString()) | ||
} | ||
|
||
@Test | ||
fun testListUpFiles002() { | ||
val args = Array(0) { "" } | ||
|
||
// インスタンス作成 | ||
val application = SharonApplication(args) | ||
|
||
// プロパティ設定 | ||
application.listFilePath.add("TEST") | ||
|
||
try { | ||
val method = ReflectionUtils.findMethod(SharonApplication::class.java, "listUpFiles") | ||
ReflectionUtils.invokeMethod(method.get(), application) | ||
|
||
fail("例外が発生しない") | ||
} | ||
catch (e: IllegalArgumentException) { | ||
// 例外チェック | ||
assertEquals("指定がファイルでもディレクトリでもありません。 TEST", e.message) | ||
} | ||
catch (e: Throwable) { | ||
fail(e) | ||
} | ||
} | ||
|
||
} |
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,39 @@ | ||
package net.love2hina.kotlin.sharon | ||
|
||
import com.github.javaparser.utils.CodeGenerationUtils | ||
import kotlin.reflect.KClass | ||
import kotlin.reflect.KMutableProperty | ||
import kotlin.reflect.full.declaredMemberProperties | ||
import kotlin.reflect.jvm.isAccessible | ||
|
||
internal object TestUtils { | ||
|
||
val pathProjectRoot = CodeGenerationUtils.mavenModuleRoot(TestUtils::class.java).resolve("../..").normalize() | ||
|
||
} | ||
|
||
internal fun setProperty(target: Any, cls: KClass<*>, name: String, value: Any) { | ||
val property = cls.declaredMemberProperties | ||
.filterIsInstance<KMutableProperty<*>>() | ||
.first { it.name == name } | ||
|
||
property.setter.isAccessible = true | ||
property.setter.call(target, value) | ||
} | ||
|
||
internal inline fun <reified T: Any> setProperty(target: T, name: String, value: Any) { | ||
setProperty(target, T::class, name, value) | ||
} | ||
|
||
internal fun getProperty(target: Any, cls: KClass<*>, name: String): Any? { | ||
val property = cls.declaredMemberProperties | ||
.filterIsInstance<KMutableProperty<*>>() | ||
.first { it.name == name } | ||
|
||
property.getter.isAccessible = true | ||
return property.getter.call(target) | ||
} | ||
|
||
internal inline fun <reified T: Any> getProperty(target: T, name: String): Any? { | ||
return getProperty(target, T::class, name) | ||
} |