Skip to content

Commit c27259c

Browse files
authored
Merge pull request #395 from FWDekker/v3-test-rewrite
Rewrite tests for v3
2 parents 44bc3b2 + a8b4c4d commit c27259c

File tree

96 files changed

+5202
-3860
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+5202
-3860
lines changed

build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ dependencies {
3333
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
3434
api("org.jetbrains.kotlin:kotlin-reflect")
3535

36-
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:${properties("mockitoKotlinVersion")}")
3736
testImplementation("org.assertj:assertj-core:${properties("assertjVersion")}")
3837
testImplementation("org.assertj:assertj-swing-junit:${properties("assertjSwingVersion")}")
39-
testImplementation("org.junit.platform:junit-platform-runner:${properties("junitRunnerVersion")}")
38+
testRuntimeOnly("org.junit.platform:junit-platform-runner:${properties("junitRunnerVersion")}")
4039
testImplementation("org.junit.jupiter:junit-jupiter-api:${properties("junitVersion")}")
4140
testImplementation("org.junit.jupiter:junit-jupiter-engine:${properties("junitVersion")}")
4241
testImplementation("org.junit.vintage:junit-vintage-engine:${properties("junitVersion")}")

gradle.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ emojiVersion = 5.1.1
2727
jacocoVersion = 0.8.7
2828
junitVersion = 5.7.2
2929
junitRunnerVersion = 1.7.2
30-
mockitoKotlinVersion = 2.2.0
3130
spekVersion = 2.0.15
3231
uuidGeneratorVersion = 3.3.0
3332

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.fwdekker.randomness
2+
3+
4+
/**
5+
* Indicates that the target is to be considered marked as private and should not be used externally, even though it is
6+
* not marked as such.
7+
*
8+
* @property reason Explains why the target is not marked as private.
9+
*/
10+
@Retention(AnnotationRetention.SOURCE)
11+
annotation class ActuallyPrivate(val reason: String)

src/main/kotlin/com/fwdekker/randomness/CapitalizationMode.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ enum class CapitalizationMode(val descriptor: String, val transform: (String) ->
3838
/**
3939
* Makes each letter randomly uppercase or lowercase.
4040
*/
41-
RANDOM("random", { string -> string.toCharArray().map { it.toRandomCase() }.joinToString("") });
41+
RANDOM("random", { string -> string.toCharArray().map { it.toRandomCase() }.joinToString("") }),
42+
43+
/**
44+
* Unused in production code.
45+
*/
46+
DUMMY("dummy", { string -> string });
4247

4348

4449
/**
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.fwdekker.randomness
2+
3+
import com.intellij.codeInsight.hint.HintManager
4+
import com.intellij.openapi.actionSystem.AnAction
5+
import com.intellij.openapi.actionSystem.AnActionEvent
6+
import com.intellij.openapi.actionSystem.CommonDataKeys
7+
import com.intellij.openapi.command.WriteCommandAction
8+
import javax.swing.Icon
9+
10+
11+
/**
12+
* Inserts strings in the editor.
13+
*
14+
* @property repeat True if and only if the same value should be inserted at each caret.
15+
*/
16+
abstract class InsertAction(private val repeat: Boolean = false) : AnAction() {
17+
/**
18+
* The icon to display as representing this action.
19+
*/
20+
abstract val icon: Icon?
21+
22+
/**
23+
* The name of this action.
24+
*/
25+
abstract val name: String
26+
27+
28+
/**
29+
* Sets the title of this action and disables this action if no editor is currently opened.
30+
*
31+
* @param event carries information on the invocation place
32+
*/
33+
override fun update(event: AnActionEvent) {
34+
val presentation = event.presentation
35+
val editor = event.getData(CommonDataKeys.EDITOR)
36+
37+
presentation.icon = icon
38+
presentation.text = name
39+
presentation.isEnabled = editor != null
40+
}
41+
42+
/**
43+
* Inserts the data generated by the scheme at the caret(s) in the editor; one datum for each caret.
44+
*
45+
* @param event carries information on the invocation place
46+
*/
47+
@Suppress("ReturnCount") // Result of null checks at start
48+
override fun actionPerformed(event: AnActionEvent) {
49+
val editor = event.getData(CommonDataKeys.EDITOR) ?: return
50+
val project = event.getData(CommonDataKeys.PROJECT) ?: return
51+
52+
val data =
53+
try {
54+
generateTimely {
55+
if (repeat)
56+
generateStrings(1).single().let { string -> List(editor.caretModel.caretCount) { string } }
57+
else
58+
generateStrings(editor.caretModel.caretCount)
59+
}
60+
} catch (e: DataGenerationException) {
61+
HintManager.getInstance().showErrorHint(
62+
editor,
63+
"""
64+
Randomness was unable to generate random data.
65+
${if (!e.message.isNullOrBlank()) "The following error was encountered: ${e.message}\n" else ""}
66+
Check your Randomness settings and try again.
67+
""".trimIndent()
68+
)
69+
return
70+
}
71+
72+
WriteCommandAction.runWriteCommandAction(project) {
73+
editor.caretModel.allCarets.forEachIndexed { i, caret ->
74+
val start = caret.selectionStart
75+
val end = caret.selectionEnd
76+
val newEnd = start + data[i].length
77+
78+
editor.document.replaceString(start, end, data[i])
79+
caret.setSelection(start, newEnd)
80+
}
81+
}
82+
}
83+
84+
85+
/**
86+
* Generates the given number of strings.
87+
*
88+
* @param count the number of strings to generate
89+
* @return the given number of strings
90+
*/
91+
abstract fun generateStrings(count: Int): List<String>
92+
}

src/main/kotlin/com/fwdekker/randomness/Scheme.kt

Lines changed: 20 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
11
package com.fwdekker.randomness
22

33
import com.fwdekker.randomness.array.ArraySchemeDecorator
4-
import com.intellij.util.xmlb.XmlSerializerUtil
54
import com.intellij.util.xmlb.annotations.Transient
6-
import icons.RandomnessIcons
75
import javax.swing.Icon
86
import kotlin.random.Random
97

108

119
/**
12-
* A scheme is a configurable random number generator.
10+
* A scheme is a [State] that is also a configurable random number generator.
1311
*
1412
* Schemes can additionally be given [SchemeDecorator]s that extend their functionality.
1513
*/
16-
abstract class Scheme {
14+
abstract class Scheme : State() {
1715
/**
1816
* Settings that determine whether the output should be an array of values.
1917
*/
2018
abstract val decorator: ArraySchemeDecorator?
2119

2220
/**
23-
* The name of the scheme as shown to the user.
21+
* The icon for this scheme; depends on whether its array decorator is enabled.
2422
*/
25-
abstract val name: String
26-
27-
/**
28-
* The icons that represent schemes of this type.
29-
*/
30-
@Transient
31-
open val icons: RandomnessIcons? = null
32-
33-
/**
34-
* The icon that represents this scheme instance.
35-
*/
36-
@get:Transient
37-
open val icon: Icon?
38-
get() = if (decorator?.enabled == true) icons?.Array
39-
else icons?.Base
23+
override val icon: Icon?
24+
get() =
25+
if (decorator?.enabled == true) icons?.Array
26+
else icons?.Base
4027

4128
/**
4229
* The random number generator used to generate random values.
@@ -53,11 +40,18 @@ abstract class Scheme {
5340
* @throws DataGenerationException if data could not be generated
5441
*/
5542
@Throws(DataGenerationException::class)
56-
fun generateStrings(count: Int = 1): List<String> =
57-
decorator?.let {
58-
it.generator = ::generateUndecoratedStrings
59-
it.generateStrings(count)
60-
} ?: generateUndecoratedStrings(count)
43+
fun generateStrings(count: Int = 1): List<String> {
44+
doValidate()?.also { throw DataGenerationException(it) }
45+
46+
return decorator.let { decorator ->
47+
if (decorator == null) {
48+
generateUndecoratedStrings(count)
49+
} else {
50+
decorator.generator = ::generateUndecoratedStrings
51+
decorator.generateStrings(count)
52+
}
53+
}
54+
}
6155

6256
/**
6357
* Generates random data according to the settings in this scheme, ignoring settings from decorators.
@@ -70,39 +64,7 @@ abstract class Scheme {
7064
abstract fun generateUndecoratedStrings(count: Int = 1): List<String>
7165

7266

73-
/**
74-
* Validates the scheme, and indicates whether and why it is invalid.
75-
*
76-
* @return `null` if the scheme is valid, or a string explaining why the scheme is invalid
77-
*/
78-
open fun doValidate(): String? = null
79-
80-
/**
81-
* Copies the given scheme into this scheme.
82-
*
83-
* Works by copying all references in a [deepCopy] of [scheme] into `this`.
84-
*
85-
* @param scheme the scheme to copy into this scheme; should be a subclass of this scheme
86-
*/
87-
fun copyFrom(scheme: Scheme) = XmlSerializerUtil.copyBean(scheme.deepCopy(), this)
88-
89-
/**
90-
* Returns a deep copy of this scheme.
91-
*
92-
* @return a deep copy of this scheme
93-
*/
94-
abstract fun deepCopy(): Scheme
95-
96-
97-
/**
98-
* Holds constants.
99-
*/
100-
companion object {
101-
/**
102-
* The default value of the [name] field.
103-
*/
104-
const val DEFAULT_NAME: String = "Unnamed scheme"
105-
}
67+
abstract override fun deepCopy(): Scheme
10668
}
10769

10870
/**

src/main/kotlin/com/fwdekker/randomness/SchemeEditor.kt

Lines changed: 0 additions & 77 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.fwdekker.randomness
2+
3+
import com.intellij.openapi.options.Configurable
4+
import com.intellij.openapi.options.ConfigurationException
5+
import javax.swing.JComponent
6+
7+
8+
/**
9+
* Tells IntelliJ how to use a [StateEditor] in the settings dialog.
10+
*/
11+
@Suppress("LateinitUsage") // `createComponent` is invoked before any of the other methods
12+
abstract class SettingsConfigurable : Configurable {
13+
/**
14+
* The user interface for changing the settings, displayed in IntelliJ's settings window.
15+
*/
16+
lateinit var editor: StateEditor<*> private set
17+
18+
19+
/**
20+
* Returns true if the settings were modified since they were loaded or they are invalid.
21+
*
22+
* @return true if the settings were modified since they were loaded or they are invalid
23+
*/
24+
override fun isModified() = editor.isModified() || editor.doValidate() != null
25+
26+
/**
27+
* Saves the changes in the settings component to the default settings object.
28+
*
29+
* @throws ConfigurationException if the changes cannot be saved
30+
*/
31+
@Throws(ConfigurationException::class)
32+
override fun apply() {
33+
val validationInfo = editor.doValidate()
34+
if (validationInfo != null)
35+
throw ConfigurationException(validationInfo, "Failed to save settings")
36+
37+
editor.applyState()
38+
}
39+
40+
/**
41+
* Discards unsaved changes in the settings component.
42+
*/
43+
override fun reset() = editor.reset()
44+
45+
46+
/**
47+
* Creates a new editor and returns the root pane of the created editor.
48+
*
49+
* @return the root pane of the created editor
50+
*/
51+
override fun createComponent(): JComponent =
52+
createEditor().let {
53+
editor = it
54+
it.rootComponent
55+
}
56+
57+
/**
58+
* Creates a new editor.
59+
*
60+
* @return a new editor
61+
*/
62+
abstract fun createEditor(): StateEditor<*>
63+
}

0 commit comments

Comments
 (0)