diff --git a/test/unit/FiniteDifferenceStencilsTests.wl b/test/unit/FiniteDifferenceStencilsTests.wl new file mode 100644 index 0000000..04e804f --- /dev/null +++ b/test/unit/FiniteDifferenceStencilsTests.wl @@ -0,0 +1,138 @@ +(* ::Package:: *) + +(* FiniteDifferenceStencilsTests.wl *) +(* Unit tests for Generato`FiniteDifferenceStencils module *) + +Print["Loading FiniteDifferenceStencilsTests.wl..."]; + +(* Load Generato *) +Needs["xAct`xCoba`", FileNameJoin[{Environment["GENERATO"], "src/Generato.wl"}]]; + +(* ========================================= *) +(* Test: GetCenteringStencils *) +(* ========================================= *) + +VerificationTest[ + (* Order 2 should return {-1, 0, 1} *) + GetCenteringStencils[2], + {-1, 0, 1}, + TestID -> "GetCenteringStencils-Order2" +]; + +VerificationTest[ + (* Order 4 should return {-2, -1, 0, 1, 2} *) + GetCenteringStencils[4], + {-2, -1, 0, 1, 2}, + TestID -> "GetCenteringStencils-Order4" +]; + +VerificationTest[ + (* Order 6 should return {-3, -2, -1, 0, 1, 2, 3} *) + GetCenteringStencils[6], + {-3, -2, -1, 0, 1, 2, 3}, + TestID -> "GetCenteringStencils-Order6" +]; + +VerificationTest[ + (* Order 8 should return {-4, -3, -2, -1, 0, 1, 2, 3, 4} *) + GetCenteringStencils[8], + {-4, -3, -2, -1, 0, 1, 2, 3, 4}, + TestID -> "GetCenteringStencils-Order8" +]; + +VerificationTest[ + (* Order 12 should have 13 points *) + Length[GetCenteringStencils[12]], + 13, + TestID -> "GetCenteringStencils-Order12-Length" +]; + +(* ========================================= *) +(* Test: GetFiniteDifferenceCoefficients *) +(* ========================================= *) + +VerificationTest[ + (* First derivative, order 2: coefficients should be -1/2, 0, 1/2 *) + coeffs = GetFiniteDifferenceCoefficients[{-1, 0, 1}, 1]; + {Subscript[c, -1], Subscript[c, 0], Subscript[c, 1]} /. coeffs, + {-1/2, 0, 1/2}, + TestID -> "GetFDCoefficients-FirstDeriv-Order2" +]; + +VerificationTest[ + (* Second derivative, order 2: coefficients should be 1, -2, 1 *) + coeffs = GetFiniteDifferenceCoefficients[{-1, 0, 1}, 2]; + {Subscript[c, -1], Subscript[c, 0], Subscript[c, 1]} /. coeffs, + {1, -2, 1}, + TestID -> "GetFDCoefficients-SecondDeriv-Order2" +]; + +VerificationTest[ + (* First derivative, order 4: known coefficients *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 1]; + {Subscript[c, -2], Subscript[c, -1], Subscript[c, 0], Subscript[c, 1], Subscript[c, 2]} /. coeffs, + {1/12, -2/3, 0, 2/3, -1/12}, + TestID -> "GetFDCoefficients-FirstDeriv-Order4" +]; + +VerificationTest[ + (* Second derivative, order 4: known coefficients *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 2]; + {Subscript[c, -2], Subscript[c, -1], Subscript[c, 0], Subscript[c, 1], Subscript[c, 2]} /. coeffs, + {-1/12, 4/3, -5/2, 4/3, -1/12}, + TestID -> "GetFDCoefficients-SecondDeriv-Order4" +]; + +VerificationTest[ + (* Coefficients should be returned as a list of rules *) + coeffs = GetFiniteDifferenceCoefficients[{-1, 0, 1}, 1]; + MatchQ[coeffs, {__Rule}], + True, + TestID -> "GetFDCoefficients-ReturnsRules" +]; + +VerificationTest[ + (* Order 6 first derivative center coefficient should be 0 *) + coeffs = GetFiniteDifferenceCoefficients[{-3, -2, -1, 0, 1, 2, 3}, 1]; + Subscript[c, 0] /. coeffs, + 0, + TestID -> "GetFDCoefficients-Order6-CenterIsZero" +]; + +VerificationTest[ + (* Coefficients should sum to 0 for first derivative *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 1]; + Total[{Subscript[c, -2], Subscript[c, -1], Subscript[c, 0], Subscript[c, 1], Subscript[c, 2]} /. coeffs], + 0, + TestID -> "GetFDCoefficients-FirstDeriv-SumToZero" +]; + +VerificationTest[ + (* Coefficients should sum to 0 for second derivative *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 2]; + Total[{Subscript[c, -2], Subscript[c, -1], Subscript[c, 0], Subscript[c, 1], Subscript[c, 2]} /. coeffs], + 0, + TestID -> "GetFDCoefficients-SecondDeriv-SumToZero" +]; + +VerificationTest[ + (* First derivative coefficients should be antisymmetric *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 1]; + cm2 = Subscript[c, -2] /. coeffs; + cp2 = Subscript[c, 2] /. coeffs; + cm2 == -cp2, + True, + TestID -> "GetFDCoefficients-FirstDeriv-Antisymmetric" +]; + +VerificationTest[ + (* Second derivative coefficients should be symmetric *) + coeffs = GetFiniteDifferenceCoefficients[{-2, -1, 0, 1, 2}, 2]; + cm2 = Subscript[c, -2] /. coeffs; + cp2 = Subscript[c, 2] /. coeffs; + cm2 == cp2, + True, + TestID -> "GetFDCoefficients-SecondDeriv-Symmetric" +]; + +Print["FiniteDifferenceStencilsTests.wl completed."]; diff --git a/test/unit/InterfaceTests.wl b/test/unit/InterfaceTests.wl index 96613a4..82611ad 100644 --- a/test/unit/InterfaceTests.wl +++ b/test/unit/InterfaceTests.wl @@ -2,7 +2,7 @@ (* InterfaceTests.wl *) (* Unit tests for Generato`Interface module *) -(* Tests: GridTensors, TileTensors, TempTensors *) +(* Tests: DefTensors, GridTensors, TileTensors, TempTensors, SetComponents, PrintEquations, PrintInitializations *) Print["Loading InterfaceTests.wl..."]; @@ -25,6 +25,34 @@ If[!MemberQ[$Manifolds, TestM3], DefMetric[1, testEuclid[-i, -j], testCD]; ]; +(* ========================================= *) +(* Test: DefTensors *) +(* ========================================= *) + +VerificationTest[ + (* DefTensors should return a list *) + result = DefTensors[{intDefScalar[], PrintAs -> "ids"}]; + ListQ[result], + True, + TestID -> "DefTensors-ReturnsList" +]; + +VerificationTest[ + (* DefTensors should define tensor without error *) + DefTensors[{intDefVec[i], PrintAs -> "idv"}]; + True, + True, + TestID -> "DefTensors-NoError" +]; + +VerificationTest[ + (* DefTensors with symmetric tensor *) + DefTensors[{intDefSym[-i, -j], Symmetric[{-i, -j}], PrintAs -> "idsym"}]; + True, + True, + TestID -> "DefTensors-Symmetric-NoError" +]; + (* ========================================= *) (* Test: GridTensors *) (* ========================================= *) @@ -45,6 +73,14 @@ VerificationTest[ TestID -> "GridTensors-VectorComponents" ]; +VerificationTest[ + (* Scalar tensor *) + scalarVarlist = GridTensors[{intTestScalar[], PrintAs -> "its"}]; + Length[scalarVarlist] >= 1, + True, + TestID -> "GridTensors-Scalar" +]; + (* ========================================= *) (* Test: Symmetric Tensor *) (* ========================================= *) @@ -57,6 +93,34 @@ VerificationTest[ TestID -> "GridTensors-SymmetricComponents" ]; +(* ========================================= *) +(* Test: TileTensors *) +(* ========================================= *) + +VerificationTest[ + (* TileTensors should return a list *) + tileList = TileTensors[{intTestTile[i], PrintAs -> "itt"}]; + ListQ[tileList], + True, + TestID -> "TileTensors-ReturnsList" +]; + +VerificationTest[ + (* TileTensors vector should have 3 components *) + tileList = TileTensors[{intTestTile2[i], PrintAs -> "itt2"}]; + Length[tileList] >= 3, + True, + TestID -> "TileTensors-VectorComponents" +]; + +VerificationTest[ + (* TileTensors with symmetric tensor *) + tileSym = TileTensors[{intTestTileSym[-i, -j], Symmetric[{-i, -j}], PrintAs -> "itts"}]; + Length[tileSym] >= 6, + True, + TestID -> "TileTensors-SymmetricComponents" +]; + (* ========================================= *) (* Test: TempTensors *) (* ========================================= *) @@ -69,4 +133,215 @@ VerificationTest[ TestID -> "TempTensors-ReturnsList" ]; +VerificationTest[ + (* TempTensors vector should have 3 components *) + tempList = TempTensors[{intTestTemp2[i], PrintAs -> "itt2"}]; + Length[tempList] >= 3, + True, + TestID -> "TempTensors-VectorComponents" +]; + +VerificationTest[ + (* TempTensors with scalar *) + tempScalar = TempTensors[{intTestTempScalar[], PrintAs -> "itts"}]; + Length[tempScalar] >= 1, + True, + TestID -> "TempTensors-Scalar" +]; + +(* ========================================= *) +(* Test: SetComponents with options *) +(* ========================================= *) + +VerificationTest[ + (* SetComponents should work without options *) + testVarlist = {{intSetCompVec[i], PrintAs -> "iscv"}}; + SetComponents[testVarlist]; + True, + True, + TestID -> "SetComponents-NoOptions" +]; + +VerificationTest[ + (* SetComponents with WithoutGridPointIndex *) + testVarlist2 = {{intSetCompVec2[i], PrintAs -> "iscv2"}}; + SetComponents[{WithoutGridPointIndex -> True}, testVarlist2]; + True, + True, + TestID -> "SetComponents-WithoutGridPointIndex" +]; + +VerificationTest[ + (* SetComponents with UseTilePointIndex *) + testVarlist3 = {{intSetCompVec3[i], PrintAs -> "iscv3"}}; + SetComponents[{UseTilePointIndex -> True}, testVarlist3]; + True, + True, + TestID -> "SetComponents-UseTilePointIndex" +]; + +VerificationTest[ + (* SetComponents with IndependentIndexForEachVar *) + testVarlist4 = {{intSetCompVec4[i], PrintAs -> "iscv4"}}; + SetComponents[{IndependentIndexForEachVar -> False}, testVarlist4]; + True, + True, + TestID -> "SetComponents-IndependentIndexForEachVar" +]; + +(* ========================================= *) +(* Test: PrintEquations modes *) +(* ========================================= *) + +(* Setup test tensors and equations for PrintEquations tests *) +peqVarlist = GridTensors[{intPEQVec[i], PrintAs -> "peqv"}]; +SetEQN[intPEQVec[i_], 2 intPEQVec[i]]; + +VerificationTest[ + (* PrintEquations with Mode -> "Main" should not error *) + PrintEquations[{Mode -> "Main"}, peqVarlist]; + True, + True, + TestID -> "PrintEquations-ModeMain" +]; + +VerificationTest[ + (* PrintEquations with Mode -> "Temp" should not error *) + peqVarlist2 = TempTensors[{intPEQTemp[i], PrintAs -> "peqt"}]; + SetEQN[intPEQTemp[i_], intPEQVec[i]]; + PrintEquations[{Mode -> "Temp"}, peqVarlist2]; + True, + True, + TestID -> "PrintEquations-ModeTemp" +]; + +VerificationTest[ + (* PrintEquations with Mode -> "AddToMain" should not error *) + peqVarlist3 = GridTensors[{intPEQVec3[i], PrintAs -> "peqv3"}]; + SetEQN[intPEQVec3[i_], 3 intPEQVec[i]]; + PrintEquations[{Mode -> "AddToMain"}, peqVarlist3]; + True, + True, + TestID -> "PrintEquations-ModeAddToMain" +]; + +VerificationTest[ + (* PrintEquations with SuffixName option *) + peqVarlist4 = GridTensors[{intPEQVec4[i], PrintAs -> "peqv4"}]; + SetEQN[{SuffixName -> "testSuffix"}, intPEQVec4[i_], intPEQVec[i]]; + PrintEquations[{SuffixName -> "testSuffix", Mode -> "Main"}, peqVarlist4]; + True, + True, + TestID -> "PrintEquations-WithSuffixName" +]; + +(* ========================================= *) +(* Test: PrintInitializations modes *) +(* ========================================= *) + +pinitVarlist = GridTensors[{intPInitVec[i], PrintAs -> "pinv"}]; + +VerificationTest[ + (* PrintInitializations with Mode -> "Temp" *) + PrintInitializations[{Mode -> "Temp"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeTemp" +]; + +VerificationTest[ + (* PrintInitializations with Mode -> "MainOut" *) + PrintInitializations[{Mode -> "MainOut"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeMainOut" +]; + +VerificationTest[ + (* PrintInitializations with Mode -> "MainIn" *) + PrintInitializations[{Mode -> "MainIn"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeMainIn" +]; + +VerificationTest[ + (* PrintInitializations with Mode -> "MoreInOut" *) + PrintInitializations[{Mode -> "MoreInOut"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeMoreInOut" +]; + +(* ========================================= *) +(* Test: PrintInitializations TensorType options *) +(* ========================================= *) + +VerificationTest[ + (* PrintInitializations with TensorType -> "Scal" *) + pinitScalar = GridTensors[{intPInitScal[], PrintAs -> "pins"}]; + PrintInitializations[{Mode -> "Temp", TensorType -> "Scal"}, pinitScalar]; + True, + True, + TestID -> "PrintInitializations-TensorTypeScal" +]; + +VerificationTest[ + (* PrintInitializations with TensorType -> "Vect" *) + PrintInitializations[{Mode -> "Temp", TensorType -> "Vect"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-TensorTypeVect" +]; + +VerificationTest[ + (* PrintInitializations with TensorType -> "Smat" *) + pinitSym = GridTensors[{intPInitSym[-i, -j], Symmetric[{-i, -j}], PrintAs -> "pinsym"}]; + PrintInitializations[{Mode -> "Temp", TensorType -> "Smat"}, pinitSym]; + True, + True, + TestID -> "PrintInitializations-TensorTypeSmat" +]; + +(* ========================================= *) +(* Test: PrintInitializations StorageType options *) +(* ========================================= *) + +VerificationTest[ + (* PrintInitializations with StorageType -> "GF" *) + PrintInitializations[{Mode -> "Temp", StorageType -> "GF"}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-StorageTypeGF" +]; + +VerificationTest[ + (* PrintInitializations with StorageType -> "Tile" *) + pinitTile = TileTensors[{intPInitTileVec[i], PrintAs -> "pintv"}]; + PrintInitializations[{Mode -> "Temp", StorageType -> "Tile"}, pinitTile]; + True, + True, + TestID -> "PrintInitializations-StorageTypeTile" +]; + +(* ========================================= *) +(* Test: PrintInitializations Derivs mode *) +(* ========================================= *) + +VerificationTest[ + (* PrintInitializations with Mode -> "Derivs" and order/accuracy options *) + PrintInitializations[{Mode -> "Derivs", DerivsOrder -> 1, AccuracyOrder -> 4}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeDerivsOrder1" +]; + +VerificationTest[ + (* PrintInitializations with Mode -> "Derivs" and second order *) + PrintInitializations[{Mode -> "Derivs", DerivsOrder -> 2, AccuracyOrder -> 4}, pinitVarlist]; + True, + True, + TestID -> "PrintInitializations-ModeDerivsOrder2" +]; + Print["InterfaceTests.wl completed."]; diff --git a/test/unit/WritefileTests.wl b/test/unit/WritefileTests.wl new file mode 100644 index 0000000..5df7e25 --- /dev/null +++ b/test/unit/WritefileTests.wl @@ -0,0 +1,178 @@ +(* ::Package:: *) + +(* WritefileTests.wl *) +(* Unit tests for Generato`Writefile module *) + +Print["Loading WritefileTests.wl..."]; + +(* Load Generato *) +Needs["xAct`xCoba`", FileNameJoin[{Environment["GENERATO"], "src/Generato.wl"}]]; + +(* Suppress verbose output during tests *) +SetPVerbose[False]; +SetPrintDate[False]; + +(* ========================================= *) +(* Test: SetMainPrint and GetMainPrint *) +(* ========================================= *) + +VerificationTest[ + (* SetMainPrint should set content without error *) + SetMainPrint[Print["Test content"]]; + True, + True, + TestID -> "SetMainPrint-NoError" +]; + +VerificationTest[ + (* GetMainPrint should return something (not Null after setting) *) + SetMainPrint[1 + 1]; + result = GetMainPrint[]; + result === 2, + True, + TestID -> "GetMainPrint-ReturnsSetValue" +]; + +VerificationTest[ + (* SetMainPrint with string content *) + SetMainPrint["Hello World"]; + GetMainPrint[], + "Hello World", + TestID -> "SetMainPrint-StringContent" +]; + +VerificationTest[ + (* SetMainPrint with complex expression *) + SetMainPrint[{1, 2, 3}]; + GetMainPrint[], + {1, 2, 3}, + TestID -> "SetMainPrint-ListContent" +]; + +(* ========================================= *) +(* Test: WriteToFile *) +(* ========================================= *) + +VerificationTest[ + (* WriteToFile should create a file *) + testOutputFile = FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]; + If[FileExistsQ[testOutputFile], DeleteFile[testOutputFile]]; + SetMainPrint[Global`pr["// Test line"]]; + WriteToFile[testOutputFile]; + FileExistsQ[testOutputFile], + True, + TestID -> "WriteToFile-CreatesFile" +]; + +VerificationTest[ + (* Written file should contain the header comment *) + testOutputFile = FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]; + content = Import[testOutputFile, "Text"]; + StringContainsQ[content, "generato_test_output.hxx"], + True, + TestID -> "WriteToFile-ContainsFilename" +]; + +VerificationTest[ + (* Written file should contain "Produced with Generato" *) + testOutputFile = FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]; + content = Import[testOutputFile, "Text"]; + StringContainsQ[content, "Produced with Generato"], + True, + TestID -> "WriteToFile-ContainsGeneratoHeader" +]; + +VerificationTest[ + (* Written file should contain user content *) + testOutputFile = FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]; + content = Import[testOutputFile, "Text"]; + StringContainsQ[content, "Test line"], + True, + TestID -> "WriteToFile-ContainsUserContent" +]; + +(* Test with header macro enabled *) +VerificationTest[ + (* WriteToFile with header macro should include #ifndef guards *) + testOutputFile2 = FileNameJoin[{$TemporaryDirectory, "generato_test_macro.hxx"}]; + If[FileExistsQ[testOutputFile2], DeleteFile[testOutputFile2]]; + SetPrintHeaderMacro[True]; + SetMainPrint[Global`pr["// Macro test"]]; + WriteToFile[testOutputFile2]; + content = Import[testOutputFile2, "Text"]; + StringContainsQ[content, "#ifndef GENERATO_TEST_MACRO_HXX"], + True, + TestID -> "WriteToFile-HeaderMacroIfndef" +]; + +VerificationTest[ + (* Header macro should include #define *) + testOutputFile2 = FileNameJoin[{$TemporaryDirectory, "generato_test_macro.hxx"}]; + content = Import[testOutputFile2, "Text"]; + StringContainsQ[content, "#define GENERATO_TEST_MACRO_HXX"], + True, + TestID -> "WriteToFile-HeaderMacroDefine" +]; + +VerificationTest[ + (* Header macro should include #endif *) + testOutputFile2 = FileNameJoin[{$TemporaryDirectory, "generato_test_macro.hxx"}]; + content = Import[testOutputFile2, "Text"]; + StringContainsQ[content, "#endif"], + True, + TestID -> "WriteToFile-HeaderMacroEndif" +]; + +(* Reset header macro setting *) +SetPrintHeaderMacro[False]; + +(* ========================================= *) +(* Test: ReplaceGFIndexName *) +(* ========================================= *) + +VerificationTest[ + (* ReplaceGFIndexName should perform string replacement in file *) + testOutputFile3 = FileNameJoin[{$TemporaryDirectory, "generato_test_replace.txt"}]; + Export[testOutputFile3, "old_name = value;\n", "Text"]; + ReplaceGFIndexName[testOutputFile3, "old_name" -> "new_name"]; + content = Import[testOutputFile3, "Text"]; + StringContainsQ[content, "new_name"], + True, + TestID -> "ReplaceGFIndexName-ReplacesString" +]; + +VerificationTest[ + (* ReplaceGFIndexName should remove old string *) + testOutputFile3 = FileNameJoin[{$TemporaryDirectory, "generato_test_replace.txt"}]; + content = Import[testOutputFile3, "Text"]; + !StringContainsQ[content, "old_name"], + True, + TestID -> "ReplaceGFIndexName-RemovesOldString" +]; + +VerificationTest[ + (* ReplaceGFIndexName with multiple replacements *) + testOutputFile4 = FileNameJoin[{$TemporaryDirectory, "generato_test_multi.txt"}]; + Export[testOutputFile4, "alpha = 1; beta = 2;\n", "Text"]; + ReplaceGFIndexName[testOutputFile4, {"alpha" -> "ALPHA", "beta" -> "BETA"}]; + content = Import[testOutputFile4, "Text"]; + StringContainsQ[content, "ALPHA"] && StringContainsQ[content, "BETA"], + True, + TestID -> "ReplaceGFIndexName-MultipleReplacements" +]; + +(* Cleanup temporary files *) +If[FileExistsQ[FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]], + DeleteFile[FileNameJoin[{$TemporaryDirectory, "generato_test_output.hxx"}]] +]; +If[FileExistsQ[FileNameJoin[{$TemporaryDirectory, "generato_test_macro.hxx"}]], + DeleteFile[FileNameJoin[{$TemporaryDirectory, "generato_test_macro.hxx"}]] +]; +If[FileExistsQ[FileNameJoin[{$TemporaryDirectory, "generato_test_replace.txt"}]], + DeleteFile[FileNameJoin[{$TemporaryDirectory, "generato_test_replace.txt"}]] +]; +If[FileExistsQ[FileNameJoin[{$TemporaryDirectory, "generato_test_multi.txt"}]], + DeleteFile[FileNameJoin[{$TemporaryDirectory, "generato_test_multi.txt"}]] +]; + +Print["WritefileTests.wl completed."];