|
| 1 | +module CthulhuExtTest |
| 2 | + |
| 3 | +using SnoopCompileCore, SnoopCompile |
| 4 | +using Cthulhu |
| 5 | +using Pkg |
| 6 | +using Test |
| 7 | + |
| 8 | +if !isdefined(@__MODULE__, :fake_terminal) |
| 9 | + @eval (@__MODULE__) begin |
| 10 | + Base.include(@__MODULE__, normpath(pkgdir(Cthulhu), "test", "FakeTerminals.jl")) |
| 11 | + using .FakeTerminals |
| 12 | + end |
| 13 | +end |
| 14 | + |
| 15 | +macro with_try_stderr(out, expr) |
| 16 | + quote |
| 17 | + try |
| 18 | + $(esc(expr)) |
| 19 | + catch err |
| 20 | + bt = catch_backtrace() |
| 21 | + Base.display_error(stderr, err, bt) |
| 22 | + end |
| 23 | + end |
| 24 | +end |
| 25 | + |
| 26 | +# Test functions |
| 27 | +myplus(x, y) = x + y |
| 28 | +function f(x) |
| 29 | + x < 0.25 ? 1 : |
| 30 | + x < 0.5 ? 1.0 : |
| 31 | + x < 0.75 ? 0x01 : Float16(1) |
| 32 | +end |
| 33 | +g(c) = myplus(f(c[1]), f(c[2])) |
| 34 | + |
| 35 | + |
| 36 | +@testset "Cthulhu extension" begin |
| 37 | + @testset "ascend for invalidations" begin |
| 38 | + cproj = Base.active_project() |
| 39 | + cd(joinpath(dirname(@__DIR__), "testmodules", "Invalidation")) do |
| 40 | + Pkg.activate(pwd()) |
| 41 | + Pkg.develop(path="./PkgC") |
| 42 | + Pkg.develop(path="./PkgD") |
| 43 | + Pkg.precompile() |
| 44 | + invalidations = @snoop_invalidations begin |
| 45 | + @eval begin |
| 46 | + using PkgC |
| 47 | + PkgC.nbits(::UInt8) = 8 |
| 48 | + using PkgD |
| 49 | + end |
| 50 | + end |
| 51 | + tree = only(invalidation_trees(invalidations)) |
| 52 | + sig, root = only(tree.mt_backedges) |
| 53 | + |
| 54 | + fake_terminal() do term, in, out, _ |
| 55 | + t = @async begin |
| 56 | + @with_try_stderr out ascend(term, root; interruptexc=false) |
| 57 | + end |
| 58 | + lines = String(readavailable(out)) # this gets the header |
| 59 | + lines = String(readavailable(out)) |
| 60 | + @test occursin("call_nbits", lines) |
| 61 | + @test occursin("map_nbits(::Vector{Integer})", lines) |
| 62 | + # the job of the extension is done once we've written the menu, so we can quit here |
| 63 | + write(in, 'q') |
| 64 | + wait(t) |
| 65 | + end |
| 66 | + end |
| 67 | + |
| 68 | + Pkg.activate(cproj) |
| 69 | + end |
| 70 | + |
| 71 | + @testset "ascend for inference triggers" begin |
| 72 | + tinf = @snoop_inference g([0.7, 0.8]) |
| 73 | + itrigs = inference_triggers(tinf; exclude_toplevel=false) |
| 74 | + itrig = last(itrigs) |
| 75 | + |
| 76 | + fake_terminal() do term, in, out, _ |
| 77 | + t = @async begin |
| 78 | + @with_try_stderr out ascend(term, itrig; interruptexc=false) |
| 79 | + end |
| 80 | + lines = String(readavailable(out)) # this gets the header |
| 81 | + lines = String(readavailable(out)) |
| 82 | + @test occursin("myplus(::UInt8, ::Float16)", lines) |
| 83 | + @test occursin("g(::Vector{Float64})", lines) |
| 84 | + # the job of the extension is done once we've written the menu, so we can quit here |
| 85 | + write(in, 'q') |
| 86 | + wait(t) |
| 87 | + end |
| 88 | + end |
| 89 | +end |
| 90 | + |
| 91 | +end |
0 commit comments