From 866ac9fb72639aa6d121735c79c4260f493544f4 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Mon, 19 Oct 2015 17:53:17 -0400 Subject: [PATCH] working on test framework --- docs/example_generation.jl | 14 ++---- src/utils.jl | 28 ++++++++---- test/imgcomp.jl | 94 ++++++++++++++++++++++++++------------ 3 files changed, 89 insertions(+), 47 deletions(-) diff --git a/docs/example_generation.jl b/docs/example_generation.jl index 283738ad..766b39d6 100644 --- a/docs/example_generation.jl +++ b/docs/example_generation.jl @@ -18,21 +18,13 @@ type PlotExample end -function fakedata(sz...) - y = zeros(sz...) - for r in 2:size(y,1) - y[r,:] = 0.9 * y[r-1,:] + randn(size(y,2))' - end - y -end - # the examples we'll run for each const examples = PlotExample[ PlotExample("Lines", "A simple line plot of the columns.", [ - :(plot(fakedata(50,5), w=3)) + :(plot(Plots.fakedata(50,5), w=3)) ]), PlotExample("Functions, adding data, and animations", "Plot multiple functions. You can also put the function first, or use the form `plot(f, xmin, xmax)` where f is a Function or AbstractVector{Function}.\n\nGet series data: `x, y = plt[i]`. Set series data: `plt[i] = (x,y)`. Add to the series with `push!`/`append!`.\n\nEasily build animations. (`convert` or `ffmpeg` must be available to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the animation.", @@ -134,12 +126,12 @@ const examples = PlotExample[ PlotExample("Adding to subplots", "Note here the automatic grid layout, as well as the order in which new series are added to the plots.", [ - :(subplot(fakedata(100,10), n=4, palette=[:grays :blues :heat :lightrainbow], bg=[:orange :pink :darkblue :black])) + :(subplot(Plots.fakedata(100,10), n=4, palette=[:grays :blues :heat :lightrainbow], bg=[:orange :pink :darkblue :black])) ]), PlotExample("", "", [ - :(subplot!(fakedata(100,10))) + :(subplot!(Plots.fakedata(100,10))) ]), PlotExample("Open/High/Low/Close", "Create an OHLC chart. Pass in a vector of OHLC objects as your `y` argument. Adjust the tick width with arg `markersize`.", diff --git a/src/utils.jl b/src/utils.jl index 39be1a5c..bccf86ba 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -104,6 +104,18 @@ function sticksHack(; kw...) dLine, dScatter end +function regressionXY(x, y) + # regress + β, α = [x ones(length(x))] \ y + + # make a line segment + regx = [minimum(x), maximum(x)] + regy = β * regx + α + regx, regy +end + +# ------------------------------------------------------------------------------------ + get_mod(v, idx::Int) = v[mod1(idx, length(v))] makevec(v::AVec) = v @@ -162,16 +174,16 @@ Base.first(c::Colorant) = c sortedkeys(d::Dict) = sort(collect(keys(d))) -function regressionXY(x, y) - # regress - β, α = [x ones(length(x))] \ y - - # make a line segment - regx = [minimum(x), maximum(x)] - regy = β * regx + α - regx, regy +function fakedata(sz...) + y = zeros(sz...) + for r in 2:size(y,1) + y[r,:] = 0.9 * y[r-1,:] + randn(size(y,2))' + end + y end + + # ticksType{T<:Real,S<:Real}(ticks::@compat(Tuple{T,S})) = :limits ticksType{T<:Real}(ticks::AVec{T}) = :ticks ticksType{T<:AVec,S<:AVec}(ticks::@compat(Tuple{T,S})) = :ticks_and_labels diff --git a/test/imgcomp.jl b/test/imgcomp.jl index f9afbbc0..9156f458 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -16,48 +16,75 @@ include("../docs/example_generation.jl") # plt # end -using Plots, Gtk.ShortNames +using Plots +import Images, Gtk, ImageMagick function makeImageWidget(fn) - img = @Image(fn) - vbox = @Box(:v) + img = Gtk.GtkImageLeaf(fn) + vbox = Gtk.GtkBoxLeaf(:v) + push!(vbox, Gtk.GtkLabelLeaf(fn)) push!(vbox, img) show(img) vbox end +function replaceReferenceImage(tmpfn, reffn) + println("cp $tmpfn $reffn") +end + "Show a Gtk popup with both images and a confirmation whether we should replace the new image with the old one" -function isTempImageCorrect(tmpfn, reffn) +function compareToReferenceImage(tmpfn, reffn) # add the images - imgbox = @Box(:h) + imgbox = Gtk.GtkBoxLeaf(:h) push!(imgbox, makeImageWidget(tmpfn)) push!(imgbox, makeImageWidget(reffn)) # add the buttons - keepbtn = @Button("KEEP") - overwritebtn = @Button("OVERWRITE") - btnbox = @Box(:h) - push!(btnbox, keepbtn) - push!(btnbox, overwritebtn) + doNothingButton = Gtk.GtkButtonLeaf("Skip") + replaceReferenceButton = Gtk.GtkButtonLeaf("Replace reference image") + btnbox = Gtk.GtkButtonBoxLeaf(:h) + push!(btnbox, doNothingButton) + push!(btnbox, replaceReferenceButton) # create the window - box = @Box(:v) + box = Gtk.GtkBoxLeaf(:v) push!(box, imgbox) push!(box, btnbox) - w = @Window(@Frame(box)) - showall(w) - w + win = Gtk.GtkWindowLeaf(Gtk.GtkFrameLeaf(box)) + + # we'll wait on this condition + c = Condition() + Gtk.on_signal_destroy((x...) -> notify(c), win) + + Gtk.signal_connect(replaceReferenceButton, "clicked") do widget + replaceReferenceImage(tmpfn, reffn) + notify(c) + end + + Gtk.signal_connect(doNothingButton, "clicked") do widget + notify(c) + end + + # wait until a button is clicked, then close the window + Gtk.showall(win) + wait(c) + Gtk.destroy(win) end +# TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that +# is referenced in a button press callback (the button clicked callback will call notify() on that condition) + function image_comparison_tests(pkg::Symbol, idx::Int; debug = true, sigma = [0,0], eps = 1e-3) # first Plots._debugMode.on = debug - info("Testing plot: $pkg:$idx:$(examples[idx].header)") + info("Testing plot: $pkg:$idx:$(PlotExamples.examples[idx].header)") backend(pkg) backend() + + info("here: ", PlotExamples.examples[idx].exprs) map(eval, PlotExamples.examples[idx].exprs) # save the png @@ -65,31 +92,42 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = true, sigma = [0, png(tmpfn) # load the saved png - tmpimg = imread(tmpfn) + tmpimg = Images.load(tmpfn) - # load the reference image - reffn = joinpath(Pkg.dir("Plots"), "test", "refimg", pkg, "$idx.png") - refimg = imread(reffn) + # reference image location + refdir = joinpath(Pkg.dir("Plots"), "test", "refimg", "v$(VERSION.major).$(VERSION.minor)", string(pkg)) + try + mkdir(refdir) + catch err + display(err) + end + reffn = joinpath(refdir, "ref$idx.png") - # run the test - # NOTE: sigma is a 2-length vector with x/y values for the number of pixels - # to blur together when comparing images try + info("Comparing $tmpfn to reference $reffn") + + # load the reference image + refimg = Images.load(reffn) + # run the comparison test... a difference will throw an error - @test_approx_eq_sigma_eps(tmpimg, refimg, sigma, eps) + # NOTE: sigma is a 2-length vector with x/y values for the number of pixels + # to blur together when comparing images + Images.@test_approx_eq_sigma_eps(tmpimg, refimg, sigma, eps) catch ex if isinteractive() # if we're in interactive mode, open a popup and give us a chance to examine the images - if isTempImageCorrect(tmpfn, reffn) - return - end + compareToReferenceImage(tmpfn, reffn) + return + + else + + # if we rejected the image, or if we're in automated tests, throw the error + rethrow(ex) end - # if we rejected the image, or if we're in automated tests, throw the error - throw(ex) end end