-
Notifications
You must be signed in to change notification settings - Fork 7
frontend: split staging tests up into many small file tests #469
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
Changes from all commits
e65437e
74888da
7b0b98a
18874ba
ced1df5
a10c7fe
c2f0100
e353741
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package lang.temper.common | ||
|
|
||
| private val crlfOrLfPattern = Regex("""\r\n?|\n""") | ||
|
|
||
| fun CharSequence.splitLinesPreservingTerminators(): List<String> { | ||
| val matches = crlfOrLfPattern.findAll(this) | ||
| var pos = 0 | ||
| var listBuilder: MutableList<String>? = null | ||
| for (match in matches) { | ||
| val lines = listBuilder ?: (mutableListOf<String>().also { listBuilder = it }) | ||
| val endExclusive = match.range.last + 1 | ||
| lines.add(substring(pos, endExclusive)) | ||
| pos = endExclusive | ||
| } | ||
| return if (listBuilder == null) { | ||
| listOf(this.toString()) | ||
| } else { | ||
| listBuilder.add(substring(pos, length)) | ||
| listBuilder.toList() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package lang.temper.common.json | ||
|
|
||
| import lang.temper.common.structure.Hints | ||
| import kotlin.math.min | ||
|
|
||
| class JsonNestedObjectBuilder { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I combine a bunch of test files from the expect directory into a JSON object so that we can still get one-diff-to-expose-all-problems style failure. To that end, I keep a mapping from relative file paths to JSON property chains (and a bit of other info) and feed them into this. The set of small file definitions are in the README added in this which is probably a good place to start any review. |
||
| private val chainsToLeaves = mutableListOf<Pair<List<String>, JsonValue>>() | ||
|
|
||
| fun property(propertyChain: List<String>, value: JsonValue) { | ||
| chainsToLeaves.add(propertyChain to value) | ||
| } | ||
|
|
||
| fun toJsonObject(): JsonObject { | ||
| // sort the property chains in lexicographic order | ||
| // Perhaps we have these once we're ordered: | ||
| // - ["a", "b"] | ||
| // - ["a", "c", "d"] | ||
| // - ["a", "c", "e"] | ||
| // - ["f", "g"] | ||
| // At depth 0, we can identify a run of "a" and a run of "f", | ||
| // so we know for one JsonObject, what it's properties are. | ||
| // Then at depth 1 for the "a" object, we have a run of one "b" and one "c". | ||
| // So simple linear search lets us build objects. | ||
| chainsToLeaves.sortWith { (a), (b) -> | ||
| lexicographicTupleComparison(a, b) | ||
| } | ||
|
|
||
| fun build(range: IntRange, depth: Int): JsonObject = JsonObject( | ||
| buildList { | ||
| var i = range.first | ||
| val limit = range.last | ||
| while (i <= limit) { | ||
| val (chainI, valueI) = chainsToLeaves[i] | ||
| val propertyName = chainI.getOrNull(depth) | ||
| if (propertyName == null) { | ||
| i += 1 | ||
| continue | ||
| } | ||
| // Find the i..<j range for the property. | ||
| var j = i + 1 | ||
| while (j <= limit) { | ||
| if (chainsToLeaves[j].first.getOrNull(depth) != propertyName) { | ||
| break | ||
| } | ||
| j += 1 | ||
| } | ||
| // The property either has a singleton value or a nested object value. | ||
| val value = if (i + 1 == j && chainI.size == depth + 1) { | ||
| valueI | ||
| } else { | ||
| build(i..<j, depth + 1) | ||
| } | ||
| add(JsonProperty(propertyName, value, Hints.empty)) | ||
| i = j | ||
| } | ||
| }, | ||
| ) | ||
| return build(chainsToLeaves.indices, 0) | ||
| } | ||
| } | ||
|
|
||
| fun buildJsonNestedObject( | ||
| body: (JsonNestedObjectBuilder).() -> Unit, | ||
| ): JsonObject { | ||
| val builder = JsonNestedObjectBuilder() | ||
| builder.body() | ||
| return builder.toJsonObject() | ||
| } | ||
|
|
||
| private fun lexicographicTupleComparison(a: List<String>, b: List<String>): Int { | ||
| val aSize = a.size | ||
| val bSize = b.size | ||
| val minSize = min(aSize, bSize) | ||
| for (i in 0..<minSize) { | ||
| val aStr = a[i] | ||
| val bStr = b[i] | ||
| val delta = aStr.compareTo(bStr) | ||
| if (delta != 0) { return delta } | ||
| } | ||
|
|
||
| return aSize - bSize | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -814,14 +814,14 @@ internal fun destructureTreeMultipleRepresentations( | |
| ast: Tree, | ||
| pseudoCodeDetail: PseudoCodeDetail, | ||
| ) { | ||
| sink.key("code", Hints.s) { | ||
| sink.key("code", Hints.su) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make it more flexible as to which of lispy/pseudocode form is required. |
||
| val code = ast.toPseudoCode( | ||
| singleLine = false, | ||
| detail = pseudoCodeDetail, | ||
| ) | ||
| value(code) | ||
| } | ||
| sink.key("tree", Hints.s) { value(ast) } | ||
| sink.key("tree", Hints.su) { value(ast) } | ||
| } | ||
|
|
||
| fun Iterable<Module>.mergedNamingContext(mergedLoc: ModuleLocation): NamingContext { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kotlin's split lines drops terminators so I just thought I'd write one that's good.