Skip to content

Commit

Permalink
Improve test coverage (#3870)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Nov 5, 2024
1 parent 6768f9b commit da8a667
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 20 deletions.
7 changes: 3 additions & 4 deletions src/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,10 @@ function constraint_by_name end

function constraint_by_name(model::GenericModel, name::String)
index = MOI.get(backend(model), MOI.ConstraintIndex, name)
if index isa Nothing
if index === nothing
return nothing
else
return constraint_ref_with_index(model, index)
end
return constraint_ref_with_index(model, index)
end

function constraint_by_name(
Expand All @@ -479,7 +478,7 @@ function constraint_by_name(
::Type{S},
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
index = MOI.get(backend(model), MOI.ConstraintIndex{F,S}, name)
if index isa Nothing
if index === nothing
return nothing
end
return constraint_ref_with_index(model, index)
Expand Down
6 changes: 2 additions & 4 deletions src/nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -632,15 +632,13 @@ function jump_function(model::GenericModel, expr::MOI.Nonlinear.Expression)
)
elseif node.type == MOI.Nonlinear.NODE_MOI_VARIABLE
V(model, MOI.VariableIndex(node.index))
elseif node.type == MOI.Nonlinear.NODE_PARAMETER
NonlinearParameter(model, node.index)
elseif node.type == MOI.Nonlinear.NODE_SUBEXPRESSION
NonlinearExpression(model, node.index)
elseif node.type == MOI.Nonlinear.NODE_VALUE
expr.values[node.index]
else
# node.type == MOI.Nonlinear.NODE_COMPARISON
# node.type == MOI.Nonlinear.NODE_LOGIC
# node.type == MOI.Nonlinear.NODE_PARAMETER
# node.type == MOI.Nonlinear.NODE_SUBEXPRESSION
error("Unsupported node")
end
end
Expand Down
11 changes: 8 additions & 3 deletions src/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,15 @@ Base.transpose(x::AbstractJuMPScalar) = x
Base.conj(x::GenericVariableRef) = x
# Can remove the following code once == overloading is removed

function LinearAlgebra.issymmetric(x::Matrix{T}) where {T<:_JuMPTypes}
(n = size(x, 1)) == size(x, 2) || return false
function LinearAlgebra.issymmetric(x::Matrix{<:_JuMPTypes})
n = size(x, 1)
if n != size(x, 2)
return false
end
for i in 1:n, j in (i+1):n
isequal(x[i, j], x[j, i]) || return false
if !isequal(x[i, j], x[j, i])
return false
end
end
return true
end
Expand Down
18 changes: 16 additions & 2 deletions test/test_constraint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ function _test_constraint_name_util(ModelType, VariableRefType)
MOI.EqualTo{Float64},
)
set_name(con, "kon")
@test constraint_by_name(model, "con") isa Nothing
@test constraint_by_name(model, "con") === nothing
_test_constraint_name_util(
con,
"kon",
Expand All @@ -646,7 +646,7 @@ function _test_constraint_name_util(ModelType, VariableRefType)
)
set_name(con, "con")
@test_throws err("con") constraint_by_name(model, "con")
@test constraint_by_name(model, "kon") isa Nothing
@test constraint_by_name(model, "kon") === nothing
set_name(kon, "kon")
_test_constraint_name_util(
con,
Expand Down Expand Up @@ -2157,4 +2157,18 @@ function test_hermitian_shape()
return
end

function test_constraint_by_name()
model = Model()
@variable(model, x)
@constraint(model, c, 2x <= 1)
@test constraint_by_name(model, "c") === c
@test constraint_by_name(model, "d") === nothing
F, S1, S2 = AffExpr, MOI.LessThan{Float64}, MOI.GreaterThan{Float64}
@test constraint_by_name(model, "c", F, S1) === c
@test constraint_by_name(model, "c", F, S2) === nothing
@test constraint_by_name(model, "d", F, S1) === nothing
@test constraint_by_name(model, "d", F, S2) === nothing
return
end

end # module
16 changes: 16 additions & 0 deletions test/test_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ function test_optimize_not_called_warning()
end
@variable(model, x >= 0)
@constraint(model, c, 2x <= 1)
@test_throws OptimizeNotCalled value(x)
optimize!(model)
set_start_value(x, 0.0)
@test_logs (:warn,) (@test_throws OptimizeNotCalled objective_value(model))
Expand Down Expand Up @@ -1348,4 +1349,19 @@ function test_iterate_scalar()
return
end

function test_optimizer_index()
model = Model() do
inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}())
return MOI.Utilities.MockOptimizer(inner)
end
@variable(model, x)
@test_throws(
ErrorException(
"There is no `optimizer_index` as the optimizer is not synchronized with the cached model. Call `MOIU.attach_optimizer(model)` to synchronize it.",
),
optimizer_index(x),
)
return
end

end # module TestModels
12 changes: 12 additions & 0 deletions test/test_nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1122,4 +1122,16 @@ function test_error_legacy_parameter_constructor()
return
end

function test_promote_type()
F = GenericNonlinearExpr{GenericVariableRef{Int}}
G = GenericNonlinearExpr{GenericVariableRef{Float64}}
@test_throws(
ErrorException(
"Unable to promote two different types of nonlinear expression",
),
MA.promote_operation(+, F, G),
)
return
end

end # module
29 changes: 24 additions & 5 deletions test/test_operator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,21 @@ function test_extension_operator_warn(
if ModelType <: Model
@test model.operator_counter == 0
end
# Triggers the increment of operator_counter since sum(x) has more than 50 terms
@test_expression(sum(x) + 2x[1])
if ModelType <: Model
# The following check verifies that this test covers the code incrementing `operator_counter`
@test model.operator_counter == 1
lhs = sum(x)
rhs = 2 * x[1]
for i in 1:20_001
# Triggers the increment of operator_counter since lhs has more than
# 50 terms
if i == 20_001 && ModelType <: Model
@test_logs (:warn,) lhs + rhs
else
lhs + rhs
end
if ModelType <: Model
# The following check verifies that this test covers the code
# incrementing `operator_counter`
@test model.operator_counter == i
end
end
return
end
Expand Down Expand Up @@ -723,4 +733,13 @@ function test_hermitian_and_symmetric()
return
end

function test_is_symmetric()
model = Model()
@variable(model, x[1:3])
@test !LinearAlgebra.issymmetric([x[1] x[2]; x[3] x[3]])
@test !LinearAlgebra.issymmetric([x[1] x[2]])
@test LinearAlgebra.issymmetric([x[1] x[2]; x[2] x[3]])
return
end

end
4 changes: 2 additions & 2 deletions test/test_variable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ function test_extension_variable_name(
@variable(model, x)
_test_variable_name_util(x, "x")
set_name(x, "y")
@test variable_by_name(model, "x") isa Nothing
@test variable_by_name(model, "x") === nothing
_test_variable_name_util(x, "y")
y = @variable(model, base_name = "y")
err(name) = ErrorException("Multiple variables have the name $name.")
Expand All @@ -386,7 +386,7 @@ function test_extension_variable_name(
_test_variable_name_util(y, "x")
set_name(x, "x")
@test_throws err("x") variable_by_name(model, "x")
@test variable_by_name(model, "y") isa Nothing
@test variable_by_name(model, "y") === nothing
set_name(y, "y")
_test_variable_name_util(x, "x")
_test_variable_name_util(y, "y")
Expand Down

0 comments on commit da8a667

Please sign in to comment.