Skip to content

Commit 8433123

Browse files
committed
move tests to syntax.jl
1 parent a3965bc commit 8433123

File tree

2 files changed

+126
-124
lines changed

2 files changed

+126
-124
lines changed

test/loading.jl

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -63,88 +63,6 @@ let exename = `$(Base.julia_cmd()) --compiled-modules=yes --startup-file=no --co
6363
@test !endswith(s_dir, Base.Filesystem.path_separator)
6464
end
6565

66-
@testset "Tests for @__FUNCTION__" begin
67-
let
68-
@testset "Basic usage" begin
69-
test_function_basic() = @__FUNCTION__
70-
@test test_function_basic() === test_function_basic
71-
end
72-
73-
@testset "Factorial function" begin
74-
factorial_function(n) = n <= 1 ? 1 : n * (@__FUNCTION__)(n - 1)
75-
@test factorial_function(5) == 120
76-
end
77-
78-
@testset "Prevents boxed closures" begin
79-
function make_closure()
80-
fib(n) = n <= 1 ? 1 : (@__FUNCTION__)(n - 1) + (@__FUNCTION__)(n - 2)
81-
return fib
82-
end
83-
Test.@inferred make_closure()
84-
closure = make_closure()
85-
@test closure(5) == 8
86-
Test.@inferred closure(5)
87-
end
88-
89-
@testset "Complex closure of closures" begin
90-
function f1()
91-
function f2()
92-
function f3()
93-
return @__FUNCTION__
94-
end
95-
return (@__FUNCTION__), f3()
96-
end
97-
return (@__FUNCTION__), f2()...
98-
end
99-
Test.@inferred f1()
100-
@test f1()[1] === f1
101-
@test f1()[2] !== f1
102-
@test f1()[3] !== f1
103-
@test f1()[3]() === f1()[3]
104-
@test f1()[2]()[2]() === f1()[3]
105-
end
106-
107-
@testset "Anonymous function" begin
108-
@test (n -> n <= 1 ? 1 : n * (@__FUNCTION__)(n - 1))(5) == 120
109-
end
110-
111-
@testset "Do block" begin
112-
function test_do_block()
113-
result = map([1, 2, 3]) do x
114-
return (@__FUNCTION__, x)
115-
end
116-
# All should refer to the same do-block function
117-
@test all(r -> r[1] === result[1][1], result)
118-
# Values should be different
119-
@test [r[2] for r in result] == [1, 2, 3]
120-
# It should be different than `test_do_block`
121-
@test result[1][1] !== test_do_block
122-
end
123-
test_do_block()
124-
end
125-
126-
@testset "Compatibility with kwargs" begin
127-
foo(; n) = n <= 1 ? 1 : n * (@__FUNCTION__)(; n = n - 1)
128-
@test foo(n = 5) == 120
129-
end
130-
131-
@testset "Error upon misuse" begin
132-
@gensym A
133-
@test_throws ErrorException @eval(module $A; @__FUNCTION__; end)
134-
end
135-
136-
@testset "Callable structs" begin
137-
@gensym A
138-
@eval module $A
139-
struct CallableStruct{T}; val::T; end
140-
(c::CallableStruct)() = @__FUNCTION__
141-
end
142-
@eval using .$A: CallableStruct
143-
c = CallableStruct(5)
144-
@test c() === c
145-
end
146-
end
147-
end
14866

14967
@test Base.in_sysimage(Base.PkgId(Base.UUID("8f399da3-3557-5675-b5ff-fb832c97cbdb"), "Libdl"))
15068
@test Base.in_sysimage(Base.PkgId(Base.UUID("3a7fdc7e-7467-41b4-9f64-ea033d046d5b"), "NotAPackage")) == false

test/syntax.jl

Lines changed: 126 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4355,62 +4355,146 @@ let f = NoSpecClosure.K(1)
43554355
@test typeof(f).parameters == Core.svec()
43564356
end
43574357

4358-
@testset "Expr(:thisfunction)" begin
4359-
# regular functions can use Expr(:thisfunction) to refer to the function itself
4360-
@eval regular_func() = $(Expr(:thisfunction))
4361-
@test regular_func() === regular_func
4362-
4363-
# This also works in callable structs, which refers to the instance
4364-
struct CallableStruct
4365-
value::Int
4358+
@testset "@__FUNCTION__ and Expr(:thisfunction)" begin
4359+
@testset "Basic usage" begin
4360+
# @__FUNCTION__ in regular functions
4361+
test_function_basic() = @__FUNCTION__
4362+
@test test_function_basic() === test_function_basic
4363+
4364+
# Expr(:thisfunction) in regular functions
4365+
@eval regular_func() = $(Expr(:thisfunction))
4366+
@test regular_func() === regular_func
43664367
end
4367-
@eval (obj::CallableStruct)() = $(Expr(:thisfunction))
4368-
@eval (obj::CallableStruct)(x) = $(Expr(:thisfunction)).value + x
43694368

4370-
let cs = CallableStruct(42)
4371-
@test cs() === cs
4372-
@test cs(10) === 52
4369+
@testset "Recursion" begin
4370+
# Factorial with @__FUNCTION__
4371+
factorial_function(n) = n <= 1 ? 1 : n * (@__FUNCTION__)(n - 1)
4372+
@test factorial_function(5) == 120
4373+
4374+
# Fibonacci with Expr(:thisfunction)
4375+
struct RecursiveCallableStruct; end
4376+
@eval (::RecursiveCallableStruct)(n) = n <= 1 ? n : $(Expr(:thisfunction))(n-1) + $(Expr(:thisfunction))(n-2)
4377+
@test RecursiveCallableStruct()(10) === 55
4378+
4379+
# Anonymous function recursion
4380+
@test (n -> n <= 1 ? 1 : n * (@__FUNCTION__)(n - 1))(5) == 120
43734381
end
43744382

4375-
struct RecursiveCallableStruct; end
4376-
@eval (::RecursiveCallableStruct)(n) = n <= 1 ? n : $(Expr(:thisfunction))(n-1) + $(Expr(:thisfunction))(n-2)
4377-
4378-
@test RecursiveCallableStruct()(10) === 55
4383+
@testset "Closures and nested functions" begin
4384+
# Prevents boxed closures
4385+
function make_closure()
4386+
fib(n) = n <= 1 ? 1 : (@__FUNCTION__)(n - 1) + (@__FUNCTION__)(n - 2)
4387+
return fib
4388+
end
4389+
Test.@inferred make_closure()
4390+
closure = make_closure()
4391+
@test closure(5) == 8
4392+
Test.@inferred closure(5)
4393+
4394+
# Complex closure of closures
4395+
function f1()
4396+
function f2()
4397+
function f3()
4398+
return @__FUNCTION__
4399+
end
4400+
return (@__FUNCTION__), f3()
4401+
end
4402+
return (@__FUNCTION__), f2()...
4403+
end
4404+
Test.@inferred f1()
4405+
@test f1()[1] === f1
4406+
@test f1()[2] !== f1
4407+
@test f1()[3] !== f1
4408+
@test f1()[3]() === f1()[3]
4409+
@test f1()[2]()[2]() === f1()[3]
4410+
4411+
# In closures, var"#self#" should refer to the enclosing function,
4412+
# NOT the enclosing struct instance
4413+
struct CallableStruct2; end
4414+
@eval function (obj::CallableStruct2)()
4415+
function inner_func()
4416+
$(Expr(:thisfunction))
4417+
end
4418+
inner_func
4419+
end
43794420

4380-
# In closures, var"#self#" should refer to the enclosing function,
4381-
# NOT the enclosing struct instance
4382-
struct CallableStruct2; end
4383-
@eval function (obj::CallableStruct2)()
4384-
function inner_func()
4385-
$(Expr(:thisfunction))
4421+
let cs = CallableStruct2()
4422+
@test cs()() === cs()
4423+
@test cs()() !== cs
43864424
end
4387-
inner_func
43884425
end
43894426

4390-
let cs = CallableStruct2()
4391-
@test cs()() === cs()
4392-
@test cs()() !== cs
4427+
@testset "Do blocks" begin
4428+
function test_do_block()
4429+
result = map([1, 2, 3]) do x
4430+
return (@__FUNCTION__, x)
4431+
end
4432+
# All should refer to the same do-block function
4433+
@test all(r -> r[1] === result[1][1], result)
4434+
# Values should be different
4435+
@test [r[2] for r in result] == [1, 2, 3]
4436+
# It should be different than `test_do_block`
4437+
@test result[1][1] !== test_do_block
4438+
end
4439+
test_do_block()
43934440
end
43944441

4395-
# Keywords
4396-
let
4397-
@eval f2(; n=1) = n <= 1 ? n : n * $(Expr(:thisfunction))(; n=n-1)
4398-
result = f2(n=5)
4399-
@test result == 120
4442+
@testset "Keyword arguments" begin
4443+
# @__FUNCTION__ with kwargs
4444+
foo(; n) = n <= 1 ? 1 : n * (@__FUNCTION__)(; n = n - 1)
4445+
@test foo(n = 5) == 120
4446+
4447+
# Expr(:thisfunction) with kwargs
4448+
let
4449+
@eval f2(; n=1) = n <= 1 ? n : n * $(Expr(:thisfunction))(; n=n-1)
4450+
result = f2(n=5)
4451+
@test result == 120
4452+
end
44004453
end
44014454

4402-
# Struct constructor with thisfunction
4403-
let
4404-
@eval struct Cols{T<:Tuple}
4405-
cols::T
4406-
operator
4407-
Cols(args...; operator=union) = (new{typeof(args)}(args, operator); string($(Expr(:thisfunction))))
4455+
@testset "Callable structs" begin
4456+
# @__FUNCTION__ in callable structs
4457+
@gensym A
4458+
@eval module $A
4459+
struct CallableStruct{T}; val::T; end
4460+
(c::CallableStruct)() = @__FUNCTION__
4461+
end
4462+
@eval using .$A: CallableStruct
4463+
c = CallableStruct(5)
4464+
@test c() === c
4465+
4466+
# Expr(:thisfunction) in callable structs
4467+
struct CallableStruct3
4468+
value::Int
4469+
end
4470+
@eval (obj::CallableStruct3)() = $(Expr(:thisfunction))
4471+
@eval (obj::CallableStruct3)(x) = $(Expr(:thisfunction)).value + x
4472+
4473+
let cs = CallableStruct3(42)
4474+
@test cs() === cs
4475+
@test cs(10) === 52
44084476
end
4409-
result = Cols(1, 2, 3)
4410-
@test occursin("Cols", result)
44114477
end
44124478

4413-
let @generated foo() = Expr(:thisfunction)
4414-
@test foo() === foo
4479+
@testset "Special cases" begin
4480+
# Generated functions
4481+
let @generated foo() = Expr(:thisfunction)
4482+
@test foo() === foo
4483+
end
4484+
4485+
# Struct constructor with thisfunction
4486+
let
4487+
@eval struct Cols{T<:Tuple}
4488+
cols::T
4489+
operator
4490+
Cols(args...; operator=union) = (new{typeof(args)}(args, operator); string($(Expr(:thisfunction))))
4491+
end
4492+
result = Cols(1, 2, 3)
4493+
@test occursin("Cols", result)
4494+
end
4495+
4496+
# Error upon misuse
4497+
@gensym B
4498+
@test_throws ErrorException @eval(module $B; @__FUNCTION__; end)
44154499
end
44164500
end

0 commit comments

Comments
 (0)