diff --git a/NEWS.md b/NEWS.md index c8d88f1..d157fd6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # NEWS +## v0.2.4 + +* CHANGE: `=>` has been deprecated, use `-->` instead + ## v0.2.3 * CHANGE: Added Compat.jl to address Julia 0.4 deprecations. diff --git a/README.md b/README.md index 362820d..fc37d2e 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ end As for the tests themselves, you can use `FactCheck` to do basic assertions like you would with `Base.Test` using `@fact` and `@fact_throws`: ```julia facts("Testing basics") do - @fact 1 => 1 - @fact 2*2 => 4 - @fact uppercase("foo") => "FOO" + @fact 1 --> 1 + @fact 2*2 --> 4 + @fact uppercase("foo") --> "FOO" @fact_throws 2^-1 @fact_throws DomainError 2^-1 @fact_throws DomainError 2^-1 "a nifty message" - @fact 2*[1,2,3] => [2,4,6] + @fact 2*[1,2,3] --> [2,4,6] end ``` @@ -60,7 +60,7 @@ facts("Messages") do x = [1, 2, 3, 4] y = [4, 2, 3, 1] for i in 1:4 - @fact x[i] => y[i] "mismatch at i=$i" + @fact x[i] --> y[i] "mismatch at i=$i" end end ``` @@ -75,8 +75,8 @@ produces Finally, if you have an idea for a test you want to implement but haven't yet, you can using `@pending`. `@pending` doesn't attempt to check its assertion, or even evaluate the expression, it simply records that a pending test exists. ```julia facts("Some pending") do - @fact 2*3 => 6 - @pending divide(2,3) => :something + @fact 2*3 --> 6 + @pending divide(2,3) --> :something end ``` produces @@ -89,18 +89,18 @@ Out of 2 total facts: ### Assertions -A `FactCheck` `=>` is more general than the `==` of `Base.Test.@test`. -We refer to the value to the left of the `=>` as the *expression*, and the value to the right of as the *assertion*. +A `FactCheck` `-->` is more general than the `==` of `Base.Test.@test`. +We refer to the value to the left of the `-->` as the *expression*, and the value to the right of as the *assertion*. If the assertion is a literal value, like `1`, `"FOO"`, or `[2,4,6]`, then `@fact` checks if the expression is equal to the assertion. However if the assertion is a *function*, then function will be applied to the expression, e.g. ```julia -@fact 2 => iseven +@fact 2 --> iseven #...is equivalent to... -@fact iseven(2) => true +@fact iseven(2) --> true -@fact Int[] => isempty +@fact Int[] --> isempty #..is equivalent to... -@fact isempty(Int[]) => true +@fact isempty(Int[]) --> true ``` `FactCheck` provides several helper functions to make more complicated assertions: @@ -108,26 +108,26 @@ However if the assertion is a *function*, then function will be applied to the e #### `not` Logical not for literal values and functions. ```julia -@fact 1 => not(2) +@fact 1 --> not(2) # is equivalent to -@fact (1 != 2) => true +@fact (1 != 2) --> true -@fact 1 => not(iseven) +@fact 1 --> not(iseven) # is equivalent to -@fact !iseven(1) => true +@fact !iseven(1) --> true ``` #### `anything` Anything but `nothing`. ```julia -@fact sin(π) => anything +@fact sin(π) --> anything ``` #### `truthy`, `falsy`, `falsey` To be truthy is to be not `nothing`, false, or 0. To be falsy (or falsey) is to be not truthy. ```julia -@fact 1 => truthy -@fact nothing => falsey +@fact 1 --> truthy +@fact nothing --> falsey ``` #### `exactly` @@ -135,18 +135,18 @@ Test equality in the same way that `Base.is`/`Base.===` do. For example, two dis ```julia a = [1,2,3] b = [1,2,3] -@fact a => b -@fact a => not(exactly(b)) +@fact a --> b +@fact a --> not(exactly(b)) ``` #### `roughly` Test approximate equality of numbers and arrays of numbers using `Base.isapprox`, and accepts same keyword arguments as that function. If a second argument is provided, but no keyword, it is treated as `atol`. ```julia -@fact 2 + 1e-5 => roughly(2.0) -@fact 9.5 => roughly(10; atol=1.0) +@fact 2 + 1e-5 --> roughly(2.0) +@fact 9.5 --> roughly(10; atol=1.0) A = [2.0, 3.0] B = (1 + 1e-6)*A -@fact A => roughly(B) +@fact A --> roughly(B) ``` #### `less_than`/ @@ -155,17 +155,17 @@ B = (1 + 1e-6)*A #### `greater_than_or_equal` Test inequality relationships between numbers. ```julia -@fact 1 => less_than(2) -@fact 1 => less_than_or_equal(1) -@fact 2 => greater_than(1) -@fact 2 => greater_than_or_equal(2) +@fact 1 --> less_than(2) +@fact 1 --> less_than_or_equal(1) +@fact 2 --> greater_than(1) +@fact 2 --> greater_than_or_equal(2) ``` #### `anyof` Test equality with any of the arguments to `anyof` ```julia -@fact 2+2 => anyof(4, :four, "four") -@fact 5 => not(anyof(:five, "five")) +@fact 2+2 --> anyof(4, :four, "four") +@fact 5 --> not(anyof(:five, "five")) ``` ### Exit status @@ -188,18 +188,18 @@ is `:default`, and the other option currently is `:compact`. To see the differen ```julia FactCheck.setstyle(:compact) facts("Compact vs default") do - @fact 1 => 1 - @fact 2 => 3 - @fact 3 => 3 - @fact 4 => 4 - @fact 5 => 5 + @fact 1 --> 1 + @fact 2 --> 3 + @fact 3 --> 3 + @fact 4 --> 4 + @fact 5 --> 5 end ``` which produces the output ``` Compact vs default: .F... Failure :: (line:274) :: got 2 - 2 => 3 + 2 --> 3 ``` The main difference is that single characters only are emitted as the tests run, with all errors only being displayed at the end. diff --git a/src/FactCheck.jl b/src/FactCheck.jl index b52a855..88e8c98 100644 --- a/src/FactCheck.jl +++ b/src/FactCheck.jl @@ -81,10 +81,10 @@ allresults = Result[] clear_results() = (global allresults; allresults = Result[]) # Formats a FactCheck assertion -# e.g. :(fn(1) => 2) to `fn(1) => 2` +# e.g. :(fn(1) --> 2) to `fn(1) --> 2` function format_assertion(ex::Expr) x, y = ex.args - "$x => $y" + "$x --> $y" end # Builds string with line and context annotations, if available @@ -195,7 +195,12 @@ end # * converts it to a function that returns tuple (success, assertval) # * processes and stores result of test [do_fact] macro fact(factex::Expr, args...) - factex.head != :(=>) && error("Incorrect usage of @fact: $factex") + if factex.head == :(=>) + Base.warn_once("the `=>` syntax is deprecated, use `-->` instead") + elseif factex.head == :(-->) + else + error("Incorrect usage of @fact: $factex") + end expr, assertion = factex.args msg = length(args) > 0 ? args[1] : :nothing diff --git a/test/runtests.jl b/test/runtests.jl index 6145912..f911262 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,10 +18,10 @@ using Compat # Error cases, which wouldn't be tested otherwise. print_with_color(:blue,"Testing Result counting and printing, not actual errors!\n") facts("Test error pathways") do - a_success = @fact 1 => 1 "I will never be seen" + a_success = @fact 1 --> 1 "I will never be seen" println(a_success) - a_failure = @fact 1 => 2 "one doesn't equal two!" - a_error = @fact 2^-1 => 0.5 "domains are tricky" + a_failure = @fact 1 --> 2 "one doesn't equal two!" + a_error = @fact 2^-1 --> 0.5 "domains are tricky" a_pending = @pending not_really_pending() "sorta pending" println(a_pending) end @@ -46,8 +46,8 @@ type MyError <: Exception end facts("Testing core functionality") do - @fact 1 => 1 - @fact 2*2 => 4 + @fact 1 --> 1 + @fact 2*2 --> 4 @fact uppercase("foo") => "FOO" @fact_throws 2^-1 @fact_throws 2^-1 "a domain error happend" @@ -55,8 +55,8 @@ facts("Testing core functionality") do @fact_throws DomainError 2^-1 "a domain error happened" @fact_throws MyError throw(MyError()) @fact_throws MyError throw(MyError()) "my error happend" - @fact 2*[1,2,3] => [2,4,6] - @fact Foo(1) => Foo(1) + @fact 2*[1,2,3] --> [2,4,6] + @fact Foo(1) --> Foo(1) end facts("Testing invalid @fact_throws macro") do @@ -67,41 +67,41 @@ end facts("Testing 'context'") do # FactCheck.LEVEL starts from 1 - @fact FactCheck.LEVEL => 1 + @fact FactCheck.LEVEL --> 1 context("context will increase LEVEL and set contexts") do - @fact FactCheck.LEVEL => 2 + @fact FactCheck.LEVEL --> 2 @fact FactCheck.contexts[end] => "context will increase LEVEL and set contexts" end - @fact FactCheck.LEVEL => 1 + @fact FactCheck.LEVEL --> 1 # context is called without 'desc' won't increase LEVEL context() do - @fact FactCheck.LEVEL => 1 + @fact FactCheck.LEVEL --> 1 end context("nested context") do - @fact FactCheck.LEVEL => 2 - @fact FactCheck.contexts[end] => "nested context" + @fact FactCheck.LEVEL --> 2 + @fact FactCheck.contexts[end] --> "nested context" context("inner") do - @fact FactCheck.LEVEL => 3 - @fact FactCheck.contexts[end] => "inner" + @fact FactCheck.LEVEL --> 3 + @fact FactCheck.contexts[end] --> "inner" end end facts("'facts' doesn't increase LEVEL") do - @fact FactCheck.LEVEL => 1 + @fact FactCheck.LEVEL --> 1 end context("will execute the function which is passed to the 'context'") do executed = false f() = (executed = true) - @fact executed => false + @fact executed --> false context(f) - @fact executed => true + @fact executed --> true end context("indent by current LEVEL") do @@ -117,7 +117,7 @@ facts("Testing 'context'") do # current LEVEL is 3 expected_str = " - intended\n" # " " ^ 3 * " - " * "intended\n" - @fact system_output => (VERSION >= v"0.4-dev" ? + @fact system_output --> (VERSION >= v"0.4-dev" ? expected_str.data : expected_str) end end @@ -127,84 +127,83 @@ facts("FactCheck assertion helper functions") do context("`not` works for values and functions") do notone = not(1) - @fact notone(2) => true - @fact notone(1) => false - @fact 2 => not(1) + @fact notone(2) --> true + @fact notone(1) --> false + @fact 2 --> not(1) noteven = not(iseven) - @fact noteven(3) => true - @fact noteven(2) => false - @fact not(iseven)(2) => false - @fact 3 => not(iseven) + @fact noteven(3) --> true + @fact noteven(2) --> false + @fact not(iseven)(2) --> false + @fact 3 --> not(iseven) end context("`truthy` is anything other than nothing or false (which is 0)") do - @fact truthy(-1) => true - @fact truthy("") => true - @fact truthy([]) => true - @fact truthy(Dict()) => true - @fact truthy(nothing) => false - @fact truthy(false) => false - @fact truthy(0) => false + @fact truthy(-1) --> true + @fact truthy("") --> true + @fact truthy([]) --> true + @fact truthy(Dict()) --> true + @fact truthy(nothing) --> false + @fact truthy(false) --> false + @fact truthy(0) --> false end context("`anything` is always true") do - @fact anything(false) => true + @fact anything(false) --> true end context("`exactly` can be used to check object equality") do - @fact exactly(exactly)(exactly) => true + @fact exactly(exactly)(exactly) --> true x() = () - @fact exactly(x)(x) => true + @fact exactly(x)(x) --> true # types with no fields return a singleton object when instantiated - @fact exactly(Baz())(Baz()) => true + @fact exactly(Baz())(Baz()) --> true - @fact exactly(Bazz(1))(Bazz(1)) => false + @fact exactly(Bazz(1))(Bazz(1)) --> false end context("`roughly` compares numbers... roughly") do - @fact 2.4999999999999 => roughly(2.5) - @fact 9.5 => roughly(10; atol=1.0) - @fact 10.5 => roughly(10; atol=1.0) - @fact 10.5 => roughly(10, 1.0) + @fact 2.4999999999999 --> roughly(2.5) + @fact 9.5 --> roughly(10; atol=1.0) + @fact 10.5 --> roughly(10; atol=1.0) + @fact 10.5 --> roughly(10, 1.0) end context("`roughly` compares matrixes... roughly") do X = [1.1 1.2; 2.1 2.2] Y = X + [0 0.000001; -0.00000349 0.00001] Z = [1 1; 2 2] - @fact X => roughly(Y) - @fact X => roughly(Z; atol=0.2) - @fact X => roughly(Z, 0.2) + @fact X --> roughly(Y) + @fact X --> roughly(Z; atol=0.2) + @fact X --> roughly(Z, 0.2) end context("`anyof` compares with all arguments") do - @fact 2+2 => anyof(4, :four, "four") - @fact 5 => not(anyof(:five, "five")) + @fact 2+2 --> anyof(4, :four, "four") + @fact 5 --> not(anyof(:five, "five")) end context("less_than") do - @fact 1 => less_than(2) + @fact 1 --> less_than(2) end context("less_than_or_equal") do - @fact 1 => less_than_or_equal(2) - @fact 1 => less_than_or_equal(1) + @fact 1 --> less_than_or_equal(2) + @fact 1 --> less_than_or_equal(1) end context("greater_than") do - @fact 2 => greater_than(1) + @fact 2 --> greater_than(1) end context("greater_than_or_equal") do - @fact 2 => greater_than_or_equal(1) - @fact 2 => greater_than_or_equal(2) + @fact 2 --> greater_than_or_equal(1) + @fact 2 --> greater_than_or_equal(2) end end exitstatus() end # module -