quick
Version, currently 1.1.04 versions
- 1.1.0latestMar 29, 2016
- 1.0.2not indexedMar 29, 2016
- 1.0.1not indexedMar 29, 2016
- 1.0.0not indexedMar 29, 2016
github.com/waterlink/quick.cr
QuickCheck implementation for Crystal Language
13 stars
0 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
quick:
github: waterlink/quick.cr
version: ~> 1.1.0Then run:
shards installshard.yml
- Crystal
- no constraint declared
- License
- MIT
- Author
- Oleksii Fedorov <waterlink000@gmail.com>
Dependencies
Development Dependencies
- spec2~> 0.7.1github: waterlink/spec2.crdev
README
# quick [](https://travis-ci.org/waterlink/quick.cr)
QuickCheck implementation for Crystal Language.
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
quick:
github: waterlink/quick.cr
version: ~> 1.0
```
## Usage
```crystal
require "quick"
```
### Property testing
```crystal
Quick.check("add reflexivity", [x : Int32, y : Int32]) do
add(x, y) == add(y, x)
end
```
It raises `Quick::CheckFailedError(T)` when property does not hold for some
values. `T` is a type of tuple, containing all failed arguments.
These failed arguments are accessible on error instance as `error.failed_args`.
### Configuration
`Quick.check` accepts different keyword arguments, that can be combined:
- `Quick.check("property", [value : Int32], number_of_tests: 100)` - `number_of_tests` controls,
how much tests are generated to verify the property. Default: `100`.
### Control over generated data
`Quick.check` determines generator for the data from the type annotation of a
block arguments. Possible options:
- A basic type with default min/max limits:
- `x : Int32`, also, `UInt32, Int8, UInt8, Int16, UInt16, Int64 and UInt64` are supported,
- `s : String`,
- `f : Float64`, also, `Float32` is supported,
- `c : Char`
- `b : Bool`,
- `a : Array(Int32)`, and `Array(T)` in general case, where `T` can be any of supported basic types, built-in generators and user-defined generators,
- `p : Tuple(Int32, Float64)` (pair), `Tuple(T, U)` in general case,
- `h : Hash(String, Float64)`, `Hash(K, V)` in general case,
- One of the range: `value : Quick::Range(13, 79)`
- `Quick::Range` is an alias for `Quick::Range32`, which works only with `Int32`
- `Quick::Range8` and `Quick::Range16` are available for corresponding `Int8` and `Int16` types
- `Quick::Range64` is available, but cannot be used with ranges out of `Int32` boundaries (see: crystal-lang/crystal#2353)
- `Quick::FloatRange` and `Quick::FloatRange64` for ranges of type `Float64`
- `Quick::FloatRange32` for ranges of type `Float32`
- Array of specific size: `a : Quick::Array(Int32, 50)`
- Array of generated size: `a : Quick::Array(Int32, Quick::Range(0, 1000))`
- String of specific size: `s : Quick::String(15)`
- String of generated size: `s : Quick::String(Quick::Range(0, 50))`
- Numeric value for a size (same as `Int32`, but has smaller default limit 0..100): `size : Quick::Size`
- Pick one value from the list: `Quick.def_choice(ColorGen, "red", "blue", "green")` and use it as `value : ColorGen`
- Pick one generator from the list: `Quick.def_gen_choice(RandomStuffGen, Int32, HelloWorldGen, ColorGen, FloatRange(2, 4), Bool)` and use it as `value : RandomStuffGen`
### Literal generator that returns same value
First define your own literal generator class, that will always return provided value:
```crystal
# it defines special HelloWorldGen type, that can be
# used in type annotations afterwards
Quick.def_literal(HelloWorldGen, "hello world")
```
And then use it:
```crystal
Quick.check("property") do |s : HelloWorldGen|
s == "hello world"
end
```
### Building your own generator
If you have your own custom data structure, that you want to generate data for,
you simply need to create new generator that conforms to `Quick`'s Generator(T)
protocol:
- `include Generator(T)`, where `T` is the type of generated value, and
- implement `self.next : T` method
```crystal
record User, :email, :password
# E - email size gen
# P - password size gen
class UserGen(E, P)
include Quick
include Generator(User)
def self.next : User
User.new(
String(GeneratorFor(E).next).next + "@example.org",
String(GeneratorFor(P).next).next
)
end
end
```
Then you should be able to use it as:
```crystal
Quick.check("valid user") do |user : UserGen(Quick::Size, Quick::Size)|
user.valid?
end
# or with custom size generators
Quick.check("valid user") do |user : UserGen(Quick::Range(10, 20), Quick::Range(16, 21))|
user.valid?
end
```
## Development
After cloning this repository, run `shards install` to install dependencies.
To run the test suite, use `crystal spec`.
## Contributing
1. Fork it ( https://github.com/waterlink/quick.cr/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create a new Pull Request
## Contributors
- [waterlink](https://github.com/waterlink) Oleksii Fedorov - creator,
maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
1.1.0- Tagged
- Mar 29, 2016
- Commit
f8e512be2e1a- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/waterlink/quick.cr
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 13, 2026
- Synced
- Aug 13, 2026
- Versions
- 4