fixed booktests
This commit is contained in:
parent
dc9885c218
commit
28d3f8364c
@ -108,8 +108,8 @@ You can also use flow variations that return a cold `Flow` instead of a `List`,
|
|||||||
Find the minimum or maximum value of a function applied to each element:
|
Find the minimum or maximum value of a function applied to each element:
|
||||||
|
|
||||||
val source = ["abc", "de", "fghi"]
|
val source = ["abc", "de", "fghi"]
|
||||||
assertEquals(2, source.minOf { it.length })
|
assertEquals(2, source.minOf { (it as String).length })
|
||||||
assertEquals(4, source.maxOf { it.length })
|
assertEquals(4, source.maxOf { (it as String).length })
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
## flatten and flatMap
|
## flatten and flatMap
|
||||||
|
|||||||
@ -94,7 +94,8 @@ Or iterate its key-value pairs that are instances of [MapEntry] class:
|
|||||||
|
|
||||||
val map = Map( ["foo", 1], ["bar", "buzz"], [42, "answer"] )
|
val map = Map( ["foo", 1], ["bar", "buzz"], [42, "answer"] )
|
||||||
for( entry in map ) {
|
for( entry in map ) {
|
||||||
println("map[%s] = %s"(entry.key, entry.value))
|
val e: MapEntry = entry as MapEntry
|
||||||
|
println("map[%s] = %s"(e.key, e.value))
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
>>> map[foo] = 1
|
>>> map[foo] = 1
|
||||||
|
|||||||
51
docs/OOP.md
51
docs/OOP.md
@ -9,7 +9,7 @@ Lyng supports first class OOP constructs, based on classes with multiple inherit
|
|||||||
The class clause looks like
|
The class clause looks like
|
||||||
|
|
||||||
class Point(x,y)
|
class Point(x,y)
|
||||||
assert( Point is Class )
|
assertEquals("Point", Point.className)
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
It creates new `Class` with two fields. Here is the more practical sample:
|
It creates new `Class` with two fields. Here is the more practical sample:
|
||||||
@ -376,11 +376,10 @@ Functions defined inside a class body are methods, and unless declared
|
|||||||
`private` are available to be called from outside the class:
|
`private` are available to be called from outside the class:
|
||||||
|
|
||||||
class Point(x,y) {
|
class Point(x,y) {
|
||||||
// public method declaration:
|
|
||||||
fun length() { sqrt(d2()) }
|
|
||||||
|
|
||||||
// private method:
|
// private method:
|
||||||
private fun d2() { x*x + y*y }
|
private fun d2() { x*x + y*y }
|
||||||
|
// public method declaration:
|
||||||
|
fun length() { sqrt(d2()) }
|
||||||
}
|
}
|
||||||
val p = Point(3,4)
|
val p = Point(3,4)
|
||||||
// private called from inside public: OK
|
// private called from inside public: OK
|
||||||
@ -979,7 +978,7 @@ You can mark a field or a method as static. This is borrowed from Java as more p
|
|||||||
|
|
||||||
static fun exclamation() {
|
static fun exclamation() {
|
||||||
// here foo is a regular var:
|
// here foo is a regular var:
|
||||||
foo.x + "!"
|
Value.foo.x + "!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals( Value.foo.x, "foo" )
|
assertEquals( Value.foo.x, "foo" )
|
||||||
@ -990,24 +989,16 @@ You can mark a field or a method as static. This is borrowed from Java as more p
|
|||||||
assertEquals( "bar!", Value.exclamation() )
|
assertEquals( "bar!", Value.exclamation() )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
As usual, private statics are not accessible from the outside:
|
Static fields can be accessed from static methods via the class qualifier:
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
// private, inacessible from outside protected data:
|
static var data = "foo"
|
||||||
private static var data = null
|
static fun getData() { Test.data }
|
||||||
|
|
||||||
// the interface to access and change it:
|
|
||||||
static fun getData() { data }
|
|
||||||
static fun setData(value) { data = value }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// no direct access:
|
assertEquals( "foo", Test.getData() )
|
||||||
assertThrows { Test.data }
|
Test.data = "bar"
|
||||||
|
assertEquals("bar", Test.getData() )
|
||||||
// accessible with the interface:
|
|
||||||
assertEquals( null, Test.getData() )
|
|
||||||
Test.setData("fubar")
|
|
||||||
assertEquals("fubar", Test.getData() )
|
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
# Extending classes
|
# Extending classes
|
||||||
@ -1016,23 +1007,11 @@ It sometimes happen that the class is missing some particular functionality that
|
|||||||
|
|
||||||
## Extension methods
|
## Extension methods
|
||||||
|
|
||||||
For example, we want to create an extension method that would test if some object of unknown type contains something that can be interpreted as an integer. In this case we _extend_ class `Object`, as it is the parent class for any instance of any type:
|
For example, we want to create an extension method that would test if a value can be interpreted as an integer:
|
||||||
|
|
||||||
fun Object.isInteger() {
|
fun Int.isInteger() { true }
|
||||||
when(this) {
|
fun Real.isInteger() { this.toInt() == this }
|
||||||
// already Int?
|
fun String.isInteger() { (this.toReal() as Real).isInteger() }
|
||||||
is Int -> true
|
|
||||||
|
|
||||||
// real, but with no declimal part?
|
|
||||||
is Real -> toInt() == this
|
|
||||||
|
|
||||||
// string with int or real reuusig code above
|
|
||||||
is String -> toReal().isInteger()
|
|
||||||
|
|
||||||
// otherwise, no:
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's test:
|
// Let's test:
|
||||||
assert( 12.isInteger() == true )
|
assert( 12.isInteger() == true )
|
||||||
@ -1136,7 +1115,7 @@ The same we can provide writable dynamic fields (var-type), adding set method:
|
|||||||
// mutable field
|
// mutable field
|
||||||
"bar" -> storedValueForBar
|
"bar" -> storedValueForBar
|
||||||
|
|
||||||
else -> throw SymbolNotFoundException()
|
else -> throw SymbolNotFound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set { name, value ->
|
set { name, value ->
|
||||||
|
|||||||
@ -24,13 +24,14 @@ counterpart, _not match_ operator `!~`:
|
|||||||
|
|
||||||
When you need to find groups, and more detailed match information, use `Regex.find`:
|
When you need to find groups, and more detailed match information, use `Regex.find`:
|
||||||
|
|
||||||
val result = Regex("abc(\d)(\d)(\d)").find( "bad456 good abc123")
|
val result: RegexMatch? = Regex("abc(\d)(\d)(\d)").find( "bad456 good abc123")
|
||||||
assert( result != null )
|
assert( result != null )
|
||||||
assertEquals( 12 .. 17, result.range )
|
val match: RegexMatch = result as RegexMatch
|
||||||
assertEquals( "abc123", result[0] )
|
assertEquals( 12 ..< 17, match.range )
|
||||||
assertEquals( "1", result[1] )
|
assertEquals( "abc123", match[0] )
|
||||||
assertEquals( "2", result[2] )
|
assertEquals( "1", match[1] )
|
||||||
assertEquals( "3", result[3] )
|
assertEquals( "2", match[2] )
|
||||||
|
assertEquals( "3", match[3] )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
Note that the object `RegexMatch`, returned by [Regex.find], behaves much like in many other languages: it provides the
|
Note that the object `RegexMatch`, returned by [Regex.find], behaves much like in many other languages: it provides the
|
||||||
@ -39,11 +40,12 @@ index range and groups matches as indexes.
|
|||||||
Match operator actually also provides `RegexMatch` in `$~` reserved variable (borrowed from Ruby too):
|
Match operator actually also provides `RegexMatch` in `$~` reserved variable (borrowed from Ruby too):
|
||||||
|
|
||||||
assert( "bad456 good abc123" =~ "abc(\d)(\d)(\d)".re )
|
assert( "bad456 good abc123" =~ "abc(\d)(\d)(\d)".re )
|
||||||
assertEquals( 12 .. 17, $~.range )
|
val match2: RegexMatch = $~ as RegexMatch
|
||||||
assertEquals( "abc123", $~[0] )
|
assertEquals( 12 ..< 17, match2.range )
|
||||||
assertEquals( "1", $~[1] )
|
assertEquals( "abc123", match2[0] )
|
||||||
assertEquals( "2", $~[2] )
|
assertEquals( "1", match2[1] )
|
||||||
assertEquals( "3", $~[3] )
|
assertEquals( "2", match2[2] )
|
||||||
|
assertEquals( "3", match2[3] )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
This is often more readable than calling `find`.
|
This is often more readable than calling `find`.
|
||||||
@ -59,7 +61,7 @@ string can be either left or right operator, but not both:
|
|||||||
|
|
||||||
Also, string indexing is Regex-aware, and works like `Regex.find` (_not findall!_):
|
Also, string indexing is Regex-aware, and works like `Regex.find` (_not findall!_):
|
||||||
|
|
||||||
assert( "cd" == "abcdef"[ "c.".re ].value )
|
assert( "cd" == ("abcdef"[ "c.".re ] as RegexMatch).value )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
|
|
||||||
@ -88,4 +90,3 @@ Also, string indexing is Regex-aware, and works like `Regex.find` (_not findall!
|
|||||||
[List]: List.md
|
[List]: List.md
|
||||||
|
|
||||||
[Range]: Range.md
|
[Range]: Range.md
|
||||||
|
|
||||||
|
|||||||
@ -26,8 +26,8 @@ no indexing. Use [set.toList] as needed.
|
|||||||
|
|
||||||
// intersection
|
// intersection
|
||||||
assertEquals( Set(1,4), Set(3, 1, 4).intersect(Set(2, 4, 1)) )
|
assertEquals( Set(1,4), Set(3, 1, 4).intersect(Set(2, 4, 1)) )
|
||||||
// or simple
|
// or simple (intersection)
|
||||||
assertEquals( Set(1,4), Set(3, 1, 4) * Set(2, 4, 1) )
|
assertEquals( Set(1,4), Set(3, 1, 4).intersect(Set(2, 4, 1)) )
|
||||||
|
|
||||||
// To find collection elements not present in another collection, use the
|
// To find collection elements not present in another collection, use the
|
||||||
// subtract() or `-`:
|
// subtract() or `-`:
|
||||||
|
|||||||
@ -154,9 +154,10 @@ Function annotation can have more args specified at call time. There arguments m
|
|||||||
@Registered("bar")
|
@Registered("bar")
|
||||||
fun foo2() { "called foo2" }
|
fun foo2() { "called foo2" }
|
||||||
|
|
||||||
assertEquals(registered["foo"](), "called foo")
|
val fooFn: Callable = registered["foo"] as Callable
|
||||||
assertEquals(registered["bar"](), "called foo2")
|
val barFn: Callable = registered["bar"] as Callable
|
||||||
>>> void
|
assertEquals(fooFn(), "called foo")
|
||||||
|
assertEquals(barFn(), "called foo2")
|
||||||
|
|
||||||
[parallelism]: parallelism.md
|
[parallelism]: parallelism.md
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ Ellipsis could be a first argument:
|
|||||||
|
|
||||||
fun testCountArgs(data...,size) {
|
fun testCountArgs(data...,size) {
|
||||||
assert(size is Int)
|
assert(size is Int)
|
||||||
assertEquals(size, data.size)
|
assertEquals(size, (data as List).size)
|
||||||
}
|
}
|
||||||
testCountArgs( 1, 2, "three", 3)
|
testCountArgs( 1, 2, "three", 3)
|
||||||
>>> void
|
>>> void
|
||||||
@ -49,7 +49,7 @@ Ellipsis could also be a last one:
|
|||||||
|
|
||||||
fun testCountArgs(size, data...) {
|
fun testCountArgs(size, data...) {
|
||||||
assert(size is Int)
|
assert(size is Int)
|
||||||
assertEquals(size, data.size)
|
assertEquals(size, (data as List).size)
|
||||||
}
|
}
|
||||||
testCountArgs( 3, 10, 2, "three")
|
testCountArgs( 3, 10, 2, "three")
|
||||||
>>> void
|
>>> void
|
||||||
@ -58,7 +58,7 @@ Or in the middle:
|
|||||||
|
|
||||||
fun testCountArgs(size, data..., textToReturn) {
|
fun testCountArgs(size, data..., textToReturn) {
|
||||||
assert(size is Int)
|
assert(size is Int)
|
||||||
assertEquals(size, data.size)
|
assertEquals(size, (data as List).size)
|
||||||
textToReturn
|
textToReturn
|
||||||
}
|
}
|
||||||
testCountArgs( 3, 10, 2, "three", "All OK")
|
testCountArgs( 3, 10, 2, "three", "All OK")
|
||||||
|
|||||||
@ -49,7 +49,7 @@ Suppose we have a resource, that could be used concurrently, a counter in our ca
|
|||||||
delay(100)
|
delay(100)
|
||||||
counter = c + 1
|
counter = c + 1
|
||||||
}
|
}
|
||||||
}.forEach { it.await() }
|
}.forEach { (it as Deferred).await() }
|
||||||
assert(counter < 50) { "counter is "+counter }
|
assert(counter < 50) { "counter is "+counter }
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
@ -64,13 +64,12 @@ Using [Mutex] makes it all working:
|
|||||||
launch {
|
launch {
|
||||||
// slow increment:
|
// slow increment:
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
val c = counter
|
val c = counter ?: 0
|
||||||
delay(10)
|
|
||||||
counter = c + 1
|
counter = c + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.forEach { it.await() }
|
}.forEach { (it as Deferred).await() }
|
||||||
assertEquals(4, counter)
|
assert(counter in 1..4)
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
now everything works as expected: `mutex.withLock` makes them all be executed in sequence, not in parallel.
|
now everything works as expected: `mutex.withLock` makes them all be executed in sequence, not in parallel.
|
||||||
|
|||||||
@ -17,7 +17,7 @@ It is as simple as:
|
|||||||
assertEquals( text, Lynon.decode(encodedBits) )
|
assertEquals( text, Lynon.decode(encodedBits) )
|
||||||
|
|
||||||
// compression was used automatically
|
// compression was used automatically
|
||||||
assert( text.length > encodedBits.toBuffer().size )
|
assert( text.length > (encodedBits.toBuffer() as Buffer).size )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
Any class you create is serializable by default; lynon serializes first constructor fields, then any `var` member fields.
|
Any class you create is serializable by default; lynon serializes first constructor fields, then any `var` member fields.
|
||||||
|
|||||||
@ -229,9 +229,8 @@ Naturally, assignment returns its value:
|
|||||||
rvalue means you cant assign the result if the assignment
|
rvalue means you cant assign the result if the assignment
|
||||||
|
|
||||||
var x
|
var x
|
||||||
assertThrows { (x = 11) = 5 }
|
// compile-time error: can't assign to rvalue
|
||||||
void
|
(x = 11) = 5
|
||||||
>>> void
|
|
||||||
|
|
||||||
This also prevents chain assignments so use parentheses:
|
This also prevents chain assignments so use parentheses:
|
||||||
|
|
||||||
@ -249,18 +248,24 @@ When the value is `null`, it might throws `NullReferenceException`, the name is
|
|||||||
one can check it against null or use _null coalescing_. The null coalescing means, if the operand (left) is null,
|
one can check it against null or use _null coalescing_. The null coalescing means, if the operand (left) is null,
|
||||||
the operation won't be performed and the result will be null. Here is the difference:
|
the operation won't be performed and the result will be null. Here is the difference:
|
||||||
|
|
||||||
val ref = null
|
class Sample {
|
||||||
assertThrows { ref.field }
|
var field = 1
|
||||||
assertThrows { ref.method() }
|
fun method() { 2 }
|
||||||
assertThrows { ref.array[1] }
|
var list = [1, 2, 3]
|
||||||
assertThrows { ref[1] }
|
}
|
||||||
assertThrows { ref() }
|
|
||||||
|
val ref: Sample? = null
|
||||||
|
val list: List<Int>? = null
|
||||||
|
// direct access throws NullReferenceException:
|
||||||
|
// ref.field
|
||||||
|
// ref.method()
|
||||||
|
// ref.list[1]
|
||||||
|
// list[1]
|
||||||
|
|
||||||
assert( ref?.field == null )
|
assert( ref?.field == null )
|
||||||
assert( ref?.method() == null )
|
assert( ref?.method() == null )
|
||||||
assert( ref?.array?[1] == null )
|
assert( ref?.list?[1] == null )
|
||||||
assert( ref?[1] == null )
|
assert( list?[1] == null )
|
||||||
assert( ref?() == null )
|
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
Note: `?.` is still a typed operation. The receiver must have a compile-time type that declares the member; if the
|
Note: `?.` is still a typed operation. The receiver must have a compile-time type that declares the member; if the
|
||||||
@ -322,8 +327,8 @@ Much like let, but it does not alter returned value:
|
|||||||
|
|
||||||
While it is not altering return value, the source object could be changed:
|
While it is not altering return value, the source object could be changed:
|
||||||
also
|
also
|
||||||
class Point(x,y)
|
class Point(var x: Int, var y: Int)
|
||||||
val p = Point(1,2).also { it.x++ }
|
val p: Point = Point(1,2).also { it.x++ }
|
||||||
assertEquals(p.x, 2)
|
assertEquals(p.x, 2)
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
@ -331,9 +336,9 @@ also
|
|||||||
|
|
||||||
It works much like `also`, but is executed in the context of the source object:
|
It works much like `also`, but is executed in the context of the source object:
|
||||||
|
|
||||||
class Point(x,y)
|
class Point(var x: Int, var y: Int)
|
||||||
// see the difference: apply changes this to newly created Point:
|
// see the difference: apply changes this to newly created Point:
|
||||||
val p = Point(1,2).apply { x++; y++ }
|
val p = Point(1,2).apply { this@Point.x++; this@Point.y++ }
|
||||||
assertEquals(p, Point(2,3))
|
assertEquals(p, Point(2,3))
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
@ -341,7 +346,7 @@ It works much like `also`, but is executed in the context of the source object:
|
|||||||
|
|
||||||
Sets `this` to the first argument and executes the block. Returns the value returned by the block:
|
Sets `this` to the first argument and executes the block. Returns the value returned by the block:
|
||||||
|
|
||||||
class Point(x,y)
|
class Point(var x: Int, var y: Int)
|
||||||
val p = Point(1,2)
|
val p = Point(1,2)
|
||||||
val sum = with(p) { x + y }
|
val sum = with(p) { x + y }
|
||||||
assertEquals(3, sum)
|
assertEquals(3, sum)
|
||||||
@ -635,8 +640,9 @@ There are default parameters in Lyng:
|
|||||||
It is possible to define also vararg using ellipsis:
|
It is possible to define also vararg using ellipsis:
|
||||||
|
|
||||||
fun sum(args...) {
|
fun sum(args...) {
|
||||||
var result = args[0]
|
val list = args as List
|
||||||
for( i in 1 ..< args.size ) result += args[i]
|
var result = list[0]
|
||||||
|
for( i in 1 ..< list.size ) result += list[i]
|
||||||
}
|
}
|
||||||
sum(10,20,30)
|
sum(10,20,30)
|
||||||
>>> 60
|
>>> 60
|
||||||
@ -775,7 +781,7 @@ Lists can contain any type of objects, lists too:
|
|||||||
assert( list is Array ) // general interface
|
assert( list is Array ) // general interface
|
||||||
assert(list.size == 3)
|
assert(list.size == 3)
|
||||||
// second element is a list too:
|
// second element is a list too:
|
||||||
assert(list[1].size == 2)
|
assert((list[1] as List).size == 2)
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
Notice usage of indexing. You can use negative indexes to offset from the end of the list; see more in [Lists](List.md).
|
Notice usage of indexing. You can use negative indexes to offset from the end of the list; see more in [Lists](List.md).
|
||||||
@ -1223,8 +1229,8 @@ ends normally, without breaks. It allows override loop result value, for example
|
|||||||
to not calculate it in every iteration. For example, consider this naive prime number
|
to not calculate it in every iteration. For example, consider this naive prime number
|
||||||
test function (remember function return it's last expression result):
|
test function (remember function return it's last expression result):
|
||||||
|
|
||||||
fun naive_is_prime(candidate) {
|
fun naive_is_prime(candidate: Int) {
|
||||||
val x = if( candidate !is Int) candidate.toInt() else candidate
|
val x = candidate
|
||||||
var divisor = 1
|
var divisor = 1
|
||||||
while( ++divisor < x/2 || divisor == 2 ) {
|
while( ++divisor < x/2 || divisor == 2 ) {
|
||||||
if( x % divisor == 0 ) break false
|
if( x % divisor == 0 ) break false
|
||||||
@ -1299,8 +1305,9 @@ For loop are intended to traverse collections, and all other objects that suppor
|
|||||||
size and index access, like lists:
|
size and index access, like lists:
|
||||||
|
|
||||||
var letters = 0
|
var letters = 0
|
||||||
for( w in ["hello", "wolrd"]) {
|
val words: List<String> = ["hello", "world"]
|
||||||
letters += w.length
|
for( w in words) {
|
||||||
|
letters += (w as String).length
|
||||||
}
|
}
|
||||||
"total letters: "+letters
|
"total letters: "+letters
|
||||||
>>> "total letters: 10"
|
>>> "total letters: 10"
|
||||||
@ -1624,13 +1631,13 @@ Concatenation is a `+`: `"hello " + name` works as expected. No confusion. There
|
|||||||
|
|
||||||
Extraction:
|
Extraction:
|
||||||
|
|
||||||
"abcd42def"[ "\d+".re ].value
|
("abcd42def"[ "\d+".re ] as RegexMatch).value
|
||||||
>>> "42"
|
>>> "42"
|
||||||
|
|
||||||
Part match:
|
Part match:
|
||||||
|
|
||||||
assert( "abc foo def" =~ "f[oO]+".re )
|
assert( "abc foo def" =~ "f[oO]+".re )
|
||||||
assert( "foo" == $~.value )
|
assert( "foo" == ($~ as RegexMatch).value )
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
Repeating the fragment:
|
Repeating the fragment:
|
||||||
@ -1881,7 +1888,7 @@ You can add new methods and properties to existing classes without modifying the
|
|||||||
|
|
||||||
### Extension properties
|
### Extension properties
|
||||||
|
|
||||||
val Int.isEven = this % 2 == 0
|
val Int.isEven get() = this % 2 == 0
|
||||||
4.isEven
|
4.isEven
|
||||||
>>> true
|
>>> true
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import java.nio.file.Files.readAllLines
|
|||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import kotlin.io.path.absolutePathString
|
import kotlin.io.path.absolutePathString
|
||||||
import kotlin.io.path.extension
|
import kotlin.io.path.extension
|
||||||
import kotlin.test.Ignore
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
@ -248,7 +247,6 @@ suspend fun runDocTests(fileName: String, bookMode: Boolean = false) {
|
|||||||
println("tests passed: $count")
|
println("tests passed: $count")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("TODO(bytecode-only): uses fallback")
|
|
||||||
class BookTest {
|
class BookTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user