github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/modules/modules_test.go (about) 1 package modules 2 3 import ( 4 "encoding/json" 5 "os" 6 "strings" 7 "testing" 8 9 _ "github.com/lmorg/murex/builtins/core/structs" 10 "github.com/lmorg/murex/config/profile" 11 "github.com/lmorg/murex/lang" 12 "github.com/lmorg/murex/test/count" 13 "github.com/lmorg/murex/utils/consts" 14 ) 15 16 var ( 17 // Test Package 18 19 testPackage = "TestPackage" 20 21 testJsonPackage = profile.Package{ 22 Name: testPackage, 23 Version: "0.0", 24 } 25 26 // Test Module 2 27 28 testModule1 = "TestModule1" 29 30 testJsonModule1 = profile.Module{ 31 Name: testModule1, 32 Summary: "ūnus", 33 Version: "1.0", 34 Source: "one.mx", 35 Dependencies: profile.Dependencies{ 36 Required: []string{ 37 "go", 38 }, 39 Platform: []string{ 40 "any", 41 }, 42 }, 43 } 44 45 testFunction1 = "modules.testMxSource1" 46 testMxSource1 = "function " + testFunction1 + " {}" 47 48 // Test Module 2 49 50 testModule2 = "TestModule2" 51 52 testJsonModule2 = profile.Module{ 53 Name: testModule2, 54 Summary: "duo", 55 Version: "2.0", 56 Source: "two.mx", 57 Dependencies: profile.Dependencies{ 58 Required: []string{ 59 "go", 60 }, 61 Platform: []string{ 62 "any", 63 }, 64 }, 65 } 66 67 testFunction2 = "modules.testMxSource2" 68 testMxSource2 = "function " + testFunction2 + " {}" 69 70 testJsonModules = []profile.Module{ 71 testJsonModule1, 72 testJsonModule2, 73 } 74 ) 75 76 func testModulesWriteBytes(t *testing.T, name, path string, contents []byte) { 77 t.Helper() 78 79 file, err := os.OpenFile(path+name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0640) 80 if err != nil { 81 t.Fatalf("Error initializing %s: %s", name, err.Error()) 82 } 83 84 _, err = file.Write(contents) 85 if err != nil { 86 t.Fatalf("Error initializing %s: %s", name, err.Error()) 87 } 88 89 if file.Close() != nil { 90 t.Fatalf("Error closing %s: %s", name, err.Error()) 91 } 92 } 93 94 func testModulesWriteStruct(t *testing.T, name, path string, v interface{}) { 95 t.Helper() 96 97 b, err := json.MarshalIndent(v, "", " ") 98 if err != nil { 99 t.Fatalf("Error initializing %s: %s", name, err.Error()) 100 } 101 102 testModulesWriteBytes(t, name, path, b) 103 } 104 105 func vToString(t *testing.T, v interface{}) string { 106 t.Helper() 107 108 b, err := json.MarshalIndent(v, "", " ") 109 if err != nil { 110 t.Fatalf("Error creating JSON from %T: %s", v, err.Error()) 111 } 112 return string(b) 113 } 114 115 // TestModulesAndCustomPaths tests a range of functionality from the env var 116 // custom paths to a lot of the code surrounding loading, enabling and disabling 117 // modules and packages 118 func TestModulesAndCustomPaths(t *testing.T) { 119 var ( 120 preloadFileName = "preload_TestModulesAndCustomPaths.mx" 121 modulesPathName = "modules_TestModulesAndCustomPaths.d/" 122 profileFileName = "profile_TestModulesAndCustomPaths.mx" 123 ) 124 125 path := t.TempDir() 126 127 // get running settings 128 129 bakPreload := os.Getenv(profile.PreloadEnvVar) 130 bakModule := os.Getenv(profile.ModuleEnvVar) 131 bakProfile := os.Getenv(profile.ProfileEnvVar) 132 133 defer func() { 134 if err := os.Setenv(profile.PreloadEnvVar, bakPreload); err != nil { 135 t.Errorf("Unable to restore env var settings: '%s' to '%s'", profile.PreloadEnvVar, bakPreload) 136 } 137 138 if err := os.Setenv(profile.ModuleEnvVar, bakModule); err != nil { 139 t.Errorf("Unable to restore env var settings: '%s' to '%s'", profile.ModuleEnvVar, bakModule) 140 } 141 142 if err := os.Setenv(profile.ProfileEnvVar, bakProfile); err != nil { 143 t.Errorf("Unable to restore env var settings: '%s' to '%s'", profile.ProfileEnvVar, bakProfile) 144 } 145 }() 146 147 // set env vars 148 149 if err := os.Setenv(profile.PreloadEnvVar, path+preloadFileName); err != nil { 150 t.Errorf("Unable to set env var %s: %s", profile.PreloadEnvVar, err.Error()) 151 } 152 153 if err := os.Setenv(profile.ModuleEnvVar, path+modulesPathName); err != nil { 154 t.Errorf("Unable to set env var %s: %s", profile.ModuleEnvVar, err.Error()) 155 } 156 157 if err := os.Setenv(profile.ProfileEnvVar, path+profileFileName); err != nil { 158 t.Errorf("Unable to set env var %s: %s", profile.ProfileEnvVar, err.Error()) 159 } 160 161 // initialize empty directory structures 162 163 lang.InitEnv() 164 profile.Execute(profile.F_MODULES) 165 166 // initialize test package 167 168 packagePath := path + modulesPathName + consts.PathSlash + "TestPackage" + consts.PathSlash 169 if err := os.Mkdir(packagePath, 0777); err != nil && !strings.Contains(err.Error(), "file exists") { 170 t.Fatalf("Unable to initialize test package: Cannot create dir: %s", err.Error()) 171 } 172 173 testModulesWriteStruct(t, "package.json", packagePath, testJsonPackage) 174 testModulesWriteStruct(t, "module.json", packagePath, testJsonModules) 175 testModulesWriteBytes(t, "one.mx", packagePath, []byte(testMxSource1)) 176 testModulesWriteBytes(t, "two.mx", packagePath, []byte(testMxSource2)) 177 178 // import new packages 179 180 count.Tests(t, 1) // importing from non-standard location 181 profile.Execute(profile.F_MODULES) 182 183 if !lang.MxFunctions.Exists(testFunction1) || !lang.MxFunctions.Exists(testFunction2) { 184 t.Fatalf("test functions were not imported from test package. Reason: unknown\n%s\nTry deleting '%s' and then rerun", 185 vToString(t, lang.MxFunctions.Dump()), path+modulesPathName+consts.PathSlash) 186 } 187 188 // run tests 189 190 count.Tests(t, 2) 191 list, err := listModulesLoadNotLoad(lang.ShellProcess, true) 192 if err != nil { 193 t.Fatalf("Error in listModulesLoadNotLoad(true): %s", err.Error()) 194 } 195 if len(list) != 2 || list[testPackage+"/"+testModule1] == "" || list[testPackage+"/"+testModule2] == "" { 196 t.Fatalf("listModulesLoadNotLoad(true) has returned an unexpected list:\n%s", vToString(t, list)) 197 } 198 199 count.Tests(t, 2) 200 list, err = listModulesEnDis(lang.ShellProcess, true) 201 if err != nil { 202 t.Fatalf("Error in listModulesLoadNotLoad(true): %s", err.Error()) 203 } 204 if len(list) != 3 || list[testPackage] == "" || 205 list[testPackage+"/"+testModule1] == "" || 206 list[testPackage+"/"+testModule2] == "" { 207 t.Fatalf("listModulesLoadNotLoad(true) has returned an unexpected list:\n%s", vToString(t, list)) 208 } 209 210 count.Tests(t, 3) 211 var disabled []string 212 err = profile.ReadJson(profile.ModulePath()+profile.DisabledFile, &disabled) 213 if err != nil { 214 t.Fatalf("profile.ReadJson() err: %s", err.Error()) 215 } 216 217 err = disableMod(testPackage+"/"+testModule1, &disabled) 218 if err != nil { 219 t.Fatalf("disableMod() err: %s", err.Error()) 220 } 221 err = writeDisabled(&disabled) 222 if err != nil { 223 t.Fatalf("writeDisabled() err: %s", err.Error()) 224 } 225 226 count.Tests(t, 2) 227 list, err = listModulesEnDis(lang.ShellProcess, false) 228 if err != nil { 229 t.Fatalf("Error in listModulesEnDis(true): %s", err.Error()) 230 } 231 if len(list) != 1 || list[testPackage] != "" || 232 list[testPackage+"/"+testModule1] == "" || 233 list[testPackage+"/"+testModule2] != "" { 234 t.Fatalf("listModulesEnDis(true) has returned an unexpected list:\n%s", vToString(t, list)) 235 } 236 237 count.Tests(t, 3) 238 err = profile.ReadJson(profile.ModulePath()+profile.DisabledFile, &disabled) 239 if err != nil { 240 t.Fatalf("profile.ReadJson() err: %s", err.Error()) 241 } 242 243 disabled, err = enableMod(testPackage+"/"+testModule1, disabled) 244 if err != nil { 245 t.Fatalf("enableMod() err: %s", err.Error()) 246 } 247 err = writeDisabled(&disabled) 248 if err != nil { 249 t.Fatalf("writeDisabled() err: %s", err.Error()) 250 } 251 252 count.Tests(t, 2) 253 list, err = listModulesEnDis(lang.ShellProcess, true) 254 if err != nil { 255 t.Fatalf("Error in listModulesEnDis(true): %s", err.Error()) 256 } 257 if len(list) != 3 || list[testPackage] == "" || 258 list[testPackage+"/"+testModule1] == "" || 259 list[testPackage+"/"+testModule2] == "" { 260 t.Fatalf("listModulesEnDis(true) has returned an unexpected list:\n%s", vToString(t, list)) 261 } 262 263 }