Git Product home page Git Product logo

test.chuck's Introduction

test.chuck

test.chuck is a utility library for test.check.




       (this space intentionally left blank)



Obtention

Leiningen dependency coordinates:

[com.gfredericks/test.chuck "0.1.16"]

Usage

General Helpers

(require '[com.gfredericks.test.chuck :as chuck])

times

A helper function for being able to scale your test run count with an environment variable. To use with defspec, simply wrap your test-count argument in a call to times:

(defspec foo-bar-test (chuck/times 20)
  ...)

This will normally run the test 20 times, but if you set the TEST_CHECK_FACTOR environment variable to e.g. 3.5, it will run the tests 70 times.

Generators

(require '[com.gfredericks.test.chuck.generators :as gen'])

There are a few minor generators and helpers, see the docstrings for details:

  • for (described below)
  • string-from-regex
  • subsequence (for subsets and similar)
  • cap-size
  • partition
  • map->hash-map
  • bounded-int
  • double

for

A macro that uses the syntax of clojure.core/for to provide the functionality of gen/bind, gen/fmap, gen/such-that, and gen/tuple:

(gen'/for [len gen/nat
           bools (gen/vector gen/boolean len)]
  [len bools])

(gen/sample *1)
;; => ([0 []]
;;     [0 []]
;;     [2 [false true]]
;;     [3 [true false true]]
;;     [1 [true]]
;;     [5 [true true false false true]]
;;     [2 [false false]]
;;     [1 [true]]
;;     [8 [true false false true false false false false]]
;;     [1 [true]])
(gen'/for [:parallel [n1 gen/nat
                      n2 gen/nat]
           :when ^{:max-tries 20} (coprime? n1 n2)
           :let [product (* n1 n2)]]
  {:n product, :factors [n1 n2]})

(gen/sample *1)
;; => ({:n 1, :factors [1 1]}
;;     {:n 0, :factors [1 0]}
;;     {:n 2, :factors [1 2]}
;;     {:n 0, :factors [0 1]}
;;     {:n 6, :factors [3 2]}
;;     {:n 20, :factors [4 5]}
;;     {:n 0, :factors [1 0]}
;;     {:n 4, :factors [1 4]}
;;     {:n 24, :factors [3 8]}
;;     {:n 14, :factors [2 7]})

string-from-regex

string-from-regex is a suspiciously robust generator that will generate strings matching a regular expression:

user> (gen/sample (gen'/string-from-regex #"([☃-♥]{3}|B(A|OO)M)*"))
(""
 "☍♛☽"
 ""
 "♂♡☱BAM"
 "♥☩♏BAMBAM"
 ""
 "☓☪☤BAMBAMBOOMBOOM☑☔☟"
 ""
 "BOOM☻☘☌☏☜♋BAM♑♒♛BAMBAM"
 "BOOMBAM♅☧♉☎☐♘BOOM☥♜☐")

It does not work with every regular expression, but its goal is to correctly recognize (and report) the usage of unsupported features, and to handle supported features in a comprehensive way.

Shrinking

Generated strings shrink in a natural way:

(def gen-cool-string
  (gen'/string-from-regex
   #"This string has (1 [A-Z]|[2-9]\d* [A-Z]'s)((, (1 [A-Z]|[2-9]\d* [A-Z]'s))*, and (1 [A-Z]|[2-9]\d* [A-Z]'s))?\."))

(def bad-prop
  (prop/for-all [s gen-cool-string]
    (not (re-find #"1 F" s))))

(t.c/quick-check 1000 bad-prop)
=>
{:fail ["This string has 6309694848500700538 H's, 79102649012623413352 F's, 1 F, 59860 U's, 1 T, 1 W, 1 B, and 1 M."],
 :failing-size 26,
 :num-tests 27,
 :result false,
 :seed 1418877588316,
 :shrunk {:depth 8,
          :result false,
          :smallest ["This string has 1 A, 1 F, and 1 A."],
          :total-nodes-visited 27}}
Unsupported regex features

Some of these could be supported with a bit of effort.

  • All flags: (?i), (?s), etc.
  • Lookahead and lookbehind
  • Reluctant and Possesive quantifiers: X??, X*+, etc.
    • I'm not sure what these would mean anyhow
  • Anchors: \b, ^, \A, $...
  • Backreferences
    • This is tricky at least because it introduces the possibility of unmatchable expressions
  • Character class intersections
  • The hex syntax for unicode characters outside the BMP: \x{10001}
  • Named character classes: \p{IsAlphabetic}, \P{ASCII}, ...

Properties

com.gfredericks.test.chuck.properties/for-all is an alternative to clojure.test.check.properties/for-all that uses the for macro to interpret the binding clauses:

(require [com.gfredericks.test.chuck.properties :as prop'])

(prop'/for-all [a gen/pos-int
                :when (even? a)
                :let [b (/ a 2)]
                xs (gen/vector gen/int b)]
  (= (count xs) b))

Alternate clojure.test integration

A macro that allows you to use clojure.test/is and clojure.test/are with test.check, letting you keep the side-effecting style that is often used with clojure.test.

More details in this blog post.

Contributing

I welcome pull requests for any test.check utility that seems halfway reasonable.

Acknowledgments

  • @lackita for creating com.gfredericks.test.chuck.clojure-test
  • @weavejester for creating the original regex->string code
  • @miner for various help with the string-from-regex generator

License

Copyright © 2014 Gary Fredericks

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

test.chuck's People

Contributors

gfredericks avatar lackita avatar

Watchers

Tom Crayford avatar James Cloos avatar

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.