Packages

Triq (Term Reductive Invariant Questant) QuickCheck

Current section

4 Versions

Jump to

Compare versions

21 files changed
+267 additions
-510 deletions
  @@ -1,6 +1,7 @@
1 1 Triq - Trifork QuickCheck
2 2
3 3 Copyright (C) 2010 Trifork A/S
4 + Copyright 2013-2018 Triq authors
4 5
5 6 Licensed under the Apache License, Version 2.0 (the "License");
6 7 you may not use this file except in compliance with the License.
  @@ -8,21 +8,78 @@
8 8 :CUSTOM_ID: introduction
9 9 :END:
10 10
11 - By and large, the Triq API is modeled closely after QuviQ =eqc=, except you
12 - want to replace any occurrence of =eqc= with =triq=. The main supporting module
13 - is called =triq_dom=, corresponding to eqc's =eqc_gen=.
11 + Triq (Term Reductive Invariant Questant) is an Apache licensed
12 + QuickCheck library for Erlang. It is a continuation and community fork
13 + of [[https://github.com/krestenkrab/triq][Trifork QuickCheck]]. Unlike the original project, this fork is in
14 + *no way* affiliated with or a product of Trifork.
15 +
16 + By and large, the Triq API is modeled closely after QuviQ =eqc=,
17 + except you want to replace any occurrence of =eqc= with =triq=. The
18 + main supporting module is called =triq_dom=, corresponding to eqc's
19 + =eqc_gen=.
14 20
15 21 #+BEGIN_EXPORT html
16 22 <a href="https://gitlab.com/triq/triq/pipelines"><img src="https://gitlab.com/triq/triq/badges/master/pipeline.svg"></a>
17 23 #+END_EXPORT
18 24
19 - This is a fork of Triq that is being run under the ZeroMQ Collaberation
20 - rules, https://rfc.zeromq.org/spec:22 with the one exception being that
21 - it is under the Apache licence.
25 + ** Writing QuickCheck properties with Triq
26 + :PROPERTIES:
27 + :CUSTOM_ID: writing-properties-with-triq
28 + :END:
29 +
30 + To write properties with =triq=, include the =triq.hrl= header file:
31 +
32 + #+BEGIN_EXAMPLE erlang
33 + -include_lib("triq/include/triq.hrl").
34 + #+END_EXAMPLE
35 +
36 + Modules compiled with the =triq.hrl= header auto-export all functions
37 + named =prop_*=, and have a function added called =check/0= which runs
38 + =triq:check/1= on all the properties in the module. Further, adding
39 + the attribute =-triq(eunit)= will generate EUnit tests for all
40 + properties, turning the module into a regular EUnit test suite.
41 +
42 + If you use erlang.mk, you will typically want to use [[https://erlang.mk/guide/triq.html][the built-in Triq
43 + plugin]] to check properties. Otherwise we highly recommend letting Triq
44 + generate EUnit tests, thus arriving at a demo module like this:
45 +
46 + #+BEGIN_EXAMPLE erlang
47 + -module(triq_demo).
48 + -include_lib("triq/include/triq.hrl").
49 + -triq(eunit).
50 + prop_append() ->
51 + ?FORALL({Xs,Ys},{list(int()),list(int())},
52 + lists:reverse(Xs++Ys)
53 + ==
54 + lists:reverse(Ys) ++ lists:reverse(Xs)).
55 + #+END_EXAMPLE
56 +
57 + Now, all you have to do is run =rebar3 eunit=:
58 +
59 + #+BEGIN_EXAMPLE sh
60 + $ rebar3 eunit -v
61 + ===> Verifying dependencies...
62 + ===> Compiling triq_demo
63 + ===> Performing EUnit tests...
64 + ======================== EUnit ========================
65 + file "triq_demo.app"
66 + application 'triq_demo'
67 + triq_demo:5: append_test_ (module 'triq_demo')...[0.262 s] ok
68 + [done in 0.269 s]
69 + [done in 0.274 s]
70 + =======================================================
71 + Test passed.
72 + #+END_EXAMPLE
73 +
74 + If you use =-triq({eunit, [{runs, N}]})=, then Triq will do =N= runs for each
75 + property in the module, which is equivalent to calling =triq:check(Module, N)=.
76 + This can be useful to make Triq try more (or less) cases than the default.
77 +
78 + For advanced features, please consult the API docs.
22 79
23 80 ** Obtaining Triq
24 81 :PROPERTIES:
25 - :CUSTOM_ID: using-triq
82 + :CUSTOM_ID: obtaining-triq
26 83 :END:
27 84
28 85 *** Installation via package manager
  @@ -33,11 +90,9 @@ it is under the Apache licence.
33 90 To use =triq=, you can add it as a project dependency and let your
34 91 package manager of choice handle it:
35 92
36 - rebar.config: ={triq, "1.*"}=
37 -
38 - erlang.mk: =DEPS = triq=
39 -
40 - mix.exs: ={:triq, "~> 1.*"}=
93 + | rebar.config | ={deps, [triq]}= |
94 + | erlang.mk | =DEPS = triq= |
95 + | mix.exs | ={:triq, "~> 1.*"}= |
41 96
42 97 *** Installation from source into =$ERL_LIBS=
43 98 :PROPERTIES:
  @@ -49,10 +104,9 @@ source into your Erlang installation by adding it in one of your
49 104 =$ERL_LIBS= paths. So, it's either somewhere like
50 105 =/usr/lib/erlang/lib= or =$HOME/.erl=.
51 106
52 - You can either download a tagged release from
53 - =https://gitlab.com/triq/triq/tags= and extract that or clone the
54 - git repo =https://gitlab.com/triq/triq= in the target directory. Once
55 - that's done, cd into the directory and run =make=.
107 + You can either download a [[https://gitlab.com/triq/triq/tags][tagged release]]
108 + and extract that or clone the [[https://gitlab.com/triq/triq][git repo]] in the
109 + target directory. Once that's done, cd into the directory and run =make=.
56 110
57 111 Now, if you start =erl=, you should be able to call functions from the
58 112 =triq= module.
  @@ -63,109 +117,3 @@ Now, if you start =erl=, you should be able to call functions from the
63 117 "/usr/lib/erlang/lib/triq/ebin/triq.beam"
64 118 2>
65 119 #+END_EXAMPLE
66 -
67 - ** Writing QuickCheck properties with Triq
68 - :PROPERTIES:
69 - :CUSTOM_ID: writing-properties-with-triq
70 - :END:
71 -
72 - To write properties with =triq=, include the header file:
73 -
74 - #+BEGIN_EXAMPLE erlang
75 - -include_lib("triq/include/triq.hrl").
76 - #+END_EXAMPLE
77 -
78 - And you're ready to write property tests. An example property could be:
79 -
80 - #+BEGIN_EXAMPLE erlang
81 - prop_append() ->
82 - ?FORALL({Xs,Ys},{list(int()),list(int())},
83 - lists:reverse(Xs++Ys)
84 - ==
85 - lists:reverse(Ys) ++ lists:reverse(Xs)).
86 - #+END_EXAMPLE
87 -
88 - To test this property, run =triq:check/1=, thus:
89 -
90 - #+BEGIN_EXAMPLE
91 - 1> triq:check(prop_append()).
92 - ......................................................................
93 - ..............................
94 - Ran 100 tests
95 - true
96 - 2>
97 - #+END_EXAMPLE
98 -
99 - If the test fails, it will try to shrink the result; here is an example:
100 -
101 - #+BEGIN_EXAMPLE erlang
102 - prop_delete() ->
103 - ?FORALL(L,list(int()),
104 - ?IMPLIES(L /= [],
105 - ?FORALL(I,elements(L),
106 - ?WHENFAIL(io:format("L=~p, I=~p~n", [L,I]),
107 - not lists:member(I,lists:delete(I,L)))))).
108 - #+END_EXAMPLE
109 -
110 - Which runs like this:
111 -
112 - #+BEGIN_EXAMPLE
113 - 1> triq:check(triq_tests:prop_delete()).
114 - x....Failed!
115 - L=[4,5,5], I=5
116 -
117 - Failed after 5 tests with false
118 - Simplified:
119 - L = [0,0]
120 - I = 0
121 - false
122 - 2>
123 - #+END_EXAMPLE
124 -
125 - You can get the values used for the failing test with =counterexample=,
126 - and reuse the same test values with =check/2=:
127 -
128 - #+BEGIN_EXAMPLE
129 - 3> A = triq:counterexample(triq_tests:xprop_delete()).
130 - x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxFailed!
131 - L=[3,2,1,1,1], I=1
132 -
133 - Failed after 101 tests with false
134 - Simplified:
135 - L = [0,0]
136 - I = 0
137 - [[0,0],0]
138 - 4> A.
139 - [[0,0],0]
140 - 5> triq:check(triq_tests:xprop_delete(), A).
141 - Failed!
142 - L=[0,0], I=0
143 -
144 - Failed after 1 tests with false
145 - Simplified:
146 - L = [0,0]
147 - I = 0
148 - false
149 - 6>
150 - #+END_EXAMPLE
151 -
152 - Modules compiled with the =triq.hrl= header, auto-export all functions
153 - named =prop_*=, and have a function added called =check/0= which runs
154 - =triq:check/1= on all the properties in the module.
155 -
156 - #+BEGIN_EXAMPLE
157 - 1> mymodule:check().
158 - #+END_EXAMPLE
159 -
160 - You can also instruct =triq= to generate EUnit tests for each property
161 - which allow the module to be treated like an ordinary EUnit test
162 - suite. This is highly recommended and avoids the need for =triq= or
163 - generic =qc= support in your build/test tool of choice. To achieve
164 - that, just make sure to include the attribute =-triq(eunit).= at the
165 - top of the module. Thus, the initial =triq.hrl= include would turn
166 - into this:
167 -
168 - #+BEGIN_EXAMPLE erlang
169 - -include_lib("triq/include/triq.hrl").
170 - -triq(eunit).
171 - #+END_EXAMPLE
  @@ -1,18 +1,17 @@
1 1 {<<"name">>,<<"triq">>}.
2 - {<<"version">>,<<"1.2.0">>}.
2 + {<<"version">>,<<"1.3.0">>}.
3 3 {<<"requirements">>,#{}}.
4 4 {<<"app">>,<<"triq">>}.
5 5 {<<"precompiled">>,false}.
6 - {<<"description">>,<<"Trifork QuickCheck">>}.
6 + {<<"description">>,<<"Triq (Term Reductive Invariant Questant) QuickCheck">>}.
7 7 {<<"files">>,
8 8 [<<"src/triq.app.src">>,<<"LICENSE">>,<<"NOTICE">>,<<"README.org">>,
9 9 <<"include/triq.hrl">>,<<"include/triq_statem.hrl">>,<<"rebar.config">>,
10 10 <<"rebar.config.script">>,<<"rebar.lock">>,<<"src/triq.erl">>,
11 - <<"src/triq_app.erl">>,<<"src/triq_autoexport.erl">>,<<"src/triq_dom.erl">>,
11 + <<"src/triq_autoexport.erl">>,<<"src/triq_dom.erl">>,
12 12 <<"src/triq_expr.erl">>,<<"src/triq_fsm.erl">>,<<"src/triq_fsm_stub.erl">>,
13 - <<"src/triq_rand_compat.erl">>,<<"src/triq_reporter_stdout.erl">>,
14 - <<"src/triq_statem.erl">>,<<"src/triq_statem_fsm.erl">>,
15 - <<"src/triq_sup.erl">>]}.
13 + <<"src/triq_reporter_stdout.erl">>,<<"src/triq_rnd.erl">>,
14 + <<"src/triq_statem.erl">>,<<"src/triq_statem_fsm.erl">>]}.
16 15 {<<"licenses">>,[<<"Apache">>]}.
17 16 {<<"links">>,
18 17 [{<<"Homepage">>,<<"https://triq.gitlab.io">>},
  @@ -4,6 +4,7 @@
4 4 %% This file is part of Triq - Trifork QuickCheck
5 5 %%
6 6 %% Copyright (c) 2010 by Trifork
7 + %% Copyright 2013-2018 Triq authors
7 8 %%
8 9 %% Licensed under the Apache License, Version 2.0 (the "License");
9 10 %% you may not use this file except in compliance with the License.
  @@ -16,7 +17,6 @@
16 17 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 18 %% See the License for the specific language governing permissions and
18 19 %% limitations under the License.
19 - %%
20 20
21 21 -define(LAZY(X), DELAY(X)).
22 22 -define(DELAY(X), fun()->X end).
  @@ -4,6 +4,7 @@
4 4 %% This file is part of Triq - Trifork QuickCheck
5 5 %%
6 6 %% Copyright (c) 2011 by Trifork
7 + %% Copyright 2018 Triq authors
7 8 %%
8 9 %% Licensed under the Apache License, Version 2.0 (the "License");
9 10 %% you may not use this file except in compliance with the License.
  @@ -16,7 +17,6 @@
16 17 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 18 %% See the License for the specific language governing permissions and
18 19 %% limitations under the License.
19 - %%
20 20
21 21 -import(triq_statem,
22 22 [commands/1,
Loading more files…