Skip to content

Commit 35e253c

Browse files
committed
test: expand coverage
1 parent 5d39efc commit 35e253c

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

test/test_n_arity_nodes.jl

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,3 +494,102 @@ end
494494
ex2 = Expression(+(x1, x2, x3); operators)
495495
@test string(ex2) == "+(x1, x2, x3)"
496496
end
497+
498+
@testitem "Node arbitrary-degree child access & mutation" begin
499+
using DynamicExpressions.NodeModule:
500+
Node, get_child, get_children, set_child!, set_children!
501+
using Test
502+
503+
# Build a tiny 3-ary tree: +(1, 2, 3)
504+
c1 = Node{Float64,3}(; val=1.0)
505+
c2 = Node{Float64,3}(; val=2.0)
506+
c3 = Node{Float64,3}(; val=3.0)
507+
p = Node{Float64,3}(; op=1, children=(c1, c2, c3))
508+
509+
@test p isa Node{Float64,3} # new type parameter D shows up
510+
@test get_children(p) == (c1, c2, c3)
511+
@test get_child(p, 2) === c2
512+
@test get_children(p, Val(1)) === (c1,) # Val-specialised accessor
513+
@test_throws BoundsError get_child(p, 4)
514+
515+
# Replace the 3rd child in-place
516+
new_c3 = Node{Float64,3}(; val=30.0)
517+
set_child!(p, new_c3, 3)
518+
@test get_child(p, 3) === new_c3
519+
520+
# Length mismatch is allowed; it will be poisoned at the end
521+
set_children!(p, (c1, c2))
522+
@test get_child(p, 2) === c2
523+
524+
# Poison node is just self
525+
@test get_child(p, 3) === p
526+
end
527+
528+
@testitem "Node property forwarding (`.l` / `.r`) still works" begin
529+
using DynamicExpressions.NodeModule: Node
530+
using Test
531+
532+
a = Node{Float64,2}(; val=10.0)
533+
b = Node{Float64,2}(; val=20.0)
534+
root = Node{Float64,2}(; op=1, children=(a, b))
535+
536+
@test root.l === a
537+
@test root.r === b
538+
539+
new_a = Node{Float64,2}(; val=99.0)
540+
root.l = new_a
541+
@test root.l === new_a
542+
end
543+
544+
@testitem "Constructor guards all-defaults call throws" begin
545+
using DynamicExpressions: AbstractExpressionNode
546+
using Test
547+
548+
mutable struct MyBadNode{T,D} <: AbstractExpressionNode{T,D}
549+
degree::UInt8
550+
constant::Bool
551+
val::T
552+
feature::UInt16
553+
op::UInt8
554+
children::NTuple{D,MyBadNode{T,D}}
555+
end
556+
557+
# Calling with *nothing* default should now error
558+
@test_throws "Did you forget to define" MyBadNode{Float64,3}()
559+
560+
mutable struct MyBadNode2{T,D} <: AbstractExpressionNode{T,D}
561+
degree::UInt8
562+
constant::Bool
563+
val::T
564+
feature::UInt16
565+
op::UInt8
566+
children::NTuple{D,MyBadNode2{T,D}}
567+
568+
MyBadNode2{T,D}() where {T,D} = new{T,D}()
569+
end
570+
571+
# We only need this; it will default to 2 for D anyways:
572+
node = MyBadNode2{Float64}()
573+
@test typeof(node) <: MyBadNode2{Float64,2}
574+
end
575+
576+
@testitem "branch_copy_into! copies generic children" begin
577+
using DynamicExpressions.NodeModule: Node, get_children
578+
using DynamicExpressions.NodePreallocationModule: branch_copy_into!
579+
using Test
580+
581+
operators = OperatorEnum(2 => (+, -, *))
582+
leaves = ntuple(i -> Node{Float64,3}(; val=i), 3)
583+
src = Node{Float64,3}(; op=1, children=leaves)
584+
dummy = Node{Float64,3}(;
585+
op=2,
586+
children=(
587+
Node{Float64,3}(; val=0), Node{Float64,3}(; val=0), Node{Float64,3}(; val=0)
588+
),
589+
)
590+
591+
branch_copy_into!(dummy, src, get_children(src)...)
592+
593+
@test dummy.op == src.op
594+
@test get_children(dummy) == get_children(src)
595+
end

0 commit comments

Comments
 (0)