|
1 | 1 | classdef TestCylinder < matlab.unittest.TestCase |
2 | 2 | methods (Test) |
3 | 3 | function smokeRun(testCase) |
4 | | - % This test simply verifies that the cylinder.m script can run |
5 | | - % without errors when the CI environment variable is set |
| 4 | + % Test that the cylinder.m script runs without errors in CI environment |
6 | 5 |
|
7 | 6 | % Set CI environment variable to ensure short run |
8 | 7 | setenv('CI', 'true'); |
9 | 8 |
|
10 | 9 | % Set up paths |
11 | 10 | setup_paths(); |
12 | 11 |
|
13 | | - % We'll use evalin('base') to run the script in the base workspace |
14 | | - % This avoids the issue with the script clearing variables |
| 12 | + % Test that the script runs successfully |
15 | 13 | try |
16 | | - evalin('base', 'success = false; errorMsg = ""; try, run(''cylinder.m''); success = true; catch ME, errorMsg = ME.message; end'); |
| 14 | + % Run the script and capture any errors |
| 15 | + evalin('base', 'clear; success = false; errorMsg = "";'); |
| 16 | + evalin('base', 'try; run(''cylinder.m''); success = true; catch ME; errorMsg = ME.message; end;'); |
17 | 17 |
|
18 | 18 | % Check if the script ran successfully |
19 | 19 | success = evalin('base', 'success'); |
| 20 | + |
20 | 21 | if success |
21 | | - fprintf('✅ Script executed successfully without errors!\n'); |
22 | | - testCase.verifyTrue(true, 'Cylinder script ran without errors'); |
| 22 | + fprintf('✅ Cylinder script executed successfully without errors!\n'); |
| 23 | + testCase.verifyTrue(true, 'Cylinder script completed successfully'); |
23 | 24 | else |
24 | 25 | errorMsg = evalin('base', 'errorMsg'); |
25 | | - fprintf('❌ Script failed with error: %s\n', errorMsg); |
26 | | - testCase.verifyTrue(false, sprintf('Cylinder script failed with error: %s', errorMsg)); |
| 26 | + fprintf('❌ Cylinder script failed with error: %s\n', errorMsg); |
| 27 | + testCase.verifyTrue(false, sprintf('Cylinder script failed: %s', errorMsg)); |
27 | 28 | end |
| 29 | + |
28 | 30 | catch ME |
29 | | - fprintf('❌ Test framework failed with error: %s\n', ME.message); |
30 | | - testCase.verifyTrue(false, sprintf('Test framework failed with error: %s', ME.message)); |
| 31 | + fprintf('❌ Test execution failed: %s\n', ME.message); |
| 32 | + testCase.verifyTrue(false, sprintf('Test execution failed: %s', ME.message)); |
31 | 33 | end |
32 | 34 | end |
33 | 35 |
|
34 | | - function testConfigFile(testCase) |
35 | | - % Test that the configuration file exists and contains all required parameters |
| 36 | + function testConfigFileExists(testCase) |
| 37 | + % Test that the configuration file exists and loads correctly |
36 | 38 | try |
37 | | - % Set up paths |
38 | 39 | setup_paths(); |
39 | 40 |
|
40 | 41 | % Check that config.m exists |
41 | | - testCase.verifyTrue(exist('config.m', 'file') > 0, 'Configuration file config.m should exist'); |
| 42 | + testCase.verifyTrue(exist('config.m', 'file') > 0, 'config.m file should exist'); |
42 | 43 |
|
43 | | - % Load the config file and check for required parameters |
| 44 | + % Test that config function can be called |
44 | 45 | cfg = config(); |
| 46 | + testCase.verifyTrue(isstruct(cfg), 'config() should return a structure'); |
45 | 47 |
|
46 | | - % Check domain parameters |
| 48 | + % Check for essential fields |
47 | 49 | testCase.verifyTrue(isfield(cfg, 'domain'), 'Config should have domain field'); |
48 | | - testCase.verifyTrue(isfield(cfg.domain, 'x_min'), 'Config should have domain.x_min'); |
49 | | - testCase.verifyTrue(isfield(cfg.domain, 'x_max'), 'Config should have domain.x_max'); |
50 | | - |
51 | | - % Check mesh parameters |
52 | 50 | testCase.verifyTrue(isfield(cfg, 'mesh'), 'Config should have mesh field'); |
53 | | - testCase.verifyTrue(isfield(cfg.mesh, 'cylinder_radius'), 'Config should have mesh.cylinder_radius'); |
54 | | - |
55 | | - % Check simulation parameters |
56 | 51 | testCase.verifyTrue(isfield(cfg, 'simulation'), 'Config should have simulation field'); |
57 | | - testCase.verifyTrue(isfield(cfg.simulation, 'reynolds_number'), 'Config should have simulation.reynolds_number'); |
58 | | - testCase.verifyTrue(isfield(cfg.simulation, 'num_time_steps'), 'Config should have simulation.num_time_steps'); |
59 | 52 |
|
60 | | - % Check RBF parameters |
61 | | - testCase.verifyTrue(isfield(cfg, 'rbf'), 'Config should have rbf field'); |
62 | | - testCase.verifyTrue(isfield(cfg.rbf, 'stencil_size_main'), 'Config should have rbf.stencil_size_main'); |
63 | | - |
64 | | - fprintf('✅ Configuration file contains all required parameters!\n'); |
| 53 | + fprintf('✅ Configuration file test passed!\n'); |
65 | 54 |
|
66 | 55 | catch ME |
67 | | - fprintf('❌ Config file test failed: %s\n', ME.message); |
| 56 | + fprintf('❌ Configuration file test failed: %s\n', ME.message); |
68 | 57 | testCase.verifyTrue(false, sprintf('Configuration file test failed: %s', ME.message)); |
69 | 58 | end |
70 | 59 | end |
71 | 60 |
|
72 | | - function testNoMagicNumbers(testCase) |
73 | | - % Test that magic numbers have been eliminated (spot check) |
| 61 | + function testMainScriptStructure(testCase) |
| 62 | + % Test that the main script has the expected structure |
74 | 63 | try |
75 | | - % Set up paths |
76 | 64 | setup_paths(); |
77 | 65 |
|
78 | | - scriptContent = fileread('cylinder.m'); |
79 | | - |
80 | | - % These magic numbers should no longer appear directly in the code |
81 | | - % Check for direct use of magic numbers that should be in config |
82 | | - magicNumberPatterns = { |
83 | | - 'k\s*=\s*35', |
84 | | - 'nu\s*=\s*1/100', |
85 | | - 'dt\s*=\s*1e-2', |
86 | | - 'Nt\s*=\s*5000', |
87 | | - 'radius\s*=\s*0\.5' |
88 | | - }; |
89 | | - |
90 | | - % Look for magic numbers in non-constant, non-comment lines |
91 | | - magicNumberFound = false; |
92 | | - problemLine = ''; |
93 | | - |
94 | | - lines = strsplit(scriptContent, '\n'); |
95 | | - for i = 1:length(lines) |
96 | | - line = lines{i}; |
97 | | - % Skip comments and empty lines |
98 | | - trimmedLine = strtrim(line); |
99 | | - if isempty(trimmedLine) || startsWith(trimmedLine, '%') |
100 | | - continue; |
101 | | - end |
102 | | - |
103 | | - % Skip the constants section at the top |
104 | | - if contains(line, 'Configuration Constants') || i < 50 |
105 | | - continue; |
106 | | - end |
107 | | - |
108 | | - % Check for magic number patterns |
109 | | - for p = 1:length(magicNumberPatterns) |
110 | | - if ~isempty(regexp(line, magicNumberPatterns{p}, 'once')) |
111 | | - magicNumberFound = true; |
112 | | - problemLine = line; |
113 | | - break; |
114 | | - end |
115 | | - end |
116 | | - |
117 | | - if magicNumberFound |
118 | | - break; |
119 | | - end |
120 | | - end |
| 66 | + % Check that cylinder.m exists |
| 67 | + testCase.verifyTrue(exist('cylinder.m', 'file') > 0, 'cylinder.m file should exist'); |
121 | 68 |
|
122 | | - testCase.verifyFalse(magicNumberFound, sprintf('Magic number found in line: %s', problemLine)); |
| 69 | + % Read the script content |
| 70 | + content = fileread('cylinder.m'); |
123 | 71 |
|
124 | | - fprintf('✅ Magic numbers have been properly replaced with config parameters!\n'); |
| 72 | + % Check for key components |
| 73 | + testCase.verifyTrue(contains(content, 'cfg = config()'), 'Script should load configuration'); |
| 74 | + testCase.verifyTrue(contains(content, 'isCI'), 'Script should check CI environment'); |
| 75 | + testCase.verifyTrue(contains(content, 'addpath'), 'Script should add distmesh path'); |
| 76 | + |
| 77 | + fprintf('✅ Main script structure test passed!\n'); |
125 | 78 |
|
126 | 79 | catch ME |
127 | | - fprintf('❌ Magic number test failed: %s\n', ME.message); |
128 | | - testCase.verifyTrue(false, sprintf('Magic number test failed: %s', ME.message)); |
| 80 | + fprintf('❌ Main script structure test failed: %s\n', ME.message); |
| 81 | + testCase.verifyTrue(false, sprintf('Main script structure test failed: %s', ME.message)); |
129 | 82 | end |
130 | 83 | end |
131 | 84 |
|
132 | | - function testConfigUsage(testCase) |
133 | | - % Test that cylinder.m uses the config file |
| 85 | + function testDependenciesExist(testCase) |
| 86 | + % Test that required dependencies exist |
134 | 87 | try |
135 | | - % Set up paths |
136 | 88 | setup_paths(); |
137 | 89 |
|
138 | | - scriptContent = fileread('cylinder.m'); |
139 | | - |
140 | | - % Check that cylinder.m loads the config |
141 | | - testCase.verifyTrue(contains(scriptContent, 'cfg = config()'), 'cylinder.m should load the config file'); |
| 90 | + % Check for essential files |
| 91 | + testCase.verifyTrue(exist('NS_2d_cylinder_PHS.m', 'file') > 0, 'NS_2d_cylinder_PHS.m should exist'); |
| 92 | + testCase.verifyTrue(exist('RBF_PHS_FD_all.m', 'file') > 0, 'RBF_PHS_FD_all.m should exist'); |
| 93 | + testCase.verifyTrue(exist('nearest_interp.m', 'file') > 0, 'nearest_interp.m should exist'); |
| 94 | + testCase.verifyTrue(exist('knnsearch.m', 'file') > 0, 'knnsearch.m should exist'); |
142 | 95 |
|
143 | | - % Check that cylinder.m uses config parameters |
144 | | - testCase.verifyTrue(contains(scriptContent, 'cfg.domain'), 'cylinder.m should use domain parameters from config'); |
145 | | - testCase.verifyTrue(contains(scriptContent, 'cfg.mesh'), 'cylinder.m should use mesh parameters from config'); |
146 | | - testCase.verifyTrue(contains(scriptContent, 'cfg.simulation'), 'cylinder.m should use simulation parameters from config'); |
147 | | - testCase.verifyTrue(contains(scriptContent, 'cfg.rbf'), 'cylinder.m should use RBF parameters from config'); |
| 96 | + % Check for distmesh directory |
| 97 | + testCase.verifyTrue(exist('distmesh', 'dir') > 0, 'distmesh directory should exist'); |
148 | 98 |
|
149 | | - fprintf('✅ cylinder.m correctly uses the configuration file!\n'); |
| 99 | + fprintf('✅ Dependencies test passed!\n'); |
150 | 100 |
|
151 | 101 | catch ME |
152 | | - fprintf('❌ Config usage test failed: %s\n', ME.message); |
153 | | - testCase.verifyTrue(false, sprintf('Config usage test failed: %s', ME.message)); |
| 102 | + fprintf('❌ Dependencies test failed: %s\n', ME.message); |
| 103 | + testCase.verifyTrue(false, sprintf('Dependencies test failed: %s', ME.message)); |
154 | 104 | end |
155 | 105 | end |
156 | 106 | end |
|
0 commit comments