diff --git a/test/test_complement.jl b/test/test_complement.jl index 725122fb325..12edb55d86f 100644 --- a/test/test_complement.jl +++ b/test/test_complement.jl @@ -34,7 +34,7 @@ end function test_scalar_error_x_F() model = Model() @variable(model, x >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, x ⟂ 2x - 1)`: second term must be a " * "variable.", @@ -47,7 +47,7 @@ end function test_scalar_error_F_F() model = Model() @variable(model, x >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, x + 1 ⟂ 2x - 1)`: second term must " * "be a variable.", @@ -60,7 +60,7 @@ end function test_scalar_error_0_F() model = Model() @variable(model, x >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, 0 ⟂ 2x - 1)`: second term must be a " * "variable.", @@ -94,7 +94,7 @@ end function test_vector_error_length_mismatch() model = Model() @variable(model, x[1:2] >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, x ⟂ [x[1]])`: size of mapping does " * "not match size of variables: (2,) != (1,).", @@ -107,7 +107,7 @@ end function test_vector_error_x_F() model = Model() @variable(model, x[1:2] >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, x ⟂ 2x .- 1)`: second term must be an " * "array of variables.", @@ -119,7 +119,7 @@ end function test_vector_error_F_F() model = Model() @variable(model, x[1:2] >= 0) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, x .+ 1 ⟂ 2x .- 1)`: second term must " * "be an array of variables.", @@ -133,7 +133,7 @@ function test_vector_error_0_F() model = Model() @variable(model, x[1:2] >= 0) y = [1.2, -1.3] - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, y ⟂ 2x .- 1)`: second term must " * "be an array of variables.", diff --git a/test/test_complex.jl b/test/test_complex.jl index 80867627273..892649baa51 100644 --- a/test/test_complex.jl +++ b/test/test_complex.jl @@ -280,7 +280,7 @@ function test_HermitianPSDCone_general_matrix_error() Y = X + LinearAlgebra.I(2) * t @test LinearAlgebra.ishermitian(Y) @test !(Y isa LinearAlgebra.Hermitian) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, Y in HermitianPSDCone())`: " * "Unable to add matrix in HermitianPSDCone because the matrix is " * diff --git a/test/test_constraint.jl b/test/test_constraint.jl index 37585b61d4a..369e0a0e4cb 100644 --- a/test/test_constraint.jl +++ b/test/test_constraint.jl @@ -122,7 +122,7 @@ function test_extension_AffExpr_vectorized_constraints( "Unexpected vector in scalar constraint. The left- and right-hand " * "sides of the constraint must have the same dimension.", ) - @test_throws_strip err @constraint(model, [x, 2x] in MOI.EqualTo(1.0)) + @test_throws_runtime err @constraint(model, [x, 2x] in MOI.EqualTo(1.0)) VT = typeof([x, 2x]) err = ErrorException( "Operation `sub_mul` between `$VT` and `$Int` is not " * @@ -139,7 +139,7 @@ function test_extension_AffExpr_vectorized_constraints( ) a = 1 @test_throws err @constraint(model, a == [x, 2x]) - @test_macro_throws ErrorException begin + @test_throws_parsetime ErrorException begin @constraint(model, [x == 1 - x, 2x == 3]) end cref = @constraint(model, [x, 2x] .== [1 - x, 3]) @@ -164,7 +164,7 @@ function test_extension_AffExpr_vectorized_interval_constraints( "operators `l .<= f(x) .<= u` instead?", ) b = T[5, 6] - @test_throws_strip err @constraint(model, b <= x <= b) + @test_throws_runtime err @constraint(model, b <= x <= b) cref = @constraint(model, b .<= x .<= b) c = constraint_object.(cref) for i in 1:2 @@ -367,7 +367,7 @@ function test_extension_syntax_error_constraint( "add the constraint because we don't recognize $([3, x]) as a " * "valid JuMP function.", ) - @test_throws_strip err @constraint(model, [3, x] in SecondOrderCone()) + @test_throws_runtime err @constraint(model, [3, x] in SecondOrderCone()) return end @@ -404,23 +404,23 @@ function test_extension_indicator_constraint( err = ErrorException( "In `@constraint(model, !(a, b) => {x <= 1})`: Invalid binary variable expression `!(a, b)` for indicator constraint.", ) - @test_macro_throws err @constraint(model, !(a, b) => {x <= 1}) + @test_throws_parsetime err @constraint(model, !(a, b) => {x <= 1}) err = ErrorException( "In `@constraint(model, a => x)`: Invalid right-hand side `x` of indicator constraint. Expected constraint surrounded by `{` and `}`.", ) - @test_macro_throws err @constraint(model, a => x) + @test_throws_parsetime err @constraint(model, a => x) err = ErrorException( "In `@constraint(model, a => x <= 1)`: Invalid right-hand side `x <= 1` of indicator constraint. Expected constraint surrounded by `{` and `}`.", ) - @test_macro_throws err @constraint(model, a => x <= 1) + @test_throws_parsetime err @constraint(model, a => x <= 1) err = ErrorException( "In `@constraint(model, a => {x <= 1, x >= 0})`: Invalid right-hand side `{x <= 1, x >= 0}` of indicator constraint. Expected constraint surrounded by `{` and `}`.", ) - @test_macro_throws err @constraint(model, a => {x <= 1, x >= 0}) + @test_throws_parsetime err @constraint(model, a => {x <= 1, x >= 0}) err = ErrorException( "In `@constraint(model, [a, b] .=> {x + y <= 1})`: Inconsistent use of `.` in symbols to indicate vectorization.", ) - @test_macro_throws err @constraint(model, [a, b] .=> {x + y <= 1}) + @test_throws_parsetime err @constraint(model, [a, b] .=> {x + y <= 1}) return end @@ -593,7 +593,7 @@ function test_extension_SDP_errors( "arguments.\n\nIf you're trying to create a JuMP extension, you " * "need to implement `build_constraint` to accomodate these arguments.", ) - @test_throws_strip( + @test_throws_runtime( err, @constraint( model, @@ -674,7 +674,7 @@ function test_extension_PSD_constraint_errors( " instead of `MathOptInterface.PositiveSemidefiniteConeTriangle(2)`," * " use `JuMP.PSDCone()`.", ) - @test_throws_strip( + @test_throws_runtime( err, @constraint(model, X in MOI.PositiveSemidefiniteConeTriangle(2)) ) @@ -694,7 +694,7 @@ function test_extension_matrix_constraint_errors( ) # Note: this should apply to any MOI.AbstractVectorSet. We just pick # SecondOrderCone for convenience. - @test_throws_strip(err, @constraint(model, X in MOI.SecondOrderCone(4))) + @test_throws_runtime(err, @constraint(model, X in MOI.SecondOrderCone(4))) return end @@ -704,7 +704,7 @@ function test_extension_nonsensical_SDP_constraint( ) T = value_type(ModelType) m = ModelType() - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@variable(m, unequal[1:5, 1:6], PSD)`: Symmetric variables must be square. Got size (5, 6).", ), @@ -721,21 +721,21 @@ function test_extension_nonsensical_SDP_constraint( "for symmetric variable.", ) end - @test_throws_strip( + @test_throws_runtime( _ErrorException("@variable(m, foo[i = 1:2, j = 1:2] >= Y[i, j], PSD)"), @variable(m, foo[i = 1:2, j = 1:2] >= Y[i, j], PSD), ) - @test_throws_strip( + @test_throws_runtime( _ErrorException("@variable(m, foo[i = 1:2, j = 1:2] <= Y[i, j], PSD)"), @variable(m, foo[i = 1:2, j = 1:2] <= Y[i, j], PSD), ) - @test_throws_strip( + @test_throws_runtime( _ErrorException( "@variable(m, foo[i = 1:2, j = 1:2] >= Y[i, j], Symmetric)", ), @variable(m, foo[i = 1:2, j = 1:2] >= Y[i, j], Symmetric), ) - @test_throws_strip( + @test_throws_runtime( _ErrorException( "@variable(m, foo[i = 1:2, j = 1:2] <= Y[i, j], Symmetric)", ), @@ -1507,7 +1507,7 @@ function test_extension_HermitianPSDCone_errors( "need to implement `build_constraint` to accomodate these arguments.", ) H = LinearAlgebra.Hermitian([x 1im; -1im -y]) - @test_throws_strip( + @test_throws_runtime( err, @constraint(model, H in HermitianPSDCone(), unknown_kw = 1), ) @@ -1789,7 +1789,7 @@ function test_indicator_error() err = ErrorException( "In `@constraint(model, x[1] >= 0 --> {x[2] == 0})`: unable to build indicator constraint with the left-hand side term `(x[1] >= 0)::JuMP.NonlinearExpr`. The left-hand side must be a binary decision variable.", ) - @test_throws_strip err @constraint(model, x[1] >= 0 --> {x[2] == 0}) + @test_throws_runtime err @constraint(model, x[1] >= 0 --> {x[2] == 0}) return end diff --git a/test/test_macros.jl b/test/test_macros.jl index fea1c412eaa..b70382f4e23 100644 --- a/test/test_macros.jl +++ b/test/test_macros.jl @@ -317,12 +317,12 @@ function test_extension_build_constraint_extra_arg_test( @test constraint_object(cref).set isa MOI.LessThan{Float64} cref = @constraint(model, c1, x == 0, MyConstrType, d = 1) @test constraint_object(cref).set == MOI.LessThan{Float64}(1) - @test_throws_strip ErrorException @constraint(model, x == 0, BadPosArg) - @test_throws_strip( + @test_throws_runtime ErrorException @constraint(model, x == 0, BadPosArg) + @test_throws_runtime( ErrorException, @constraint(model, x == 0, BadPosArg, d = 1), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException, @constraint(model, x == 0, MyConstrType, BadPosArg), ) @@ -352,7 +352,7 @@ function test_extension_custom_function_test( con = constraint_object(con_ref) @test jump_function(con) == x @test moi_set(con) isa CustomSet - @test_macro_throws ErrorException @constraint(model, g(x)) + @test_throws_parsetime ErrorException @constraint(model, g(x)) return end @@ -421,7 +421,7 @@ function test_extension_check_constraint_basics( @test c.set == MOI.Interval(T(0), T(1)) @test_throws ErrorException @constraint(m, x <= t <= y) @test_throws ErrorException @constraint(m, 0 <= Dict() <= 1) - @test_macro_throws ErrorException @constraint(1 <= x <= 2, foo = :bar) + @test_throws_parsetime ErrorException @constraint(1 <= x <= 2, foo = :bar) @test isequal_canonical( @expression(m, 3x - y - α * (w + 2z) + 5), 3 * x - y - α * w - T(66) / T(10) * z + 5, @@ -482,8 +482,8 @@ function test_extension_constraint_naming( @test name(cref) == "cat" crefs = @constraint(model, [i in 1:2], x == 0, base_name = "cat_$i") @test name.(crefs) == ["cat_1[1]", "cat_2[2]"] - @test_macro_throws ErrorException @constraint(model, c3[1:2]) - @test_macro_throws ErrorException @constraint(model, "c"[1:2], x == 0) + @test_throws_parsetime ErrorException @constraint(model, c3[1:2]) + @test_throws_parsetime ErrorException @constraint(model, "c"[1:2], x == 0) return end @@ -581,7 +581,7 @@ function test_extension_extension_build_constraint_error( ) model = ModelType() @variable(model, x) - @test_macro_throws ErrorException @build_constraint(2x + 1) + @test_throws_parsetime ErrorException @build_constraint(2x + 1) return end @@ -597,7 +597,7 @@ end function test_Adding_anonymous_variable_and_specify_required_constraint_on_it() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(m, Int)`: Ambiguous variable name Int detected." * " To specify an anonymous integer variable, use `@variable(model, integer = true)` instead.", @@ -607,7 +607,7 @@ function test_Adding_anonymous_variable_and_specify_required_constraint_on_it() v = @variable(model, integer = true) @test name(v) == "" @test is_integer(v) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(m, Bin)`: Ambiguous variable name Bin detected." * " To specify an anonymous binary variable, use `@variable(model, binary = true)` instead.", @@ -617,7 +617,7 @@ function test_Adding_anonymous_variable_and_specify_required_constraint_on_it() v = @variable(model, binary = true) @test name(v) == "" @test is_binary(v) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(m, PSD)`: Size of anonymous square matrix of positive semidefinite anonymous variables is not specified." * " To specify size of square matrix use `@variable(model, [1:n, 1:n], PSD)` instead.", @@ -800,15 +800,15 @@ end function test_Plural_failures() model = Model() - @test_macro_throws MethodError @variables(model) + @test_throws_parsetime MethodError @variables(model) err = ErrorException( "Invalid syntax for @variables. The second argument must be a `begin end` " * "block. For example:\n" * "```julia\n@variables(model, begin\n # ... lines here ...\nend)\n```.", ) - @test_macro_throws err @variables(model, x) - @test_macro_throws err @variables(model, x >= 0) - @test_macro_throws MethodError @variables(model, x >= 0, Bin) + @test_throws_parsetime err @variables(model, x) + @test_throws_parsetime err @variables(model, x >= 0) + @test_throws_parsetime MethodError @variables(model, x >= 0, Bin) return end @@ -847,7 +847,7 @@ function test_Splatting_error() model = Model() A = [1 0; 0 1] @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, y[axes(A)...])`: cannot use splatting operator `...` in the definition of an index set.", ), @@ -856,31 +856,31 @@ function test_Splatting_error() f(a, b) = [a, b] @variable(model, z[f((1, 2)...)]) @test length(z) == 2 - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, [axes(A)...], x >= 1)`: cannot use splatting operator `...` in the definition of an index set.", ), @constraint(model, [axes(A)...], x >= 1) ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLconstraint(model, [axes(A)...], x >= 1)`: cannot use splatting operator `...` in the definition of an index set.", ), @NLconstraint(model, [axes(A)...], x >= 1) ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@expression(model, [axes(A)...], x)`: cannot use splatting operator `...` in the definition of an index set.", ), @expression(model, [axes(A)...], x) ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLexpression(model, [axes(A)...], x)`: cannot use splatting operator `...` in the definition of an index set.", ), @NLexpression(model, [axes(A)...], x) ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLparameter(model, p[axes(A)...] == x)`: cannot use splatting operator `...` in the definition of an index set.", ), @@ -904,7 +904,7 @@ function test_NaN_in_constraints() @test_throws ErrorException( "Expression contains an invalid NaN constant. This could be produced by `Inf - Inf`.", ) @constraint(model, 1 <= x + Inf <= 2) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, 1 <= x <= NaN)`: Invalid bounds, cannot contain NaN: [1, NaN].", ), @@ -934,7 +934,7 @@ function test_unrecognized_variable_type() "extension, you need to implement `build_variable`. Read the " * "docstring for more details.", ) - @test_throws_strip err @variable(model, x, 2, variable_type = 1) + @test_throws_runtime err @variable(model, x, 2, variable_type = 1) return end @@ -946,7 +946,7 @@ function test_unrecognized_kwarg() "create a JuMP extension, you need to implement " * "`build_variable`. Read the docstring for more details.", ) - @test_throws_strip err @variable(model, x, foo = 1) + @test_throws_runtime err @variable(model, x, foo = 1) return end @@ -965,29 +965,29 @@ function test_Model_as_index() m = Model() @variable(m, x) msg = "Index m is the same symbol as the model. Use a different name for the index." - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@variable(m, y[m = 1:2] <= m)`: $(msg)"), @variable(m, y[m = 1:2] <= m), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@constraint(m, [m = 1:2], x <= m)`: $(msg)"), @constraint(m, [m = 1:2], x <= m), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@expression(m, [m = 1:2], m * x)`: $(msg)"), @expression(m, [m = 1:2], m * x), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLconstraint(m, [m = 1:2], sqrt(x) <= m)`: $(msg)", ), @NLconstraint(m, [m = 1:2], sqrt(x) <= m), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLexpression(m, [m = 1:2], x)`: $(msg)"), @NLexpression(m, [m = 1:2], x), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLparameter(m, p[m = 1:2] == m)`: $(msg)"), @NLparameter(m, p[m = 1:2] == m), ) @@ -1010,7 +1010,7 @@ end function test_singular_plural_error() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, begin\n x\nend)`: " * "Invalid syntax. Did you mean to use `@variables`?", @@ -1020,7 +1020,7 @@ function test_singular_plural_error() end), ) @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, begin\n x >= 0\nend)`: " * "Invalid syntax. Did you mean to use `@constraints`?", @@ -1029,7 +1029,7 @@ function test_singular_plural_error() x >= 0 end), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@expression(model, begin\n x\nend)`: " * "Invalid syntax. Did you mean to use `@expressions`?", @@ -1038,7 +1038,7 @@ function test_singular_plural_error() x end), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLconstraint(model, begin\n x >= 0\nend)`: " * "Invalid syntax. Did you mean to use `@NLconstraints`?", @@ -1047,7 +1047,7 @@ function test_singular_plural_error() x >= 0 end), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLexpression(model, begin\n x\nend)`: " * "Invalid syntax. Did you mean to use `@NLexpressions`?", @@ -1056,7 +1056,7 @@ function test_singular_plural_error() x end), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@NLparameter(model, begin\n x == 1\nend)`: " * "Invalid syntax: did you mean to use `@NLparameters`?", @@ -1100,7 +1100,7 @@ function test_Interval_errors_lhs() "two separate constraints, or move all variables into the " * "central term.", ) - @test_throws_strip err @constraint(model, x <= x <= 2) + @test_throws_runtime err @constraint(model, x <= x <= 2) return end @@ -1113,7 +1113,7 @@ function test_Interval_errors_rhs() "two separate constraints, or move all variables into the " * "central term.", ) - @test_throws_strip err @constraint(model, 2 <= x <= x) + @test_throws_runtime err @constraint(model, 2 <= x <= x) return end @@ -1126,7 +1126,7 @@ function test_Interval_errors_lhs_and_rhs() "two separate constraints, or move all variables into the " * "central term.", ) - @test_throws_strip err @constraint(model, x <= x <= x) + @test_throws_runtime err @constraint(model, x <= x <= x) return end @@ -1173,7 +1173,7 @@ end function test_nlparameter_too_many_positional_args() msg = "Invalid syntax: too many positional arguments." model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLparameter(model, p == 1, Int)`: $(msg)"), @NLparameter(model, p == 1, Int), ) @@ -1183,7 +1183,7 @@ end function test_nlparameter_unsupported_keyword_args() msg = "Invalid syntax: unsupported keyword arguments." model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLparameter(model, p == 1, bad = false)`: $(msg)"), @NLparameter(model, p == 1, bad = false), ) @@ -1193,7 +1193,7 @@ end function test_nlparameter_invalid_syntax() msg = "Invalid syntax: expected syntax of form `param == value`." model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLparameter(model, p)`: $(msg)"), @NLparameter(model, p), ) @@ -1213,7 +1213,7 @@ end function test_nlparameter_anonymous_error() msg = "Invalid syntax: no positional args allowed for anonymous parameters." model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@NLparameter(model, p, value = 1)`: $(msg)"), @NLparameter(model, p, value = 1), ) @@ -1223,7 +1223,7 @@ end function test_nlparameter_invalid_number() msg = "Parameter value is not a number." model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@NLparameter(model, p == :a)`: $(msg)"), @NLparameter(model, p == :a), ) @@ -1261,11 +1261,11 @@ function test_variable_vector_lowerbound() ``` """ model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] >= [1, 2])`: $(msg)"), @variable(model, x[1:2] >= [1, 2]), ) - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] .>= [1, 2])`: $(msg)"), @variable(model, x[1:2] .>= [1, 2]), ) @@ -1291,11 +1291,11 @@ function test_variable_vector_upperbound() ``` """ model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] <= [1, 2])`: $(msg)"), @variable(model, x[1:2] <= [1, 2]), ) - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] .<= [1, 2])`: $(msg)"), @variable(model, x[1:2] .<= [1, 2]), ) @@ -1321,11 +1321,11 @@ function test_variable_vector_fixed() ``` """ model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] == [1, 2])`: $(msg)"), @variable(model, x[1:2] == [1, 2]), ) - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2] .== [1, 2])`: $(msg)"), @variable(model, x[1:2] .== [1, 2]), ) @@ -1351,7 +1351,7 @@ function test_variable_vector_start() ``` """ model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException("In `@variable(model, x[1:2], start = [1, 2])`: $(msg)"), @variable(model, x[1:2], start = [1, 2]), ) @@ -1377,13 +1377,13 @@ function test_variable_vector_interval() ``` """ model = Model() - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@variable(model, 0 <= x[2:3, 3:4] <= rand(2, 2))`: $(msg)", ), @variable(model, 0 <= x[2:3, 3:4] <= rand(2, 2)), ) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@variable(model, 0 .<= x[2:3, 3:4] .<= rand(2, 2))`: $(msg)", ), @@ -1394,7 +1394,7 @@ end function test_invalid_name_errors() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("Expression x.y cannot be used as a name."), @variable(model, x.y), ) @@ -1403,7 +1403,7 @@ end function test_invalid_name_errors_denseaxisarray() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("Expression x.y cannot be used as a name."), @variable(model, x.y[2:3, 1:2]), ) @@ -1412,7 +1412,7 @@ end function test_invalid_name_errors_sparseaxisarray() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("Expression x.y cannot be used as a name."), @variable(model, x.y[i = 1:3; isodd(i)]), ) @@ -1421,7 +1421,7 @@ end function test_invalid_variable_syntax() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, MyInfo(1))`: Invalid syntax: your syntax " * "is wrong, but we don't know why. Consult the documentation for " * @@ -1488,7 +1488,7 @@ function test_parse_constraint_head_error() "writing a JuMP extension, implement " * "`parse_constraint_head(::Function, ::Val{:braces}, args...)", ) - @test_macro_throws(err, @constraint(model, {x == 0})) + @test_throws_parsetime(err, @constraint(model, {x == 0})) return end @@ -1499,7 +1499,7 @@ function test_parse_constraint_head_inconsistent_vectorize() "In `@constraint(model, 1 .<= [x, x] <= 2)`: " * "Operators are inconsistently vectorized.", ) - @test_macro_throws(err, @constraint(model, 1 .<= [x, x] <= 2)) + @test_throws_parsetime(err, @constraint(model, 1 .<= [x, x] <= 2)) return end @@ -1511,7 +1511,7 @@ function test_parse_constraint_head_inconsistent_signs() "unsupported mix of comparison operators `1 >= ... <= 2`.\n\n" * "Two-sided rows must of the form `1 <= ... <= 2` or `2 >= ... >= 1`.", ) - @test_macro_throws(err, @constraint(model, 1 >= x <= 2)) + @test_throws_parsetime(err, @constraint(model, 1 >= x <= 2)) return end @@ -1679,7 +1679,7 @@ end function test_constraint_not_enough_arguments() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@constraint(model)`: Not enough arguments"), @constraint(model), ) @@ -1694,13 +1694,13 @@ function test_constraint_no_constraint_expression_detected() "If you are trying to construct an equality constraint, use `==` " * "instead of `=`.", ) - @test_macro_throws(err, @constraint(model, x = 2)) + @test_throws_parsetime(err, @constraint(model, x = 2)) return end function test_objective_not_enough_arguments() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@objective(model, Min)`: expected 3 positional arguments, got 2.", ), @@ -1711,7 +1711,7 @@ end function test_expression_not_enough_arguments() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@expression(model)`: expected 2 or 3 positional arguments, got 1.", ), @@ -1723,7 +1723,7 @@ end function test_expression_keyword_arguments() model = Model() @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@expression(model, x, foo = 1)`: unsupported keyword argument `foo`.", ), @@ -1735,7 +1735,7 @@ end function test_objective_keyword_arguments() model = Model() @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@objective(model, Min, x, foo = 1)`: unsupported keyword argument `foo`.", ), @@ -1747,7 +1747,7 @@ end function test_build_constraint_invalid() model = Model() @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@build_constraint(x)`: Incomplete constraint specification " * "x. Are you missing a comparison (<=, >=, or ==)?", @@ -1772,7 +1772,7 @@ end function test_variable_unsupported_operator() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException("In `@variable(model, x ⊕ 1)`: unsupported operator ⊕"), @variable(model, x ⊕ 1), ) @@ -1782,7 +1782,7 @@ end function test_constraint_unsupported_operator() model = Model() @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, x ⊕ 1)`: unsupported operator ⊕", ), @@ -1793,7 +1793,7 @@ end function test_variable_anon_bounds() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, [1:2] >= 0)`: Cannot use explicit bounds " * "via >=, <= with an anonymous variable", @@ -1829,14 +1829,14 @@ function test_variable_Bool_argument() "`{0, 1}` decision variable, use `Bin` instead. For example, " * "`@variable(model, x, Bin)` or `@variable(model, x, binary = true)`.", ) - @test_throws_strip(err, @variable(model, x, Bool)) + @test_throws_runtime(err, @variable(model, x, Bool)) err = ErrorException( "In `@variable(model, x, Bool = true)`: " * "Unsupported keyword argument: Bool.\n\nIf you intended to " * "create a `{0, 1}` decision variable, use the `binary` keyword " * "argument instead: `@variable(model, x, binary = true)`.", ) - @test_throws_strip(err, @variable(model, x, Bool = true)) + @test_throws_runtime(err, @variable(model, x, Bool = true)) return end @@ -1901,7 +1901,7 @@ function test_nonlinear_generator_bad_init() model = Model() @variable(model, x) expr = :(sum((x for i in 1:1); bad_init = 3)) - @test_macro_throws( + @test_throws_parsetime( ErrorException("Unsupported nonlinear expression: $expr"), @NLexpression(model, sum(x for i in 1:1; bad_init = 3)) ) @@ -1961,7 +1961,7 @@ function test_matrix_in_vector_set() model = Model() @variable(model, X[1:2, 1:2]) A = [1 2; 3 4] - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, X >= A)`: " * "Unsupported matrix in vector-valued set. Did you mean to use the " * @@ -1971,7 +1971,7 @@ function test_matrix_in_vector_set() ), @constraint(model, X >= A), ) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, X <= A)`: " * "Unsupported matrix in vector-valued set. Did you mean to use the " * @@ -1981,7 +1981,7 @@ function test_matrix_in_vector_set() ), @constraint(model, X <= A), ) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@constraint(model, X == A)`: " * "Unsupported matrix in vector-valued set. Did you mean to use the " * @@ -2004,7 +2004,7 @@ end function test_unsupported_operator_errors() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x > 0)`: " * "unsupported operator `>`.\n\n" * @@ -2018,7 +2018,7 @@ function test_unsupported_operator_errors() ), @variable(model, x > 0), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x < 0)`: " * "unsupported operator `<`.\n\n" * @@ -2033,7 +2033,7 @@ function test_unsupported_operator_errors() @variable(model, x < 0), ) @variable(model, x) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, x > 0)`: " * "unsupported operator `>`.\n\n" * @@ -2047,7 +2047,7 @@ function test_unsupported_operator_errors() ), @constraint(model, x > 0), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, x < 0)`: " * "unsupported operator `<`.\n\n" * @@ -2066,7 +2066,7 @@ end function test_unsupported_ternary_operator() model = Model() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, 1 < x < 2)`: " * "unsupported mix of comparison operators `1 < ... < 2`.\n\n" * @@ -2166,7 +2166,7 @@ end function test_bad_objective_sense() model = Model() @variable(model, x) - @test_throws_strip( + @test_throws_runtime( ErrorException( "In `@objective(model, :MinMax, x)`: unexpected sense `MinMax`. " * "The sense must be an `::MOI.OptimizatonSense`, or the symbol " * diff --git a/test/test_nlp.jl b/test/test_nlp.jl index a154be09f9e..324f0370b5e 100644 --- a/test/test_nlp.jl +++ b/test/test_nlp.jl @@ -399,11 +399,11 @@ end function test_parse_unsupported_generator() model = Model() @variable(model, x[1:2]) - @test_macro_throws( + @test_throws_parsetime( ErrorException("Unsupported generator `:min`"), @NLexpression(model, min(x[i] for i in 1:2)), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException("Unsupported generator `:max`"), @NLexpression(model, max(x[i] for i in 1:2)), ) @@ -482,7 +482,7 @@ function test_error_on_begin_end() "`begin...end` blocks are not supported in nonlinear macros. The " * "nonlinear expression must be a single statement.", ) - @test_macro_throws(err, @NLobjective(model, Max, begin + @test_throws_parsetime(err, @NLobjective(model, Max, begin sin(x) + 1 end)) return @@ -498,7 +498,7 @@ end function test_error_on_getfield_in_expression() model = Model() @variable(model, x[1:2]) - @test_macro_throws( + @test_throws_parsetime( ErrorException, @NLexpression(model, sum(foo.bar(i) * x[i] for i in 1:2)) ) diff --git a/test/test_reified.jl b/test/test_reified.jl index e0051b30bbb..506d809864e 100644 --- a/test/test_reified.jl +++ b/test/test_reified.jl @@ -56,7 +56,7 @@ function test_reified_inconsistent() @variable(model, x) @variable(model, z, Bin) expr = :(z <--> {x .== 1}) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, $expr)`: " * "vectorized constraints cannot be used with reification.", @@ -71,7 +71,7 @@ function test_reified_no_curly_bracket() @variable(model, x) @variable(model, z, Bin) expr = :(z <--> x == 1) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@constraint(model, $expr)`: " * "Invalid right-hand side `x == 1` of reified constraint. " * diff --git a/test/test_variable.jl b/test/test_variable.jl index 431494bcc87..5bbcd95af04 100644 --- a/test/test_variable.jl +++ b/test/test_variable.jl @@ -155,8 +155,8 @@ function test_extension_variable_interval( _has_bounds(bothb3, 0.0, 1.0) @variable(model, 1 ≥ bothb4 ≥ 0) _has_bounds(bothb4, 0.0, 1.0) - @test_macro_throws ErrorException @variable(model, 1 ≥ bothb5 ≤ 0) - @test_macro_throws ErrorException @variable(model, 1 ≤ bothb6 ≥ 0) + @test_throws_parsetime ErrorException @variable(model, 1 ≥ bothb5 ≤ 0) + @test_throws_parsetime ErrorException @variable(model, 1 ≤ bothb6 ≥ 0) return end @@ -597,7 +597,7 @@ function test_extension_variables_constrained_on_creation_errors( VariableRefType = VariableRef, ) model = ModelType() - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x[1:2] in SecondOrderCone(), set = PSDCone())`: " * "Cannot use set keyword because the variable is already " * @@ -605,7 +605,7 @@ function test_extension_variables_constrained_on_creation_errors( ), @variable(model, x[1:2] in SecondOrderCone(), set = PSDCone()), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x[1:2] in SecondOrderCone(), PSD)`: " * "Cannot pass `PSD` as a positional argument because the variable " * @@ -613,7 +613,7 @@ function test_extension_variables_constrained_on_creation_errors( ), @variable(model, x[1:2] in SecondOrderCone(), PSD), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x[1:2, 1:2], PSD, Symmetric)`: " * "Cannot pass `Symmetric` as a positional argument because the " * @@ -621,7 +621,7 @@ function test_extension_variables_constrained_on_creation_errors( ), @variable(model, x[1:2, 1:2], PSD, Symmetric), ) - @test_macro_throws( + @test_throws_parsetime( ErrorException( "In `@variable(model, x[1:2], set = SecondOrderCone(), set = PSDCone())`: " * "the keyword argument `set` was given multiple times.", diff --git a/test/utilities.jl b/test/utilities.jl index 2db40a48acc..aa2d7a375fe 100644 --- a/test/utilities.jl +++ b/test/utilities.jl @@ -33,17 +33,25 @@ end function _strip_line_from_error(err::ErrorException) return ErrorException(replace(err.msg, r"^At.+\:[0-9]+\: `@" => "In `@")) end + _strip_line_from_error(err::LoadError) = _strip_line_from_error(err.error) + _strip_line_from_error(err) = err -# Test that the macro call `m` throws an error exception during pre-compilation -macro test_macro_throws(errortype, m) - # See https://discourse.julialang.org/t/test-throws-with-macros-after-pr-23533/5878 - quote +""" + @test_throws_parsetime(error_type, expression) + +Test that the macro call `expression` throws an `error_type` exception during +the parsing of the macro. + +See https://discourse.julialang.org/t/test-throws-with-macros-after-pr-23533 +""" +macro test_throws_parsetime(error_type, expression) + return quote @test_throws( - $(esc(_strip_line_from_error(errortype))), + $(esc(_strip_line_from_error(error_type))), try - @eval $m + @eval $expression catch err throw(_strip_line_from_error(err)) end @@ -51,13 +59,18 @@ macro test_macro_throws(errortype, m) end end -# Test that the macro call `m` throws an error exception during _runtime_. -macro test_throws_strip(errortype, m) - quote +""" + @test_throws_runtime(error_type, expression) + +Test that the macro call `expression` throws an `error_type` exception during +_runtime_. +""" +macro test_throws_runtime(error_type, expression) + return quote @test_throws( - $(esc(_strip_line_from_error(errortype))), + $(esc(_strip_line_from_error(error_type))), try - $(esc(m)) + $(esc(expression)) catch err throw(_strip_line_from_error(err)) end