initial thoughts

This commit is contained in:
waalge 2024-02-06 11:12:44 +00:00
parent 982eff449e
commit c03d12b98c
8 changed files with 243 additions and 2 deletions

View File

@ -3,7 +3,7 @@ use chumsky::prelude::*;
use crate::{
ast,
expr::UntypedExpr,
parser::{error::ParseError, expr, token::Token},
parser::{error::ParseError, expr, token::Token, definition::function::param},
};
pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
@ -13,7 +13,15 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
.or_not()
.then_ignore(just(Token::Test))
.then(select! {Token::Name {name} => name})
.then(
param(false)
.separated_by(just(Token::Comma))
.allow_trailing()
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
.map_with_span(|arguments, span| (arguments, span)),
)
.then_ignore(just(Token::LeftParen))
.then_ignore(just(Token::RightParen))
.then(just(Token::Fail).ignored().or_not())
.map_with_span(|name, span| (name, span))

1
examples/moonrat/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

114
examples/moonrat/README.md Normal file
View File

@ -0,0 +1,114 @@
# Moonrat
> Hedgehog's spineless cousin
## Aims
Property based testing for aiken inspired by hedgehog and elm-test.
Aims:
- Default gen and shrinking auto derived for any types
- Support custom gen/shrinking
- Friendly output (progress, sensible feedback such as diffs on large data)
- Reasonably speedy
Non-aims:
- e2e testing.
This is intended for functions rather than testing full txs against validators.
Although it should still be possible, it is not our aim here to make writing and testing txs ergonomic.
## Interface
An aiken file
```aiken
// my_tests.ak
type T0 {
f0 : Int,
...
}
fn gen_t0(seed : Int, complexity : Int) -> T0 {
...
}
fn shrink_t0(x : T0) -> List<T0> {
// TODO : what should the signature of this be?!
...
}
type T1 {
f0 : Int,
...
}
test prop_x (
a0 : T0 via (gen_t0(0), shrink_t0),
a1 : T0 via (gen_t0(1), shrink_t0),
a2 : T0,
a2 : T1,
) {
todo!
}
```
Comments on the sample.
`prop_x` is our test - now supporting arguments.
There is new syntax `via`.
We have a custom generator and shrinker for `T0` which we may or may not use.
In the absence of a specified gen/shrink pair, the default, autoderived one is used.
Run 100 times
```
aiken check -m "my_lib/my_test.{prop_x}"
```
Run 1000 cases with a specified seed and shrink limit
```
aiken check --repeat 1000 --seed 123212123 --shrink-limit 5
```
Reporting:
```sample
Testing ...
my_test
prop_x PASS [100/100]
```
```sample
Testing ...
my_test
prop_x FAIL (after 16 tests and 5 shrinks):
a0 = T0 { f0 : 120201, ... }
a1 = T0 { ... }
...
RHS = True
LHS = False
seed = 123212123
Rerun with
aiken check -m "my_lib/my_test.{prop_x}" --args " [ T0 { }] ... "
```
## Functionality
Aiken compiler finds all tests.
Any tests with args are assumed subject to property based testing.
[Property config](https://hackage.haskell.org/package/hedgehog-1.4/docs/Hedgehog-Internal-Property.html#t:PropertyConfig) is global, rather than local.
The test is compiled as if it were a parametrized validator.
Separate gen and shrink functions are also compiled.
To evaluate the test, the generator(s) are run to generate input for the test.
Then the args are applied, and the code evaluated.
On success this is repeated until `repeat` number of successes.
On failure, the shrinker is employed to seek a simpler failure case.

View File

@ -0,0 +1,16 @@
# This file was generated by Aiken
# You typically do not need to edit this file
[[requirements]]
name = "aiken-lang/stdlib"
version = "main"
source = "github"
[[packages]]
name = "aiken-lang/stdlib"
version = "main"
requirements = []
source = "github"
[etags]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707160390, nanos_since_epoch = 895305443 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"]

View File

@ -0,0 +1,8 @@
name = "aiken-lang/moonrat"
version = "0.0.0"
description = ""
[[dependencies]]
name = 'aiken-lang/stdlib'
version = 'main'
source = 'github'

View File

@ -0,0 +1,4 @@
test test_with_arg(x : Int) {
x - x == 0
}

View File

@ -0,0 +1,89 @@
{
"preamble": {
"title": "aiken-lang/acceptance_test_089",
"version": "0.0.0",
"plutusVersion": "v2",
"compiler": {
"name": "Aiken",
"version": "v1.0.24-alpha+982eff4"
}
},
"validators": [
{
"title": "test2.simple_oneshot",
"redeemer": {
"title": "_r",
"schema": {
"$ref": "#/definitions/Void"
}
},
"parameters": [
{
"title": "utxo_ref",
"schema": {
"$ref": "#/definitions/aiken~1transaction~1OutputReference"
}
}
],
"compiledCode": "58d40100003232323232323232322225333006323232323232533300c3370e900018058018991919299980799b8748000c0380044c8c94ccc044cdc3a40000022944528180780099801002119baf3004300e00100d163300100323375e6006601a00201844646600200200644a6660280022980103d87a8000132325333013300500213374a90001980b80125eb804cc010010004c060008c0580048c04800458dd61808000980400198070009807001180600098020008a4c26cac4600a6ea80048c00cdd5000ab9a5573aaae7955cfaba05742ae89",
"hash": "dd850cc95e173d7dbb3357a4a021afc350f405a3cc2e85ace58bfe8d"
}
],
"definitions": {
"ByteArray": {
"dataType": "bytes"
},
"Int": {
"dataType": "integer"
},
"Void": {
"title": "Unit",
"description": "The nullary constructor.",
"anyOf": [
{
"dataType": "constructor",
"index": 0,
"fields": []
}
]
},
"aiken/transaction/OutputReference": {
"title": "OutputReference",
"description": "An `OutputReference` is a unique reference to an output on-chain. The `output_index`\n corresponds to the position in the output list of the transaction (identified by its id)\n that produced that output",
"anyOf": [
{
"title": "OutputReference",
"dataType": "constructor",
"index": 0,
"fields": [
{
"title": "transaction_id",
"$ref": "#/definitions/aiken~1transaction~1TransactionId"
},
{
"title": "output_index",
"$ref": "#/definitions/Int"
}
]
}
]
},
"aiken/transaction/TransactionId": {
"title": "TransactionId",
"description": "A unique transaction identifier, as the hash of a transaction body. Note that the transaction id\n isn't a direct hash of the `Transaction` as visible on-chain. Rather, they correspond to hash\n digests of transaction body as they are serialized on the network.",
"anyOf": [
{
"title": "TransactionId",
"dataType": "constructor",
"index": 0,
"fields": [
{
"title": "hash",
"$ref": "#/definitions/ByteArray"
}
]
}
]
}
}
}

View File

@ -78,9 +78,10 @@
openssl
cargo-insta
(pkgs.rust-bin.stable.latest.default.override {
extensions = [ "rust-src" "clippy" "rustfmt" ];
extensions = [ "rust-src" "clippy" "rustfmt" "rust-analyzer" ];
})
] ++ osxDependencies;