-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a list instead of a hash table for storing package tests #3419
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why doesn't code tests Saturation
work?
The only other requested change is the one in the documentation, but here are several other desiderata:
- The printing of
TestInput
could use simplifying:- Why is it in parenthesis inside
NumberedVerticalList
? - The full path to the test seems unnecessary, can we cap it to path from
packages
directory? e.g.TestInput[FirstPackage.m2:54:1-57:1]
. Full location can be queried withlocate N
orlocate tests Saturation
.
- Why is it in parenthesis inside
- I'd expect
capture tests Saturation
to work. - Why are
code first tests Saturation
andcode locate first tests Saturation
are so different? I understand that the former is the string that we will eventually run, but even the location line is different, and the extra lines before and after look weird. MaybetoString TestInput
should give the actual string socode
can just show the exact lines in the file?
i5 : code locate first tests Saturation
o5 = ../../Macaulay2/packages/Saturation/quotient-test.m2:1:1-11:1: --source code:
TEST ///
R = ZZ[x, y];
I = ideal(6*x^3, 9*x*y, 8*y^2);
J1 = ideal(-3, x^2);
J2 = ideal(4*y);
assert(intersect(I:J1, I:J2) == ideal(8*y^2, 3*x*y, x*y^2, 6*x^3))
assert(I : (J1+J2) == ideal(8*y^2, 3*x*y, 6*x^3))
for strategy in {Quotient, Iterate} do
assert(quotient(I, J1, Strategy => strategy) == ideal(8*y^2, 3*x*y, x*y^2, 6*x^3))
///
i6 : code first tests Saturation
o6 = -- /home/mahrud/Projects/M2/quickfix/M2/Macaulay2/packages/Saturation/quotient-test.m2:11:1: location of test code
R = ZZ[x, y];
I = ideal(6*x^3, 9*x*y, 8*y^2);
J1 = ideal(-3, x^2);
J2 = ideal(4*y);
assert(intersect(I:J1, I:J2) == ideal(8*y^2, 3*x*y, x*y^2, 6*x^3))
assert(I : (J1+J2) == ideal(8*y^2, 3*x*y, 6*x^3))
for strategy in {Quotient, Iterate} do
assert(quotient(I, J1, Strategy => strategy) == ideal(8*y^2, 3*x*y, x*y^2, 6*x^3))
i7 :
It works now!
That was because
I'd rather stick with the current behavior for Emacs clickability.
I've added
|
M2/Macaulay2/m2/testing.m2
Outdated
(minimizeFilename currentFileName, currentRowNumber(), teststring); | ||
currentPackage#"test number" = n + 1;) | ||
n := #currentPackage#"test inputs"; | ||
if opts.FileName then ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this option ever used? I have seen TEST get "test.m2"
but never this option. Wouldn't be opposed to deprecating it for simplicity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh actually this seems like a bug:
i1 : TEST get "../../Macaulay2/packages/Macaulay2Doc/demo1.m2"
i2 : tests User
o2 = {0 => TestInput[stdio:-13:1-1:80]}
i3 : locate oo
o3 = {0 => (stdio:-13:1-1:80)}
i4 : code oo
o4 = stdio:-13:1-1:80: --source code:
-- This is the beginning of your Macaulay2 log stored at /home/mahrud/.Macaulay2/history.m2
Sorry to be making this PR more complicated for you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FileName
option is used for all the Core
tests. JSON
too. I'm not sure if there are any others -- it's relatively new.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yeah that's a tricky bug. I think it's probably always existed for locate
, since it assumes we're calling TEST
on a literal string and not the output of some function. It's just now that code
is calling locate
, it's showing up there, too.
I guess the documentation for TEST
could discourage the use of get
for this reason, and we could modify the handful of tests that currently use it. (I'm only counting 13.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's first try to find a way to fix the bug because I'd rather keep allowing TEST get ...
, it's much simpler than using an option.
Can you say more about how you use this? e.g. I would imagine |
My initial rationale for introducing So now, if we see on some log that |
This way, "tests" will work like other similar functions like "methods" and "about".
Avoids unnecessary parentheses in output of "tests".
Rather than storing the filename and line number separately, we store a FilePosition containing both of them. We update locate(TestInput) to use this. We also remove the redundant source file stamp from the code -- there's no reason to also store the file location here. Finally, we remove the NewFromMethod for constructing a TestInput from a sequence. There was really no reason to use this, as we only construct a TestInput object once, inside TEST.
Now returns source code of test. Update an error message when "check" is called with the Verbose option that previously used the old toString behavior.
Now returns a DIV like other "code" methods.
Now that the test inputs are stored in a list, we can just use the length of the list.
2189d5c
to
314ae63
Compare
I've fixed the test location bug, which required turning I also added the ability for i1 : TEST get "/usr/share/Macaulay2/Macaulay2Doc/demo1.m2"
i2 : TEST openIn "/usr/share/Macaulay2/Macaulay2Doc/demo1.m2"
i3 : tests User
o3 = {0 => TestInput[stdio:1:5-1:53] }
{1 => TestInput[/usr/share/Macaulay2/Macaulay2Doc/demo1.m2:1:1-14:9]}
o3 : NumberedVerticalList
i4 : code oo
o4 = stdio:1:5-1:53: --source code:
TEST get "/usr/share/Macaulay2/Macaulay2Doc/demo1.m2"
---------------------------------------------------------------------------
/usr/share/Macaulay2/Macaulay2Doc/demo1.m2:1:1-14:9: --source code:
-- when running examples, we usually specify the --stop option
-- here we reverse that so we can demonstrate the debugger in an example
stopIfError = false
debuggingMode = true
f := x -> (
a := "hi there";
b := 1/x;
b+1)
g = y -> (
c := f(y-1);
d := f(y-2);
c+d) |
In principle this sounds useful, but I can totally imagine it becoming a pain to figure out where a test file was loaded from! |
Great point! I'll remove the |
7540242
to
234900b
Compare
By the way, one benefit of turning TEST into a keyword is that the content in front of it doesn't have to be a string anymore. It could literally be Not necessarily suggesting doing this now, but worth considering. |
@@ -1248,6 +1248,7 @@ TEST /// | |||
|
|||
TEST | |||
/// -- DON'T TEST YET?? | |||
-- no-check-flag (encountered an unknown key or option: Engine) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikestillman - This test appears to never have been run since TEST
and the test string were on separate lines. After changing TEST
to a keyword, the test does get run, but it fails because LLL
doesn't have an Engine
option.
I'm proposing that we continue skipping it for now (which no-check-flag
takes care of), but I figured I'd tag you in case you'd like to take a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there an engine implementation that got removed or never got added? Seems strange.
M2/Macaulay2/packages/JSON.m2
Outdated
|
||
TEST(currentPackage#"source directory" | "JSON/test-encode.m2", | ||
FileName => true) | ||
TEST get(currentPackage#"source directory" | "JSON/test-parse.m2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just TEST "./JSON/..."
should always work, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't :( I get the following:
i1 : check "JSON"
../src/macaulay2/M2/M2/Macaulay2/packages/JSON.m2:361:0:(2):[18]: error: opening input file "./JSON/test-parse.m2" failed: No such file or directory
I think it depends on the value of currentDirectory()
. If I changeDirectory
into the packages directory, then it works just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm but load "./..."
works correctly. What's the difference? Does TEST(currentFileDirectory | ...)
work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it works with currentFileDirectory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, the difference is that load
looks everywhere under path
but get
doesn't. A little strange to be honest.
2490ad9
to
421482f
Compare
I'm hesitant about the broader interpreter changes in this PR. Could you scale back this PR to just the new |
|
||
TEST(currentPackage#"source directory" | "JSON/test-encode.m2", | ||
FileName => true) | ||
TEST get(currentPackage#"auxiliary files" | "test-parse.m2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this line, I would be more confused about where to look for that file than before. You can of course go with whatever solution you prefer in your package.
This way, we can access its argument while it's still a Code object and properly determine its location rather than guessing.
check(2, "LLLBases") wasn't previously being registered since TEST and the test string were on different lines. Now it's picked up, but it raises an error (unknown key: Engine), so we skip it
421482f
to
690105d
Compare
Hmm one last thing that comes to mind: is there an easy way to make sure none of the undistributed-packages stop working because of this change to |
I checked the undistributed packages locally on this branch. A good chunk of them don't even load -- perhaps why they're undistributed -- but the tests pass for the rest of them: -- warning: CacheFileName has no tests
-- warning: CodepthThree did not load
-- warning: CustomEngineTests did not load
-- capturing check(0, "ExampleFreeResolutions") -- .102555s elapsed
-- capturing check(1, "ExampleFreeResolutions") -- .0819185s elapsed
-- capturing check(2, "ExampleFreeResolutions") -- .105076s elapsed
-- running check(3, "ExampleFreeResolutions") -- 1.68029s elapsed
-- warning: ExampleIdeals has no tests
-- warning: FastLinearAlgebra did not load
-- warning: FreeResolutions has no tests
-- warning: FrobeniusMultiplicities did not load
-- warning: Functoriality did not load
-- capturing check(0, "GenerateD") -- .0782202s elapsed
-- capturing check(1, "GenerateD") -- .078785s elapsed
-- capturing check(2, "GenerateD") -- .082572s elapsed
-- capturing check(3, "GenerateD") -- .0757686s elapsed
-- capturing check(4, "GenerateD") -- .0796765s elapsed
-- running check(5, "GenerateD") -- 3.36057s elapsed
-- capturing check(6, "GenerateD") -- .0784762s elapsed
-- warning: MemoryLeaks did not load
-- capturing check(0, "MGBInterface") -- .114109s elapsed
-- capturing check(1, "MGBInterface") -- .091242s elapsed
-- running check(2, "MGBInterface") -- 3.44805s elapsed
-- running check(3, "MGBInterface") -- 1.77514s elapsed
-- running check(4, "MGBInterface") -- 1.74921s elapsed
-- running check(5, "MGBInterface") -- 1.79347s elapsed
-- running check(6, "MGBInterface") -- 4.34543s elapsed
-- warning: Mysql did not load
-- capturing check(0, "NAGtools") -- 1.14616s elapsed
-- warning: ParameterSchemes did not load
-- warning: Polyhedra2 did not load
-- warning: PolyhedralObjects did not load
-- warning: PolymakeInterface did not load
-- warning: RandomSearch has no tests
-- warning: RisaAsir did not load
-- warning: Sage did not load
-- warning: SchurRingsOld has no tests
-- warning: SecondPackage did not load
-- warning: SuffixTrees has no tests
-- warning: ToricCohomology did not load |
This is a matter for another time, but this isn't great. If the undistributed packages don't load, what's the point of keeping them? |
assert Equation(code pkgtest, expectedCode) | ||
assert Equation(code 0, expectedCode) | ||
|
||
assert Equation(toSequence locate pkgtest, (testpkg, 3, 5, 3, 32, 3, 5)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This happened in a brew build:
-- running check(357, "Core") -- .380111s elapsed
/opt/homebrew/Cellar/macaulay2/1.24.11-rc1/share/doc/Macaulay2/Core/tests/testing.m2:1:1 error:
-- i5 : pkgtest = tests(0, "TestPackage")
--
-- o5 = TestInput[../../M2-93313-0/0.m2:3:5-3:32]
--
-- o5 : TestInput
--
-- i6 : assert instance(pkgtest, TestInput)
--
-- i7 : assert Equation(toSequence locate pkgtest, (testpkg, 3, 5, 3, 32, 3, 5))
-- stdio:10:6:(3): error: assertion failed:
-- (../../M2-93313-0/0.m2, 3, 5, 3, 32, 3, 5) == (/private/tmp/M2-93313-0/0.m2, 3, 5, 3, 32, 3, 5) is false
--
stdio:1:5:(3): error: test(s) #333 of package Core failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that makes sense. Calling minimizeFilename
should fix it. I'll open a PR.
This way,
tests
will work like other similar functions likemethods
andabout
.As suggested by @mahrud in #3418 (comment).
Before
After
Another neat consequence that we get for free is negative indices work: