Skip to content

Commit 0d645cd

Browse files
committed
Improve code coverage
1 parent d68b3fb commit 0d645cd

File tree

19 files changed

+334
-21
lines changed

19 files changed

+334
-21
lines changed

src/FileFormats/MPS/MPS.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ function Base.read!(io::IO, model::Model)
11531153
end
11541154
data = TempMPSModel()
11551155
header = HEADER_NAME
1156-
while !eof(io)
1156+
while !eof(io) && header != HEADER_ENDATA
11571157
raw_line = readline(io)
11581158
if startswith(raw_line, '*')
11591159
continue # Lines starting with `*` are comments
@@ -1219,7 +1219,6 @@ function Base.read!(io::IO, model::Model)
12191219
parse_indicators_line(data, items)
12201220
else
12211221
@assert header == HEADER_ENDATA
1222-
break
12231222
end
12241223
end
12251224
copy_to(model, data)
@@ -1556,7 +1555,7 @@ function parse_single_rhs(
15561555
data.row_upper[row] = value
15571556
else
15581557
@assert data.sense[row] == SENSE_N
1559-
error("Cannot have RHS for objective: $(join(items, " "))")
1558+
error("Cannot have RHS for free row: $(join(items, " "))")
15601559
end
15611560
return
15621561
end

src/Utilities/print.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,13 +683,25 @@ end
683683

684684
Base.show(io::IO, ::MIME"text/latex", model::_LatexModel) = show(io, model)
685685

686-
function Base.print(model::MOI.ModelLike; kwargs...)
686+
function _get_ijulia_latex_display()
687687
for d in Base.Multimedia.displays
688688
if Base.Multimedia.displayable(d, "text/latex") &&
689689
startswith("$(typeof(d))", "IJulia.")
690-
return display(d, "text/latex", latex_formulation(model; kwargs...))
690+
return d
691691
end
692692
end
693+
return
694+
end
695+
696+
function Base.print(
697+
model::MOI.ModelLike;
698+
_latex_display = _get_ijulia_latex_display(),
699+
kwargs...,
700+
)
701+
if _latex_display !== nothing
702+
formulation = latex_formulation(model; kwargs...)
703+
return display(_latex_display, "text/latex", formulation)
704+
end
693705
return print(stdout, model; kwargs...)
694706
end
695707

src/indextypes.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ end
9393

9494
function Base.showerror(io::IO, err::InvalidIndex)
9595
return print(
96+
io,
9697
"The index $(err.index) is invalid. Note that an index becomes invalid after it has been deleted.",
9798
)
9899
end

src/instantiate.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct OptimizerWithAttributes
2424
end
2525

2626
_to_param(param::Pair{<:AbstractOptimizerAttribute}) = param
27+
2728
function _to_param(param::Pair{String})
2829
return RawOptimizerAttribute(param.first) => param.second
2930
end

test/Benchmarks/Benchmarks.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ function test_baseline()
4343
suite = MOI.Benchmarks.suite() do
4444
return MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
4545
end
46+
@test_throws(
47+
ErrorException("You create a baseline with `create_baseline` first."),
48+
MOI.Benchmarks.compare_against_baseline(
49+
suite,
50+
"baseline";
51+
directory = @__DIR__,
52+
samples = 1,
53+
verbose = true,
54+
),
55+
)
4656
MOI.Benchmarks.create_baseline(
4757
suite,
4858
"baseline";

test/FileFormats/FileFormats.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,19 @@ function test_generic_names()
189189
return
190190
end
191191

192+
function test_unique_names()
193+
model = MOI.Utilities.Model{Float64}()
194+
x = MOI.add_variables(model, 3)
195+
MOI.set.(model, MOI.VariableName(), x, "x")
196+
c = MOI.add_constraint.(model, 1.0 .* x, MOI.EqualTo(1.0))
197+
MOI.set.(model, MOI.ConstraintName(), c, "c")
198+
MOI.set(model, MOI.ConstraintName(), c[2], "c_1")
199+
MOI.FileFormats.create_unique_names(model)
200+
@test MOI.get.(model, MOI.VariableName(), x) == ["x", "x_1", "x_2"]
201+
@test MOI.get.(model, MOI.ConstraintName(), c) == ["c", "c_1", "c_2"]
202+
return
203+
end
204+
192205
end
193206

194207
TestFileFormats.runtests()

test/FileFormats/LP/LP.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,20 @@ function test_comprehensive_write()
10991099
return
11001100
end
11011101

1102+
function test_unable_to_parse_bound()
1103+
io = IOBuffer("""
1104+
minimize
1105+
obj: 1 x
1106+
subject to
1107+
bounds
1108+
x
1109+
end
1110+
""")
1111+
model = LP.Model()
1112+
@test_throws(ErrorException("Unable to parse bound: x"), read!(io, model))
1113+
return
1114+
end
1115+
11021116
end # module
11031117

11041118
TestLP.runtests()

test/FileFormats/MPS/MPS.jl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,55 @@ function test_model_not_empty()
14841484
return
14851485
end
14861486

1487+
function test_rhs_free_row()
1488+
io = IOBuffer("""
1489+
NAME
1490+
ROWS
1491+
N OBJ
1492+
N c
1493+
COLUMNS
1494+
x OBJ 1
1495+
x c 1
1496+
RHS
1497+
rhs c 1
1498+
RANGES
1499+
BOUNDS
1500+
FR bounds x
1501+
ENDATA
1502+
""")
1503+
model = MPS.Model()
1504+
@test_throws(
1505+
ErrorException("Cannot have RHS for free row: rhs c 1"),
1506+
read!(io, model),
1507+
)
1508+
return
1509+
end
1510+
1511+
function test_malformed_indicator()
1512+
io = IOBuffer("""
1513+
NAME
1514+
ROWS
1515+
N OBJ
1516+
COLUMNS
1517+
x OBJ 1
1518+
y OBJ 1
1519+
RHS
1520+
RANGES
1521+
BOUNDS
1522+
FR bounds x
1523+
BV bounds y
1524+
INDICATORS
1525+
IF c1 y
1526+
ENDATA
1527+
""")
1528+
model = MPS.Model()
1529+
@test_throws(
1530+
ErrorException("Malformed INDICATORS line: IF c1 y"),
1531+
read!(io, model),
1532+
)
1533+
return
1534+
end
1535+
14871536
end # TestMPS
14881537

14891538
TestMPS.runtests()

test/Test/Test.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ end
125125
@test_logs MOI.Test.runtests(model, config; exclude = exclude)
126126
end
127127

128+
@testset "test_FeasibilitySenseEvaluator" begin
129+
evaluator = MOI.Test.FeasibilitySenseEvaluator(true)
130+
@test MOI.features_available(evaluator) == [:Grad, :Jac, :Hess, :ExprGraph]
131+
@test MOI.hessian_lagrangian_structure(evaluator) == [(1, 1)]
132+
evaluator = MOI.Test.FeasibilitySenseEvaluator(false)
133+
@test MOI.features_available(evaluator) == [:Grad, :Jac, :ExprGraph]
134+
@test_throws AssertionError MOI.hessian_lagrangian_structure(evaluator)
135+
end
136+
128137
@testset "test_HS071_evaluator" begin
129138
evaluator = MOI.Test.HS071(true, true)
130139
features = [:Grad, :Jac, :JacVec, :ExprGraph, :Hess, :HessVec]

test/Utilities/functions.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,6 +2238,24 @@ function test_filter_variables_variable_index()
22382238
return
22392239
end
22402240

2241+
function test_mult_bool()
2242+
f = 1.0 * MOI.VariableIndex(1) + 2.0
2243+
@test *(f, false) zero(MOI.ScalarAffineFunction{Float64})
2244+
return
2245+
end
2246+
2247+
function test_is_complex()
2248+
@test !MOI.Utilities.is_complex(MOI.ScalarAffineFunction{Float64})
2249+
@test !MOI.Utilities.is_complex(MOI.ScalarQuadraticFunction{Float64})
2250+
@test !MOI.Utilities.is_complex(MOI.VectorAffineFunction{Float64})
2251+
@test !MOI.Utilities.is_complex(MOI.VectorQuadraticFunction{Float64})
2252+
@test MOI.Utilities.is_complex(MOI.ScalarAffineFunction{ComplexF64})
2253+
@test MOI.Utilities.is_complex(MOI.ScalarQuadraticFunction{ComplexF64})
2254+
@test MOI.Utilities.is_complex(MOI.VectorAffineFunction{ComplexF64})
2255+
@test MOI.Utilities.is_complex(MOI.VectorQuadraticFunction{ComplexF64})
2256+
return
2257+
end
2258+
22412259
end # module
22422260

22432261
TestUtilitiesFunctions.runtests()

test/Utilities/matrix_of_constraints.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,31 @@ function test_modify_set_constants()
689689
return
690690
end
691691

692+
function test_unsupported_constraint()
693+
model = _new_ScalarSets()
694+
x = MOI.VariableIndex(1)
695+
@test_throws(
696+
MOI.UnsupportedConstraint{MOI.VariableIndex,MOI.ZeroOne}(),
697+
MOI.add_constraint(model.constraints, x, MOI.ZeroOne()),
698+
)
699+
src = MOI.Utilities.Model{Float64}()
700+
index_map = MOI.Utilities.IndexMap()
701+
@test_throws(
702+
MOI.UnsupportedConstraint{MOI.VariableIndex,MOI.ZeroOne}(),
703+
MOI.Utilities._allocate_constraints(
704+
model.constraints,
705+
src,
706+
index_map,
707+
MOI.VariableIndex,
708+
MOI.ZeroOne,
709+
),
710+
)
711+
MOI.Utilities.final_touch(model, index_map)
712+
@test_throws AssertionError MOI.Utilities.final_touch(model, index_map)
713+
MOI.Utilities.final_touch(model, nothing)
714+
return
715+
end
716+
692717
end
693718

694719
TestMatrixOfConstraints.runtests()

test/Utilities/model.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,14 @@ function test_indicator_constraints()
562562
return
563563
end
564564

565+
function test_set_unsupported_objective()
566+
model = MOI.Utilities.Model{Float64}()
567+
f = FunctionNotSupportedBySolvers(MOI.VariableIndex(1))
568+
attr = MOI.ObjectiveFunction{typeof(f)}()
569+
@test_throws(MOI.UnsupportedAttribute(attr), MOI.set(model, attr, f))
570+
return
571+
end
572+
565573
end # module
566574

567575
TestModel.runtests()

test/Utilities/parser.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,15 @@ function test_parse_scope()
435435
return
436436
end
437437

438+
function test_parse_unrecognized_expression()
439+
model = MOI.Utilities.Model{Float64}()
440+
@test_throws(
441+
ErrorException("Unrecognized expression []"),
442+
MOI.Utilities.loadfromstring!(model, "[]"),
443+
)
444+
return
445+
end
446+
438447
end # module
439448

440449
TestParser.runtests()

test/Utilities/print.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,32 @@ function test_show_2505()
724724
return
725725
end
726726

727+
function test_print_model_to_stdout()
728+
model = MOI.Utilities.Model{Float64}()
729+
dir = mktempdir()
730+
d = MOI.Utilities._get_ijulia_latex_display()
731+
# d is only not nothing if IJulia is running.
732+
if d === nothing
733+
open(joinpath(dir, "stdout.log"), "w") do io
734+
redirect_stdout(io) do
735+
print(model)
736+
return
737+
end
738+
return
739+
end
740+
@test read(joinpath(dir, "stdout.log"), String) ==
741+
"Feasibility\n\nSubject to:\n"
742+
end
743+
io = IOBuffer()
744+
d = Base.Multimedia.TextDisplay(io)
745+
@test Base.Multimedia.displayable(d, "text/latex")
746+
print(model; _latex_display = d)
747+
seekstart(io)
748+
@test read(io, String) ==
749+
"\$\$ \\begin{aligned}\n\\text{feasibility}\\\\\n\\text{Subject to}\\\\\n\\end{aligned} \$\$\n"
750+
return
751+
end
752+
727753
end
728754

729755
TestPrint.runtests()

test/Utilities/test_operate!.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,14 @@ function test_operate_3b_scalarnonlinearfunction_specialcase()
340340
return
341341
end
342342

343+
function test_operate_3c()
344+
x = MOI.VariableIndex(1)
345+
f = 1.0 * x + 2.0
346+
g = MOI.Utilities.operate(*, Float64, f, x)
347+
@test g 1.0 * x * x + 2.0 * x
348+
return
349+
end
350+
343351
function test_operate_4a()
344352
T = Float64
345353
for (f, g) in (
@@ -387,6 +395,7 @@ function test_operate_5a()
387395
args = (_test_function(f), _test_function(g))
388396
@test MOI.Utilities.operate!(vcat, T, args...) _test_function(h)
389397
end
398+
@test MOI.Utilities.operate(vcat, T) == T[]
390399
return
391400
end
392401

0 commit comments

Comments
 (0)