@@ -40,7 +40,9 @@ version: [README of v2.0.0-RC-1](https://github.com/tegonal/minimalist/tree/v2.0
4040 - [Your first parameterized Test](#your-first-parameterized-test)
4141 - [Ordered and arbitrary arguments generators](#ordered-and-arbitrary-arguments-generators)
4242 - [Combinators](#combinators)
43- - [combine](#combine)
43+ - [generic combine](#generic-combine)
44+ - [ordered.cartesian](#ordered-cartesian)
45+ - [arb.zip](#arb-zip)
4446 - [combineDependent](#combinedependent)
4547 - [transform](#transform)
4648 - [map](#map)
@@ -148,11 +150,11 @@ Raw values are turned into a `List` and then passed to `ordered.fromList`. The n
148150
149151Minimalist provides two entry points to create an `ArgsGenenerator `: `ordered` and `arb`.
150152
151- `ordered` can be used to define an ordered (not to be confused with sorted) list of finite values where the
152- corresponding
153- ` OrderedArgsGenerator ` generates a sequence which repeats them indefinitely.
154- For instance, if you use `ordered.of( ' a' , ' b ' )` as provider, then it results in two runs where in the first run you
155- will get ` ' a ' ` and in the second ` ' b ' ` or you will get `' b' ` in the first run and `' a' ` in the second.
153+ `ordered` can be used to define an ordered (not to be confused with sorted) list of finite (` OrderedArgsGenerator .size`)
154+ values where the corresponding ` OrderedArgsGenerator ` generates a sequence which repeats them indefinitely.
155+ For instance, if you use `ordered.of( ' a ' , ' b ' )` as provider, then ` OrderedArgsGenerator .size = 2 ` and correspondingly
156+ it results in two runs. You either will get ` ' a' ` in the first run and in the second ` ' b ' ` or
157+ you will get `' b' ` in the first run and `' a' ` in the second.
156158That is because the resulting sequence repeats indefinitely `' a' , ' b' , ' a' , ' b' , .. . `
157159and it depends on a randomly chosen seed what offset is taken.
158160
@@ -184,8 +186,14 @@ ordered.longFromTo(1, 5)
184186
185187The "counterpart" of ` ordered ` is ` arb ` that allows to create ` ArbArgsGenerator ` s which per definition generate
186188an infinite sequence of values where it is basically not known if they follow some order or not.
187- The default implementations almost all are based on ` Random ` .
188- Following a few examples as well (import and enum definition omitted, as it is the same as above):
189+ The default implementations are almost all based on ` Random ` .
190+ The number of runs of such a provider is in theory infinite as well (` ArbArgsGenerator.size ` doesn't exist) but gets
191+ limited by the [ profile] ( #profiles ) the test falls into, the environment where the test runs and what configuration
192+ was set up for this combination. Also ` OrderedArgsGenerator ` are limited by profile/env but introduce an own limit in
193+ addition.
194+
195+ Following a few examples for ` ArbArgsGenerator ` as well (import and enum definition omitted, as it is the same as
196+ above):
189197
190198<code-arb-1 >
191199
@@ -250,17 +258,15 @@ contain predefined `ArgsSource` providers and one ArgsSourceProvider which exten
250258from Minimalist's PredefinedArgsSourceProviders as well.
251259
252260Back to the example, in contrast to the [ first parameterized test example] ( #your-first-parameterized-test ) where we used
253- raw values (which are
254- turned into a ` List ` and then passed to ` ordered.fromList ` ), we now want to be sure the test
261+ raw values (which are turned into a ` List ` and then passed to ` ordered.fromList ` ), we now want to be sure the test
255262works for all positive integers and not only ` 1..20 ` . Since there are many positive integers, we use ` arb ` and no
256263longer ` ordered ` .
257264
258265Note, that even if we defined a provider with ` arb.intFromTo(1, 20) ` the runtime behaviour differs from ` ordered ` .
259266Where ` OrderedArgsGenerator ` s generate a window of all possible values (i.e. still ordered),
260267an ` ArbArgsGenerator ` generates arbitrary/random values (possibly the same value multiple times).
261268To illustrate it better, following an example where ` maxArgs=5 ` (more on ` maxArgs ` in
262- the [ Configuration] ( #configuration )
263- section):
269+ the [ Configuration] ( #configuration ) section):
264270
265271``` kotlin
266272ordered.of(1 , 2 , 3 ) // results in 3 runs: 1, 2, 3 or 2, 3, 1 or 3, 1, 2
@@ -274,12 +280,12 @@ suited.
274280## Combinators
275281
276282Minimalist provides different combinators to produce new ` ArgsGenerator ` .
277- The most common combinator is to combine multiple ` ArgsGenerator ` s, a reason why it got some extra care.
278283
279- ### Combine
284+ ### Generic Combine
280285
281- Although Minimalist provides a ` combine ` function (more on that later on), the cleanest way to define that two
282- ` ArgsGenerator ` s shall be combined, is to use ` Tuple ` (from ch.tutteli.kbox) which exists up to ` Tuple9 ` :
286+ The most frequently used combinator is probably a way to combine multiple ` ArgsGenerator ` s in some way. A reason why
287+ we added a bit of magic to Minimalist. The idiomatic way to define that we want to combine multiple generators is
288+ to use ` Tuple ` (from ch.tutteli.kbox) which exists up to ` Tuple9 ` :
283289
284290<code-combine-tuple >
285291
@@ -309,28 +315,27 @@ class CombineTupleTest : PredefinedArgsProviders {
309315
310316</code-combine-tuple >
311317
312- As you can see in the example, you can also combine ` ordered ` and ` arb ` (resulting in a ` SemiOrderedArgsGenerator ` ).
313- You only need to make sure that your first ` ArgsGenerator ` in the tuple is a ` SemiOrderedArgsGenerator `
314- (` OrderedArgsGenerator ` is a subtype of ` SemiOrderedArgsGenerator ` ). If your first ` ArgsGenerator ` in the tuple is
315- an ` ArbArgsGenerator ` then all generators which follow need to be an ` ArbArgsGenerator ` as well (otherwise it will
316- fail at runtime).
317-
318- Maybe you are asking yourself how many runs result out of the above definition. ` SemiOrderedArgsGenerator ` s have a
319- property ` size ` and as long as no ` maxArgs ` definition restricts it, it will result in that many runs.
318+ Combining two ` OrderedArgsGenerator ` s A and B (or ` SemiOrderedArgsGenerator ` s) results in an ` OrderedArgsGenerator `
319+ representing their cartesian product and the size correspondingly ` A.size * B.size ` . I.e. such combinations can
320+ grow quickly, but Minimalist has you covered in therms that this is just a definition (nothing generated yet) and
321+ you still execute only a window of those values in a fast and efficient way.
322+ On the other hand, combining two ` ArbArgsGenerator ` means zipping them and results in another ` ArbArgsGenerator ` .
323+
324+ Combining an ` OrderedArgsGenerators ` and an ` ArbArgsGenerator ` works as well (as shown in the example) and uses
325+ again zip behaviour, where the result is no longer an ` OrderedArgsGenerators ` but a ` SemiOrderedArgsGenerators ` (which
326+ still has a ` size ` property). You only need to make sure that your first ` ArgsGenerator ` in the tuple is a
327+ ` SemiOrderedArgsGenerator ` (` OrderedArgsGenerator ` is a subtype of ` SemiOrderedArgsGenerator ` ).
328+ If your first ` ArgsGenerator ` in the tuple is an ` ArbArgsGenerator ` then all generators which follow need to be an
329+ ` ArbArgsGenerator ` as well (otherwise it will fail at runtime).
330+
331+ Maybe you are asking yourself how many runs result out of the above definition. As long as no ` maxArgs ` definition
332+ restricts it, it will result in ` SemiOrderedArgsGenerator.size ` runs.
320333So for ` ordered.intFromTo(15, 30) ` , we will get 30 - 15 + 1 = 16 runs at max (+1 since bounds are inclusive for
321334` intFromTo ` ). Which means we combine 16 arbitrary names with the defined ages.
322335
323- If you combine two ` OrderedArgsGenerator ` s A and B (or ` SemiOrderedArgsGenerator ` s) the resulting ` OrderedArgsGenerator `
324- will be their cartesian product and the size correspondingly ` A.size * B.size ` . I.e. such combinations can grow quickly,
325- but Minimalist has you covered in therms that this is just a definition (nothing generated yet) and you still execute
326- only a window of those values in a fast and efficient way.
327-
328- If you combine two ` ArbArgsGenerator ` s then you will get back an ` ArbArgsGenerator ` which semantically
329- [ ` zip ` s] ( https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/zip.html ) the generates values.
330-
331336What if you want to combine more than 9 ` ArgsGenerators ` ? In such a case you have to combine them via
332337` TupleX.combineAll() ` to get an ` ArgsGenerators<TupleX<...>> ` which then again can be used in a tuple.
333- Or use ` ArgsGenerator.combine(otherArgsGenerator) ` to create an ` ArgsGenerators<Tuple2<...>> ` .
338+ Or use ` cartesian ` , ` zip ` to create an ` ArgsGenerators<Tuple2<...>> ` .
334339Following an example (using less than 9 ` ArgsGenerators ` for brevity -- imports omitted, same as in
335340` TupleCombine1Test ` above)
336341
@@ -349,7 +354,7 @@ class CombineManuallyTest : PredefinedArgsProviders {
349354 @JvmStatic
350355 fun numbersAndChar () = run { // use run to let the compiler infer the return type
351356 val numbers = Tuple (
352- arb.int().combine (arb.long()), // combines them into an ArbArgsGenerators<Tuple2<Int, Long>>
357+ arb.int().zip (arb.long()), // combines them into an ArbArgsGenerators<Tuple2<Int, Long>>
353358 arb.double(),
354359 arb.bigIntFromUntil(BigInt .ZERO , BigInt .TEN )
355360 ).combineAll() // combines all into an ArbArgsGenerators<Tuple3<...>>
@@ -365,19 +370,81 @@ class CombineManuallyTest : PredefinedArgsProviders {
365370
366371</code-combine-manually >
367372
368- Note two things. First, tuples are flattened in the process of transforming the definition into ` Arguments ` . Second,
369- ` Tuple2 ` /` Tuple3 ` are just type aliases for ` Pair ` /` Triple ` . Which means, if you want that an argument is like a
373+ Note two things. First, tuples are flattened in the process of transforming the definition into JUnit's ` Arguments ` .
374+ Second, ` Tuple2 ` /` Tuple3 ` are just type aliases for ` Pair ` /` Triple ` . Which means, if you want that an argument is like a
370375` Pair ` /` Triple ` without being flattened, then define e.g. a ` data class ` .
371376
372- The advantage of using tuples instead of manual ` combine ` are:
377+ The advantage of using tuples instead of manual ` cartesian ` / ` zip ` are:
373378
374379- a) readability (less consecutive ` combine ` method calls -- less cluttering) and
375380- b) you only define that you would like to combine them without actually doing it. Which allows that you can for
376381 instance ` append ` another ` ArgsGenerator ` to the tuple, replace one at a specific position, ` glue ` tuples together and
377382 more (see the documentation of [ kbox] ( https://github.com/robstoll/kbox ) regarding tuples).
378383
379- ` combine ` also provides an overload which takes a ` transform ` function so that you can turn it into something else than
380- ` Tuple2 ` .
384+ ` cartesian ` and ` zip ` provide an overload which takes a ` transform ` function so that you can turn the generates values
385+ pairwise into something else than ` Tuple2 ` .
386+
387+ ### ordered cartesian
388+
389+ As mentioned in [ generic combine] ( #generic-combine ) , combining multiple ` OrderArgsGenerator ` s by using a ` Tuple ` uses
390+ ` cartesian ` behind the scenes and results in a new ` OrderArgsGenerator ` which represents the cartesian product of them,
391+ i.e. all possible combinations.
392+
393+ <code-cartesian-1 >
394+
395+ ``` kotlin
396+ ordered.of(1 , 2 ).cartesian(ordered.of(' A' , ' B' ))
397+ ```
398+
399+ </code-cartesian-1 >
400+
401+ For the above example, the possible combinations are 1/A, 2/A, 1/B, 2/B
402+ You can pass a ` transform ` function as last argument and map the values pairwise to another type:
403+
404+ <code-cartesian-2 >
405+
406+ ``` kotlin
407+ ordered.of(1 , 2 ).cartesian(ordered.of(4 , 5 )) { i1, i2 ->
408+ i1 + i2
409+ }
410+ ```
411+
412+ </code-cartesian-2 >
413+
414+ The above example results in an ` OrderedArgsGenerator<Int> ` with the values 5 (1+4), 6 (2+4), 6 (1+5), 7 (2+5)
415+ (the order of the values is implementation specific). As you can see, an ` OrderedArgsGenerator ` can also generate the
416+ same value multiple times.
417+
418+ ### arb zip
419+
420+ As mentioned in [ generic combine] ( #generic-combine ) , combining multiple ` ArbArgsGenerator ` s by using a ` Tuple ` uses
421+ ` zip ` behind the scenes and results in a new ` ArbArgsGenerator ` :
422+
423+ <code-zip-1 >
424+
425+ ``` kotlin
426+ arb.intFromUntil(1 , 100 ).zip(arb.charFromTo(' A' , ' Z' ))
427+ ```
428+
429+ </code-zip-1 >
430+
431+ For the above example, the possible combinations are 1/A, 2/A,... 99/A, 1/B, 2/B... 99/Z
432+ As mentioned in [ ordered and arbitrary arguments generators] ( #ordered-and-arbitrary-arguments-generators ) , an
433+ ` ArbArgsGenerator ` order is undefined and it could occur that you see a combination more than once.
434+ You can pass a ` transform ` function as last argument and map the values pairwise another type:
435+
436+ <code-zip-2 >
437+
438+ ``` kotlin
439+ arb.intFromUntil(1 , 100 ).zip(arb.intFromUntil(1000 , 2000 )) { i1, i2 ->
440+ i1 + i2
441+ }
442+ ```
443+
444+ </code-zip-2 >
445+
446+ The above example results in an ` ArbArgsGenerator<Int> ` generating values from 1001 until 2098 where 1002 until 1099 are
447+ more likely to appear since they result twice (1+1001 and 2+1000 = 1002 etc.).
381448
382449### combineDependent
383450
@@ -520,7 +587,7 @@ else.
520587``` kotlin
521588arb.intFromTo(1 , 100 ).chunked(3 )
522589arb.intFromTo(1 , 100 ).chunked(3 ) { it.sorted() }
523- arb.charFromTo(' a' , ' t' ).combine (arb.intFromTo(1 , 100 )).chunked(3 ) { it.toMap() }
590+ arb.charFromTo(' a' , ' t' ).zip (arb.intFromTo(1 , 100 )).chunked(3 ) { it.toMap() }
524591```
525592
526593</code-chunked >
@@ -584,13 +651,23 @@ method.
584651Minimalist provides a configuration via ` MinimalistConfig ` which per default can be customised via
585652` minimalist.properties ` .
586653This file needs to be available on your classpath. Typically, you put it in src/test/resources.
587- Next to ` minimalist.properties ` which is intended to make project based adjustments, you can create a
588- ` minimalist.local.properties `
589- which you should add on your git ignore list. This file overwrites settings in ` minimalist.properties ` and is intended
590- for personal adjustments and debugging.
654+ Next to ` minimalist.properties ` which is intended to make project based adjustments
655+ (e.g. change ` Miniamlist.defaultProfile ` to ` E2E ` , see [ profiles ] ( #profiles ) ), you can create a
656+ ` minimalist.local.properties ` which you should add on your git ignore list.
657+ This file overwrites settings in ` minimalist.properties ` and is intended for personal adjustments and debugging.
591658
592659More documentation about the configuration will follow, in the meantime, take a look at the KDoc of MinimalistConfig.
593660
661+ ## Profiles
662+
663+ Minimalist steers how many runs will result at maximum (if not limited by other factors such as
664+ ` OrderedArgsGenerator.size ` ) by the profile definition in use (` MinimalistConfig.defaultProfile ` is ` Integration ` )
665+ and the environment the test runs in (defined via ` MinimalistConfig.activeEnv ` ).
666+ The active environment is determined from environment variables (GitHub and GitLab env vars),
667+ defaulting to ` Local ` if it cannot be deduced.
668+
669+ See ` MinimalistConfig.testProfiles ` for what ` maxArgs ` are defined per default.
670+
594671# Code Documentation
595672
596673Code documentation can be found on github-pages: < https://tegonal.github.io/minimalist/2.0.0-RC-1/kdoc > .
0 commit comments