Giter Site home page Giter Site logo

quickcheck's Issues

'Rng.gen_range called with low >= high'

This can happen due to invalid casts from quickcheck::Gen::size of type usize to various other integer types with a value range smaller than usize (cf. quickcheck::arbitrary::unsigned_arbitrary).

Test case:

#[test]
fn test() {
    fn prop(_: u8) -> bool { true }

    QuickCheck::new()
        .gen(StdGen::new(rand::thread_rng(), 1024))
        .quickcheck(prop as fn(u8) -> bool)
}

Compilation flow arrested on ARM using 1.8 dinghy

Compiling quickcheck_macros v0.2.26
     Running `rustc /tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs --crate-name quickcheck_macros --crate-type dylib -C prefer-dynamic -C opt-level=3 -C metadata=df62799bae73490e -C extra-filename=-df62799bae73490e --out-dir /tmp/ramp-master/target/release/deps --emit=dep-info,link -L dependency=/tmp/ramp-master/target/release/deps -L dependency=/tmp/ramp-master/target/release/deps --extern quickcheck=/tmp/ramp-master/target/release/deps/libquickcheck-ef66e0544cfbee5c.rlib --cap-lints allow`
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 error: found possibly newer version of crate `std` which `syntax` depends on [E0460]
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10 extern crate syntax;
                                                                                            ^~~~~~~~~~~~~~~~~~~~
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 note: perhaps this crate needs to be recompiled?
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10 extern crate syntax;
                                                                                            ^~~~~~~~~~~~~~~~~~~~
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 note: crate `std` path #1: /home/odroid/rust-1.8.0-system-alloc-LFS/lib/rustlib/arm-unknown-linux-gnueabihf/lib/libstd-db5a760f.rlib
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 note: crate `std` path #2: /home/odroid/rust-1.8.0-system-alloc-LFS/lib/rustlib/arm-unknown-linux-gnueabihf/lib/libstd-db5a760f.so
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 note: crate `syntax` path #1: /home/odroid/rust-1.8.0-system-alloc-LFS/lib/rustlib/arm-unknown-linux-gnueabihf/lib/libsyntax-db5a760f.so
/tmp/.cargo/registry/src/github.com-48ad6e4054423464/quickcheck_macros-0.2.26/src/lib.rs:10:1: 10:21 note: crate `syntax` path #2: /home/odroid/rust-1.8.0-system-alloc-LFS/lib/rustlib/arm-unknown-linux-gnueabihf/lib/libsyntax-db5a760f.rlib
error: aborting due to previous error
Could not compile `quickcheck_macros`.

Dinghy is almost two nights old.

make number shrinking lazy

Currently, shrinking numbers is done by filling up a vector with all possibilities and returning it as an iterator. It would be great if this were changed so that each shrunk value wasn't generated until the iterator advanced.

get rid of `Shrinker` proxy trait

In a bygone era, I invented the Shrinker trait as a proxy so the shrink method of Arbitrary could return any iterator without regard to its underlying type. This was because Box<Iterator<A>> didn't itself implement Iterator<A>.

Now that DST is here and Rust has a more coherent story regarding trait object safety, it would be nice to remove this proxy trait and return Box<Iterator> instead.

I started working on this, but I ran into some bugs: rust-lang/rust#20605 and rust-lang/rust#20953. Once those are fixed, I think we can drop Shrinker.

Does not compile with latest nightly (2015-02-19)

There's more than a few compile errors resulting from using the latest nightly:

$ rustc --version
rustc 1.0.0-nightly (dfc5c0f1e 2015-02-18) (built 2015-02-19)
$ cargo build
   Compiling quickcheck v0.1.39 (file:///home/caspar/src/rust-quickcheck)
src/arbitrary.rs:150:29: 150:44 error: the parameter type `A` may not live long enough [E0310]
src/arbitrary.rs:150                 let chain = single_shrinker(None).chain(x.shrink().map(Some));
                                                 ^~~~~~~~~~~~~~~
src/arbitrary.rs:150:29: 150:44 help: consider adding an explicit lifetime bound `A: 'static`...
src/arbitrary.rs:150                 let chain = single_shrinker(None).chain(x.shrink().map(Some));
                                                 ^~~~~~~~~~~~~~~
src/arbitrary.rs:150:29: 150:44 note: ...so that the type `core::option::Option<A>` will meet its required lifetime bounds
src/arbitrary.rs:150                 let chain = single_shrinker(None).chain(x.shrink().map(Some));

* etc etc for another 85 lifetime-related error messages *

src/tester.rs:189:30: 189:36 error: type `core::result::Result<std::thread::JoinGuard<'_, T>, std::io::error::Error>` does not implement any method in scope named `join`
src/tester.rs:189                             .join()
                                               ^~~~~~
src/tester.rs:446:29: 446:35 error: type `core::result::Result<std::thread::JoinGuard<'_, T>, std::io::error::Error>` does not implement any method in scope named `join`
src/tester.rs:446         match t.scoped(fun).join() {
                                              ^~~~~~
error: aborting due to 88 previous errors
Could not compile `quickcheck`.

I had a shot at fixing it without any success (still getting my head around lifetimes and associated syntax) so I figured the next best thing is reporting it.

Related: maybe it'd be worth fixing up http://www.rust-ci.org/BurntSushi/quickcheck ? Seems like it hasn't kicked off a new build in almost a year; it's not particularly clear on that page but on the main rust-ci.org page it claims it was unable to build and needs the owner to authenticate, or something along those lines.

quickcheck depends on WinAPI?

 Downloading rand v0.3.11 (reasonable - quickcheck is a randomized test)
 Downloading log v0.3.2 (reasonable - it's omnipresent)
 Downloading winapi v0.2.4 ( ??? )
 Downloading quickcheck v0.2.24

Write own Arbitrary impls

I wanted to write my own Arbitrary impls but apparently I cannot access the quickcheck::arbitrary module?

RUST_LOG has no effect

README.md:

N.B. When using quickcheck (either directly or via the attributes), RUST_LOG=quickcheck enables info! so that it shows useful output (like the number of tests passed). This is not needed to show witnesses for failures.

RUST_LOG no longer controls the output of the log crate itself. The old behavior can be replicated with env_logger, or the logging behavior can be changed (and the documentation be updated).

Debug trait somehow getting lost (?) making debugging difficult

Expected

Details about why my my data structure failed.

Actual

UNABLE TO SHOW RESULT OF PANIC.

Details

(I am still learning Rust, so bear with me if my code is dumb or I miss something obvious.)

I am trying to define simple, stable-compatible quickcheck tests for a trait, that can be reused to test different data structures that implement it. In this case, I am trying to test a persistent heap.

Data structure + generic test.

Unfortunately, one of my two implementations is broken somewhere, but the only information I get out of quickcheck is Error: "UNABLE TO SHOW RESULT OF PANIC."', <path>/quickcheck-0.2.21/src/tester.rs:113.

Link to broken build.

Link to broken usage location

The data structure in question has #[derive(Debug)] and I have tested that println("{:?}", s) works for this instance of the data structure, so I don't know why I am not getting any other information about the panic, and I don't know what to do to make the situation better.

Seed and print the value of seed used on failure

I have tests that fail very rarely. When this happens on Travis, I'd really like to reproduce the issue locally.

If quickcheck randomly chose a seed, but printed that seed value on failure, then I could replicate test failures.

Provide some way to fail the unit test if all the quickcheck tests were discarded

Sometimes I write too many "discard conditions" (along with too many arguments), or sometimes I get those conditions wrong, and quickcheck ends up discarding all the 10k tests, and flagging the unit test as passed. IMO, either case is a bug, because I'm not actually testing anything, and I should fix the discard conditions.

Right now, the only way to detect this issue is to use RUST_LOG=quickcheck and look out for "Passed 0 Quickcheck tests" messages.

I would like to see some way to fail the unit test if too few quickcheck tests passed. Preferably, using a environment variable, say QC_PASSED_TESTS_THRESHOLD=25 cargo test will fail the unit test if less than 25 quickcheck tests passed, if the variable is unset, the threshold will be zero, which is the current behavior.

Thoughts @BurntSushi ?

The random selection doesn't appear to be very random

I have a type which wraps an i32, and wrote an Arbitrary impl like so:

trait Arbitrary<PgDate> {
    fn arbitrary<G: Gen>() -> Self {
          PgDate(i32::arbitrary())
    }
}

When I actually output what it's running with, the values are only ranging from 100 to -100, instead of 100 completely random numbers as I'd expect. Additionally, shrink appears to be flawed on these types. My understanding was that quickcheck would test for known problematic values for a given type. For i32 I'd expect that to at minimum be 1, 0, -1, i32::MAX and i32::MIN, but when I add the shrink like so:

fn shrink(&self) -> Box<Iterator<Item=Self>> {
    Box::new(self.0.shrink().map(PgDate))

I just see the same range of -100 to 100. This caused a critical bug that occurs for any values less than -2451545 to go unnoticed.

add more examples

It would be great to have an example for implementing shrink with a custom type.

Recursive shrink implementation requiring Clone on sub-iterators.

Ok, so my problem is wanting to implement shrink() for a type made up of other Arbitrary types:

struct Foo {
    bar: Bar,
    baz: Baz,
}

impl Arbitrary for Foo {
    fn arbitrary<G: Gen>(gen: &mut Gen) -> Foo {
        Foo {
            bar: Bar::arbitrary(),
            baz: Baz::arbitrary(),
        }
    }

    fn shrink(&self) -> Box<Iterator<Item=Foo>> {
        let bars = self.bar.shrink().chain(Some(self.bar));
        let bazs = self.baz.shrink().chain(Some(self.baz));
        Box::new(bars.cartesian_product(bazs).map(|(bar, baz)| Foo { bar: bar, baz: baz }))
    }
}

I think this shrink() impl is very elegant, but it doesn't work because cartesian_product (from itertools) requires Clone on the second iterator (of course). This is a well known problem with trait objects; making shrink() return Box<Iterator + Clone> isn't a very satisfying solution, since there's a question of "where do I stop? what about Sync + Send etc?. Furthermore, closures are neverClone` :(. Making the iterator type of shrink an associated type

pub trait Arbitrary {
  type Shrink: Iterator<Item=Self>;
  fn shrink(&self) -> Self::Shrink;
  /* ... */
}

means a default impl can't be provided (at least not without specialisation), but it would solve the issue. I know I can implement a shrink iterator by storing bar and baz itself, and creating new iterators all the time, but that is a lot of boilerplate. Is there some general solution to this problem of composing Arbitrary types?

`cargo test` fails

make test succeeds, but cargo test fails to compile with quickcheck macro dependency issues. I spent a few minute poking around, but couldn't figure out how to fix the issues.

$ cargo test
       Fresh quickcheck_macros v0.1.0 (file:///Users/dan/src/rust/quickcheck)
   Compiling quickcheck v0.1.0 (file:///Users/dan/src/rust/quickcheck)
src/lib.rs:23:1: 23:25 error: can't find crate for `quickcheck`
src/lib.rs:23 extern crate quickcheck;
              ^~~~~~~~~~~~~~~~~~~~~~~~

Edge cases

Is it possible to also define edge cases beside the random data without implementing my own Arbitrary type?

Of course for such cases I could just use normal testingโ€ฆ

Document that String is ASCII alphanumerics-only, maybe have a way of generating more Unicode?

Right now, Strings only have ASCII alphanumeric characters. I tried to use it to generate strings with spaces in it and was surprised when my code was never called ๐Ÿ˜บ

It would be cool if there were more of the Unicode set included. Even awesomer might be if we had some tuning knobs where we could say "more punctuation, less letters", perhaps using the Unicode character classes?

Thanks for the fun-to-use library!

Build failure with recent rust nightly (rustc 79a5448f4)

When I try to compile quickcheck_macros as a Cargo dependency for something else, I get:

Build failed, waiting for other jobs to finish...
Could not compile `quickcheck_macros`.

--- stderr
src\lib.rs:29:48: 29:70 error: mismatched types: expected `Box<syntax::ext::base
::ItemModifier+'static>`, found `fn(&mut syntax::ext::base::ExtCtxt<'_>, syntax:
:codemap::Span, Gc<syntax::codemap::Spanned<syntax::ast::MetaItem_>>, Gc<syntax:
:ast::Item>) -> Gc<syntax::ast::Item>` (expected box, found extern fn)
src\lib.rs:29                                   ItemModifier(expand_meta_quickch
eck));

rustc version is rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000), quickcheck_macros version is v0.1.0 (https://github.com/BurntSushi/quickcheck#c5a719a3). Windows 64-bit (hence the unwieldy line breaks, blame the Win32 console!).

Thanks!

Idea: Testing `fail!`ures with `TestResult::must_fail`

Currently, quickcheck doesn't provide a way to test properties that must trigger a task failure to pass. For example, if you want to test that bound checking is working, you would write the following property:

#[quickcheck]
fn out_of_bounds(length: uint, index: uint) -> TestResult {
    let v = Vec::from_elem(length, 0u8);

    if index < length {
        TestResult::discard()
    } else {
        // v[index] ?
    }
}

But you are missing a piece: You need some function that returns TestResult::passed() if v[index] triggers a task failure, or TestResult::failed() if v[index] succeeded.

That's why I propose adding the must_fail function to the library, where must_fail is defined as:

use quickcheck::TestResult;
use std::comm;
use std::io::ChanWriter;
use std::task::TaskBuilder;

// This should be a `TestResult` static method
fn must_fail<T: Send>(f: proc(): Send -> T) -> TestResult {
    // A "/dev/null" sink for the stderr of the child task
    let (tx, _) = comm::channel();
    let dev_null = box ChanWriter::new(tx) as Box<Writer + Send>;

    let failed =
        TaskBuilder::new().
            // Redirect the stderr of the child task to "/dev/null"
            stderr(dev_null).
            try(f).
            is_err();

    TestResult::from_bool(failed)
}

This function provides the missing functionality to complete the out_of_bounds property:

#[quickcheck]
fn out_of_bounds(length: uint, index: uint) -> TestResult {
    let v = Vec::from_elem(length, 0u8);

    if index < length {
        TestResult::discard()
    } else {
        must_fail(proc() v[index])
    }
}

Which now can be tested:

running 1 test
test out_of_bounds ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

And if you wrongly implement the test, for example by reversing the index < length condition, then the test would fail as expected:

running 1 test
test out_of_bounds ... FAILED

failures:

---- out_of_bounds stdout ----
        task 'out_of_bounds' failed at '[quickcheck] TEST FAILED. Arguments: (1, 0)', src/lib.rs:83



failures:
    out_of_bounds

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

@BurntSushi What do you think? Should this functionality be added to quickcheck?

Add a way to export failing test cases

It would be very convenient to add a way to export failing test cases to allow to reproduce them and make a regression test suite.

The failing test should be exported either as:

  • a test function (with the #[test] attribute) you can just copy-paste inside your code or
  • a file containing the test cases with a way to rerun these test case automatically

This feature is more or less presented in the following video:
https://www.youtube.com/watch?v=x7O2Hkq983Y
And is used on:
http://www.quickcheck-ci.com/

`#[quickcheck]` doesn't work when `quickcheck` isn't in crate root

The #[quickcheck] macro doesn't work when the quickcheck crate is linked as a path other than ::quickcheck:

#![feature(plugin)]
#![plugin(quickcheck_macros)]

#[cfg(test)]
mod test {
    extern crate quickcheck;

    #[quickcheck]
    fn bar() -> bool { true }
}

Errors:

src/lib.rs:8:5: 8:15 error: failed to resolve. Maybe a missing `extern crate quickcheck`?
src/lib.rs:8     #[quickcheck]
                 ^~~~~~~~~~
src/lib.rs:8:5: 8:18 error: unresolved name `quickcheck::quickcheck`
src/lib.rs:8     #[quickcheck]
                 ^~~~~~~~~~~~~

It's clear why this is happening from the macro's implementation, but it would be nice for it to be supported. One solution would be to pass arguments to the #[quickcheck] macro like

#[quickcheck(self, quickcheck)]
fn bar() -> foo { true }

and turn the sequence of identifiers into a path, defaulting to ::quickcheck when none are given. It should also work when quickcheck is used under a different name:

extern crate "quickcheck" as baz;
#[quickcheck(self, baz)]
fn bar() -> foo { true }

This would involve making use of the third argument (the &ast::MetaItem) passed to expand_meta_quickcheck, which is currently ignored.

Is there any way to run a single test

I'm having errors for one test. I'm changing code and running cargo test, but it's including the 300 other tests. Is there any way to flag the test to be the only one run? Something like #[only(quickcheck)]?

make vector shrinking lazy

Currently, a vector is shrunk by producing all possible shrunk values immediately. It would be much better if they were generated lazily with an iterator.

Perhaps std::iter::Unfold will be useful for this.

Failing build with most recent Rust

Looks like the most recent Rust broke things. Building my repo https://github.com/FranklinChen/type-directed-tdd-rust which uses quickcheck resulted in

src/arbitrary.rs:60:29: 60:40 error: explicit lifetime bound required
src/arbitrary.rs:60 impl<A> Iterator<A> for Box<Shrinker<A>> {
                                                ^~~~~~~~~~~
src/arbitrary.rs:75:35: 75:46 error: explicit lifetime bound required
src/arbitrary.rs:75 pub fn empty_shrinker<A>() -> Box<Shrinker<A>> {
                                                      ^~~~~~~~~~~
src/arbitrary.rs:89:44: 89:55 error: explicit lifetime bound required
src/arbitrary.rs:89 pub fn single_shrinker<A>(value: A) -> Box<Shrinker<A>> {
                                                               ^~~~~~~~~~~
src/arbitrary.rs:372:25: 372:36 error: explicit lifetime bound required
src/arbitrary.rs:372     fn new(x: A) -> Box<Shrinker<A>> {
                                             ^~~~~~~~~~~
src/arbitrary.rs:407:25: 407:36 error: explicit lifetime bound required
src/arbitrary.rs:407     fn new(x: A) -> Box<Shrinker<A>> {
                                             ^~~~~~~~~~~

Strings generated by default should have more usual characters

Strings typically generted look like this:

๒’ฝน๒ชฌ›๒˜ŒŸ๓ฅซน๑•˜ผ๒Ÿถน๑€๓ฟกฅ๑ฐซฉ๔‚’ก๐ป˜’๒…‡ช๒ธˆ๒‘™๒Ÿช†๓ดฅ๔…ฒด๓ฉ‡‡ี”๐กซ—๓ผบ†๒บฉช๐พบ—๐ต…Ÿ๐ปŽš๑ฆŽ…๑ณœฟ๓”ˆแ˜ค๑œพŠ๑บฅฟ๒”›๓†ฌญ๐™šน๑ƒƒฃ๑ฅŠ†๒‡†—๒‚ค‡๔€‘ฌ๓จ๓‰จซ๒บŒ‘๑ฝ™•๑ท—ฎ๓ป‰๐ฟžŠ๑นฉต๒–ฌŠ๑ฃ‡๓˜…›๓–›‰๐ผ„ ๓„šท๒ฝ•Ž

๑กฐŽ๐ฃ’Œ๓นฃต

๔…˜ค๓€žถ๑ผฎณ๐ฎ•‡๒€•๑—Žฐ๒€‡ฆ๒น–ป๑š‚ซ๓šพช๒ƒข›เตพ๐ฌซค๑˜–ค๔‡พท๒‡ค๑ฎ…ˆๅผ…๒ฅ…ฝ๑จญด๓ถˆก๑ซฏญ๐งšผไ แด๔Œทž๓ปƒƒ๑›‘“๓ตŽ๐ฏญœ๔„ผง๒›ทบ๑š‚›๑Šชง๓ฏฑฉ๑ฉด๐›ญ‘๐จ€’๑กฅ๓›ข˜๑บข๐ต‘Œ็œป๓–™ž๑…‰Š๒›ปจ๑†ทฎ๓ธง–๓ต”ธ๑Žฝ”๒กšฅ๑‚ผฎ๒†ผค๑„“ญ๑ทฌ—๔‚ญก๒ผ €๑ฅ‰‘๓“Šข๒กฝ๔€Ÿž๑ฎ†€๑ฟซ‡๑ฟŒ๒’‹๑œŽ€๑ข’๒‹ฏผ๑นŒˆ๔ƒ”ช๒ˆŸ™๓Ÿฌ ๓€งธ๓€‰–๐ ฅค๑Œกญ๐ง†ผ๑ฆ›ผ๑ถฐ†๑‚ ‘๐ป—›๒™„’

๒‚บ๓ถผ€๐ฐทน๐พ‰๒ฎ˜ญ๒ˆฅ๓“žค๒ซš๓™–˜๓†–™๐ฐปŸ๑‡ซ™๐ด‹…๐ ˆผ๓นŒ€ๅ‡พ๐–™Ÿ๐ “•๐พญญ๐—ข๑ฅ‚ก๑‡ซ˜๒ซฏ๓จƒ–๏จฑ๓ฐฒบ๒˜ณ‘๐›‰๑กดถ๔นŠ๒”Œ‡แ˜ผ๔Žœ…๓‡†ฏ๓ˆคŸ๓ทƒš๔ŽžŽ๑ฆ–„๋ด„๒ฌฉ˜๑Žฉญ๒“ฒœ๓ฅŠ๐ฐ€ˆ๔†”๑ฅ–๒…ˆณ๐ฟด›๔Œ†—๑ฐ๑›ฏš๔กฉ๒ต† ๑ญ†๔˜ฃ๒…•œ๒ž™„๓ฌฆ๑œŸฉ๓ฎ๒Šฝ›๓˜‰๑”€Š๑Ž‡๓ž๑ฅ‡๓•ŽŽ๐‘ฉ๑กจญ๒‹ก ๒ช™ƒ๓†‚ต๐ซŸฏ๑ฉฝ—๐•กซ๒ž ‡๐คทธ๒™บ›๒„Žฉ๒ฎ‚๒’นฃได’๐ป‰œ๓ธ…ฉ๔Žฌ™๐ท†Š๑ฒŽ€๑ชจŒ๒Œ€€๔„ป–๑‡‹’๓นœ…

๑’ขฉ๒ŠŸ—๐ฅฟ๒Œ…ž๑ฌ•ง๐žŽ‚๑ฎ•„๒žฟฎา™๎ฅญ๓ข‰๓ ขœ๑ญˆ‘๓•“ด๓…ธ›๒•Ž…๐ณž‡๑ช‰ฉ๑žขœ๒ญง˜๓›ฆฆ๓Žชฆ๓ฑšํ™€๑‹ง็ฏฌ๓ฆฒซ๒ˆงน๑”ฟ๑šฃช๒›พ๐กš™๓ซฌด๒ฝ‰ซ๑ˆ—๑”ฏ๓น•ฉ๑ฆŸ ๓ผน๐ฆผ„๓น†ฒ๑œ‹‘๑ ‡’๑‡ฝ–๔‹ค‹๑ค”‡๓‚š๑ผ›๔„ผ€๓ฎ€ฏ๐”ฏ€๓ฆƒ‚๑ต’ต๒„ฏŽ๓ฉŽ…๒“Š•๒ฏ Ž๑Œฌ†๋ก‡๑˜บŠ๑ตบพ๐•งจ๑šพ“๒šฌ๓ทˆฎ๓ ขง๒ฆ‚ผ๐นฅž๓ฎพ›๒ผข๔€œ๒ธฌŸ๓ฎƒฃ๒ชพ‚๒ฌท๑ฏ•ž๑‹“๓žญค๓ฐฅ”๑ฎƒ๓ฒซ๓ปžป๒ปฌ’๔„‘Ž๒‰—ญ๒„ซ›๓จถ‡๓”ฝŸ๒น‘น๒ผนจ๒จต–๑ฐŠ…๑ปฃŠ

๑•‚๔Œฅฉ๑ต‰—๑ถ—–๐ฌ‰ž้ญŠ๑žฆน๓™คต๐ฆช€๐’ฎก๓„ฎฝ๐•— ๑ฅฝ•๔‚ฅฆ๔ˆฒน๓™ก๒žžŒ๐ต„๐ณŽฉ๋šฒ๓„ฌฅ๒ถฐ‚๑ททข๒ฌ‰๑žŸ๒ƒนช่…Ž๓‘ญ๒’‹€๒”ฒ™๓‰บฟ๑ฒฅ“๐นฏ๓ฉฌ‘

๑พง๓ซฎ๒Žฟ›็ชฏ๑•“จ๔ˆฒถ๑ฝถ›๒ฉชฃ๒นก๔‚”๒›˜Ž๒˜‡€๐ ทบ๑Ž‚ฆ๑ญญธ๑ฝŽŠ๐ŠŠ๐จบฟ๒†Šบ๐—žฉ๔Œฝ‚๑ธถ่ผฌ๑„ƒธ๑…™œ๑ขณ๑”ง๑ˆ™„๐ณ๐ช‰›

๐ฅน ๐ผžณ๓พข™๐”…ฟ๔Šญท๑พฃ๒Ž•Š๑ญณ–๒•ธŒ๓Ž€›๒ถƒฃ๐œฟ‰๔€ข›๓ถ„ฟ๐ฒŠŠ๑ชŸ›๑ˆ˜‰๑ฒปฆ๑ญฉ‚๓ณ„’๐พบฒ๐ฏ†Š๑ธ†๑Œผ ๑ญณ’๑ทžˆ๒“Ž๔ˆ‹–๐šœธ๓ฟ’ฒ๒”€๐ฐคซ๒ซฅ‘๒žผฒ๐ฅธ๑ฅพฅ๓“ฎฟ๒ณ–ฑ๐—‹•๓ณ‰‹๔‰ จ๐–ณ๓ท•๒˜Š๒ฉฐ๓บฑ๑ฐ‰ๅดณ๓€ˆ๐’ฏป๒ฟฎฅ๐ฏ™‡๑ฅป‚๓“ฟญ๒ซ™Ž๑„ฆฝ๑ ทŽ๐žธ๑ตณณ๓ฟงป๔‚ฏ“๓น—„๒‡ชพ๓ฝ˜๓‰ตท๒—šซ๑ธ„๓˜ณ๑ถŒ๑ฅตพ๓ง’Ÿ๒ฎซฐ๐–ช„๑žผ—๔พข๐ถ•˜๒Šฎด๐—ฐผ๒„Œ‹๑บฟญ๒ฃ˜ธ

๒ต‘†๒ข€๒ฏช‚๑พ๐ง”ฅ๓ผ–ˆ๒ฌฟš๓ฐ–“๔ฏŒ๒†™๑Ž ค๑ฌดž๐’ฒ๓นฉ๒พœฃ๑ฐข๓ญ™ฏ๑ ต›๑น˜ฆ๓’ณผ๑กซ‰๓บฒข๑˜พฅ๑ฟ”ท๓พฃŽๅŸ™๓Šฝ‘๒ผช๒Šฐญ๑ ฎบ็ฆน๓พฃฃ๐ผต๒’น๑“ชŠ๓ซจฌ๒ซ„’๓ฆ‰‚๑‡ซ„๓ฌ†ฟ๒ปƒƒ๑ฏŸถ๓œš“๐ท—š๐ฒฆ‚๓ป”ด๑ฎ‚๒ถฐŽ๑ฅŠข๑ฐตช๑ข”€๒ปขๅ–’๓ขท…๓Ÿฝ„๑šš๑“ผˆ๒ญถธ๔…‡†๓ญ‚๐œฏƒ๐จ–‰๓‘ถง๒ชŒฟ๐จŒฝ๒„”–๐ฑขผ๒ฉฑผ๒ซฎด

๐ปฅป๒–ฟ„๓Žฐ๐”ฑท๐‘’‚๐ผŸŠ๔‡ผ…๐ฒ‚„๔ˆ”œ๓‰„˜๔‹ซข๐–”„๑‹บ†๐ฌŽฝ๒›–ข๎ญ›๒ ฌ”๔ƒธซ๔€ต†๐ฎ˜œ๓›ฅบ๔‚ถ๒ต„ค๐บ…๑€•›๑Ÿฅ ๔ฝ‘๓นซ ๒กง„๓’ธก๒ฐŽœ๒ŠŽฐ๑ฅ‘Œ๑‡‡ฃ๐ฉ”’๒ฐ…ˆ๒ต„ฏ๑“ฃ๓“ข๒‘››๒‰จธ๐พ“Š๐ท…ฃ๐ตผค๐ฆŒ˜๒“€ž๐ฝฃŸ๒žด

๑’šž๑™ถด๓ซƒ”๑€นฎ๑ฃฏ๐ต˜ฃ๓พˆฃ๒œด๓„Œฟ๐ฆถž๓ฏ›ซ๓„Š๑ณฎ๑šถจ๓กทฃ๐ธซ‚๐žณŠ๑œช๓œฎถ๐บพ†ใฎ„๑†ก๓“ถญ๏ฏˆ๓ŠŽŠ๓ฟงบ๔‹”๓ค„๓พ’๒ฃŽฆ๑›ฆ‹๒ฏ –๔“™๑œ ”๒‡บฑ๐“†ฆ๑Ÿฃค๓ขง๒ฑ•๑—ฝณ๓ถฑฎ๓ถŠผ๓ฟ“Š๒พš“๒ตต†๒ผซ๓„ˆฌ๒œ’•๓ฑฆก๑˜—๒ฎ‘๓”ผ‹๒‚„ธ๓บบ˜๐จ›ฝ๓šฒ๑ถ—œ๓–ฟญ๓ฃ ฏ๒†ฑฉ๑ฐŠซๆ†Ž๑ณฅ’๑ผทต๐ —†๑ป ๓ฝ–พ๐ฟ‚†๓‘““๑Žšฏ๒ฆ‰ ๐˜Šฒ

๐ณธˆ๒‹ธด๎คœ๓‚ฉ—๑ฝฐ‹๑„จช๑‰™๒€คต๓•ณท๐šฑฒ๒ตš‘๓“ถต๑€ก๓ˆก๒ฎ–ต๑œฌƒ๑ซกต๑ ฌณ๑ฌถŠ๐กฑญ๑…ผบ๒™พ๑žฌ๊ˆบ๐น–‰๐ตŒ›ใƒญ๑’ญ๔‰ซ’๓‹Ÿ‘๑”Šข๒ฝฒ“๑ฟจˆ๑‘œฐ๑‡ฟด๒ขฃ–๔Ÿฃ๒ฐฎ๓ฟ˜ฑ๓„กฃ๓น‰š๐ฌฅฟ๑‹˜™๐”ญฆ๒กŽ‘

๓ฐบฟ๓ถ„”๐ฌ†ท๓ฑ‚Œ๓‰ฌž๓พชข๑–––๑ฎŠ•๑งƒ๒พฝผ๑จคณ๐ธพ‚๐ฃ‘Œ๓ธ•–๓นดŒ๐ฌœ„๐‘ผฆ๔Œทฑ๒ฉ”ค๐–Œธ๑ฅบผ๑—Žฑ๑—ฑ๓ฒฃ‘๐ด’จ๓ดน’๐น’ช๓‹ŠŒ๓จด–๒™€๒ฟต๑ซ˜•๓‡ฏ๒‚ฏฒ๑ต•Œ๑ขœ๓นคจ๒™ข„๑จ“ฉ๒„ ‘๑ปจธ๐ปฆ๓ฆฉ’๑ฌชธ๓ปดด๑œ€›๒‡ฉ๑ผ—•๒ฃš‰๓ต›๓ฃนฅ๒‰ญž๒ฆšŽ๑€บฒ๑†›œ๓ฎŸ๑Ÿ’ซ๐ฒน‡๒‹ผก๒ทง˜๑ฟฉฌ๓Žญ๒ช†€๐›‘›๑ป‰ž๓ซจ๐กžฑใ†’

๒ผ‹ก๓ฏปญ๔ค›๑Ž”๓ธดญ๓œˆฐ๑ฑšฑํ”ฆ๓Ž†๐ขป๒ทŸ๑žฎต่˜ช๓–ฃข๐ซญช๐ฒŠบ๓ฟœš๑ˆ…—๒ฟง™๓ฟดž๑ซŒฑ่กฏ๒‰•ญ๒Šžดา›๓ด™ ๐ฑœฏ๑™ฐ๒ŠŒ๑ฎจฌ๓ชพช๒ฎ‚๐พจ†๑ฑ˜พ๑ก ‡ํŒข๒—ก—๒ฝ‘ถ๒ดธŸ๐™…ก๒Ž‹Ž๐ ฎ๓ถ–‰๒„ก๓Ÿ›ฟ๔ ฐ๒Ÿฟข๑šจฌ๐ฏขฌ๒ญซ‰๔‰Œž๑˜ฎ๓—•–๑กค๐ฎบ€๑ซ€๐”šˆ๑ท‹ญ๐™ชข๒‡ฌฃ๒›กก๑—šก๒“›๒˜Œถ๐ฆทด๑ถต๒ฎต”์ˆฅ๐ฒŸช

๑˜ฟ˜๐›€ฆ๒ตŠป๓ ‘œ๓ผพ๐™ˆจ๓นฒƒ๐ธฏ•๐œ†ฆๆท…๓ตฎ๐ฐ‚˜๑›ฆ‘๓›ซŒ๓Œฒ๓”•‡๓น™ฎ๑งƒท๑งˆต๑ ถ„๒™นซ๓“ฐ†๒’ˆ๔ƒŽข้‚ฎ๒ฃป–๑ฉน–๐“‹ฑ๐ฅฅซ๑ฉ˜†

It fails (or takes long) to find simple case like a when something starts with a space, special character or like this.

I think normal characters should be preferred to deeply Unicode things.

I think by default there should be tiers of characters classes:

  1. Bug-prone characters: whitespace, punctuation, control characters, maybe up to 5 selected Unicode queeries like zero-width space;
  2. [a-zA-Z0-9_];
  3. Unicode characters in the first plane;
  4. Everything else.

And character generator may aim for, for example, 10% of buggy chars, 40% of [a-zA-Z0-9_], 40% of basic Unicode characters, 10% of everything else.

implement Testable for Fn*

Using rustc 1.0.0-nightly (3d0d9bb6f 2015-01-12 22:56:20 +0000):

fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
    let mut rev = vec!();
    for x in xs.iter() {
        rev.insert(0, x.clone())
    }
    rev
}

#[test]
fn reverse_identity() {
  fn prop(xs: Vec<i32>) -> bool {
    xs == reverse(reverse(xs.as_slice()).as_slice())
  }
  quickcheck(prop);
}

produces

error: the trait `quickcheck::tester::Testable` is not implemented for the type `fn(collections::vec::Vec<i32>) -> bool {tests::reverse_identity::prop}`

quickcheck(false) compiles; this appears to be specific to the fn impls, including the zero-arg fn.

quickcheck-macros doesn't build on the latest nightly

When building on the latest nightly, I get the following error message:

$ cargo test
 Downloading rand v0.3.12
 Downloading log v0.3.4
 Downloading quickcheck v0.2.24
 Downloading winapi v0.2.5
 Downloading libc v0.2.2
 Downloading quickcheck_macros v0.2.24
   Compiling winapi v0.2.5
   Compiling libc v0.2.2
   Compiling log v0.3.4
   Compiling advapi32-sys v0.1.2
   Compiling rand v0.3.12
   Compiling quickcheck v0.2.24
   Compiling quickcheck_macros v0.2.24
/Users/hawk/.multirust/toolchains/nightly/cargo/registry/src/github.com-88ac128001ac3a9a/quickcheck_macros-0.2.24/src/lib.rs:23:5: 23:28 error: unresolved import `rustc::plugin::Registry`. Could not find `plugin` in `rustc` [E0432]
/Users/hawk/.multirust/toolchains/nightly/cargo/registry/src/github.com-88ac128001ac3a9a/quickcheck_macros-0.2.24/src/lib.rs:23 use rustc::plugin::Registry;
                                                                                                                                    ^~~~~~~~~~~~~~~~~~~~~~~
/Users/hawk/.multirust/toolchains/nightly/cargo/registry/src/github.com-88ac128001ac3a9a/quickcheck_macros-0.2.24/src/lib.rs:23:5: 23:28 help: run `rustc --explain E0432` to see a detailed explanation
error: aborting due to previous error
Could not compile `quickcheck_macros`.

To learn more, run the command again with --verbose.

On the latest nightly:

$ rustc --version
rustc 1.7.0-nightly (81ae8be71 2015-12-09)
$ cargo --version
cargo 0.7.0-nightly (1af03be 2015-12-08)

quickcheck_macros does not work on stable (or beta)

Using stable Rust trying to install quickcheck_macros gives:

Compiling quickcheck_macros v0.2.24
/home/users/russel/.cargo/registry/src/github.com-0a35038f75765ae4/quickcheck_macros-0.2.24/src/lib.rs:8:1: 8:45 error: #[feature] may not be used on the stable release channel
/home/users/russel/.cargo/registry/src/github.com-0a35038f75765ae4/quickcheck_macros-0.2.24/src/lib.rs:8 #![feature(plugin_registrar, rustc_private)]

which more or less makes this potentially wonderful testing tool useless. Or have I missed something?

Error with quickcheck_macros

Running cargo test in the quickcheck_macros directory with the latest rust nightly 4874ca36f.

   Compiling quickcheck_macros v0.1.30 (file:///Users/sam/Dropbox/Projects/quickcheck/quickcheck_macros)
tests/macro.rs:9:1: 9:14 error: functions used as tests must have signature fn() -> ()
tests/macro.rs:9 #[quickcheck]
                 ^~~~~~~~~~~~~
tests/macro.rs:18:1: 18:14 error: functions used as tests must have signature fn() -> ()
tests/macro.rs:18 #[quickcheck]
                  ^~~~~~~~~~~~~
tests/macro.rs:22:1: 22:14 error: functions used as tests must have signature fn() -> ()
tests/macro.rs:22 #[quickcheck]
                  ^~~~~~~~~~~~~
tests/macro.rs:25:1: 25:14 error: functions used as tests must have signature fn() -> ()
tests/macro.rs:25 #[quickcheck]
                  ^~~~~~~~~~~~~
error: aborting due to 4 previous errors
Could not compile `quickcheck_macros`.

To learn more, run the command again with --verbose.

Would it be a good idea to update the .travis.yml file to also test the macros?

How to make generated parameters test certain cases

I have another question about writing QuickCheck tests.

My function under test, edit_distance, has another property, which I want to quickcheck.

It is zero if and only if the strings are equal.

This requires that both parameters reasonably often are equal. I have a naive implementation here:

febeling/edit-distance@30532c2#diff-475a9530a9c1e888d097445199b74c2fR75

But when I run it and prepare the code a bit, I have seen that the the condition 'strings are equal' is never met. I guess that's a common problem in quickcheck test. Is there a good way to deal with this case?

source trait is private (Rng)

Please consider this test case:

extern crate quickcheck;

use quickcheck::{Arbitrary, Gen};

#[derive(Clone)]
pub struct Foo(u8);

impl Arbitrary for Foo {
    fn arbitrary<G: Gen>(g: &mut G) -> Foo {
        Foo(g.gen())
    }
}

Compilation with rustc 1.3.0-nightly (0c052199b 2015-07-11) gives:

src/lib.rs:10:13: 10:20 error: source trait is private
src/lib.rs:10         Foo(g.gen())
                          ^~~~~~~

I think it is necessary to export not only Gen but also it's parent trait Rng:

diff --git a/src/lib.rs b/src/lib.rs
index f13fcdc..ab1698b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -10,6 +10,7 @@
 #[macro_use] extern crate log;
 extern crate rand;

+pub use rand::Rng;
 pub use arbitrary::{
     Arbitrary, Gen, StdGen,
     empty_shrinker, single_shrinker,

Using the function traits would improve usability.

At the moment when passing a function to quickcheck, its type has to specified:

fn prop() -> bool {
    true
}

quickcheck(prop as fn() -> bool);

However, bare functions can be passed as generic items implementing Fn traits without any casting:

fn run<F, T>(f: F) -> T where F: Fn() -> T {
    f()
}

fn prop() -> bool {
    true
}

fn main() {
    let t = run(prop);
    println!("{}", t);
}

If we implemented the Testable trait for F where F: Fn(A, ...) -> T instead of the concrete fn(A, ...) - T types, it would be possible to just do:

quickcheck(function);

I think this is a usability win, especially with #[quickcheck] unusable under 1.0 (people are likely to be writing quickcheck quite a bit).

I had a quick go at implementing this, but ran into trouble with the Fun trait. I couldn't work out a way to call the function (passed as &self) in a move closure passed to safe. It may be possible, or else more extensive restructuring may be required.

Feature request: Add auto-derivators for structs and enums

I want quickcheck to have a compiler plugin that automatically generates Arbitrary impl for structs and enums composed of Arbitrary types, like with serialisation.

That should shrink

extern crate quickcheck;

use quickcheck::Arbitrary;

#[derive(Clone,Debug)]
struct Mumu {
    a : u32,
    b : String,
}

#[derive(Clone,Debug)]
enum Qqq {
    Lol,
    Ror,
    Kokoko(Mumu),
    Totot(u32),
}

impl Arbitrary for Mumu {
    fn arbitrary<G : quickcheck::Gen>(g:&mut G) -> Mumu {
        Mumu {a : Arbitrary::arbitrary(g), b : Arbitrary::arbitrary(g) }
    }
    fn shrink(&self) -> Box<Iterator<Item=Self>> {
        Box::new ( (self.a.clone(), self.b.clone()).shrink().map(|(aa,bb)| Mumu { a: aa, b:bb}))
    }
}

impl Arbitrary for Qqq {
    fn arbitrary<G : quickcheck::Gen>(g:&mut G) -> Qqq {
        let y = g.next_u32() % 4;
        match y {
            0 => Qqq::Lol,
            1 => Qqq::Ror,
            2 => Qqq::Kokoko(Arbitrary::arbitrary(g)),
            3 => Qqq::Totot(Arbitrary::arbitrary(g)),
            _ => panic!(),
        }
    }
    fn shrink(&self) -> Box<Iterator<Item=Self>> {
        match self {
            &Qqq::Totot(ref x) => Box::new(x.shrink().map(|s| Qqq::Totot(s))),
            &Qqq::Kokoko(ref x) => Box::new(x.shrink().map(|s| Qqq::Kokoko(s))),
            _ => quickcheck::empty_shrinker(),
        }
    }
}



#[test]
fn it_works() {
    fn qqq(x : Qqq) -> bool {
        if let Qqq::Kokoko(Mumu { a : v, b: _ }) = x {
            return v != 4
        }
        true
    }

    quickcheck::QuickCheck::new().tests(1000_000_000).quickcheck(qqq as fn(Qqq) -> bool);
}

to

extern crate quickcheck;

use quickcheck::Arbitrary;

#[derive(Clone,Debug,Arbitrary)]
struct Mumu {
    a : u32,
    b : String,
}

#[derive(Clone,Debug,Arbitrary)]
enum Qqq {
    Lol,
    Ror,
    Kokoko(Mumu),
    Totot(u32),
}

#[test]
fn it_works() {
    fn qqq(x : Qqq) -> bool {
        if let Qqq::Kokoko(Mumu { a : v, b: _ }) = x {
            return v != 4
        }
        true
    }

    quickcheck::QuickCheck::new().tests(1000_000_000).quickcheck(qqq as fn(Qqq) -> bool);
}

Implement Wrapping<integer type> for Arbitrary

It would be nice to be able to use quickcheck with (e.g.) Wrapping<u8>. I'm not sure I can fix this in my own code, adding

impl Arbitrary for Wrapping<u8> {
    fn arbitrary<G: Gen>(g: &mut G) -> Wrapping<u8> {
        Wrapping(Arbitrary::arbitrary(g))
    }
}

generates a compile error because neither Arbitrary nor Wrapping were defined by me.

How to test a function `fn(&str, &str) -> bool`?

This is a question issue, and I hope that's an acceptable use in this project.

I try to use quickcheck to write tests for function accepting two strings. I haven't been able to adapt the example test to my use case. This is what I have. Is quickcheck able to provide random parameters for strings (or &strs)?

extern crate quickcheck;
// at least difference of the sizes of a and b
#[test]
fn prop_test_() {
    use quickcheck::quickcheck;

    fn at_least_size_difference(a: &str, b: &str) -> bool {
        let size_a = a.chars().count() as i32;
        let size_b = b.chars().count() as i32;
        let diff = (size_a - size_b).abs();

        edit_distance::edit_distance(a, b) > diff;
    }

    quickcheck(at_least_size_difference as fn(a: &str, b: &str) -> bool);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.