|
| 1 | +component extends="wheels.WheelsTest" { |
| 2 | + |
| 3 | + function run() { |
| 4 | + |
| 5 | + g = application.wo |
| 6 | + |
| 7 | + // The legacy plugins/ directory is deprecated (superseded by vendor/<name>/ |
| 8 | + // packages) and apps are expected to remove it. The plugin loader must not |
| 9 | + // error when it is absent — Lucee/Adobe return empty for a missing dir, but |
| 10 | + // stricter engines (e.g. RustCFML) throw on directory listing of a missing |
| 11 | + // path, which previously failed onApplicationStart. $folders()/$files() now |
| 12 | + // short-circuit to an empty query when the directory does not exist. |
| 13 | + describe("plugin loader with an absent plugins/ directory", () => { |
| 14 | + |
| 15 | + missingPath = "/wheels/tests/_assets/plugins/__this_directory_does_not_exist__" |
| 16 | + |
| 17 | + it("initializes without throwing when the plugins directory is missing", () => { |
| 18 | + var config = { |
| 19 | + path = "wheels", |
| 20 | + fileName = "Plugins", |
| 21 | + method = "$init", |
| 22 | + pluginPath = missingPath, |
| 23 | + deletePluginDirectories = false, |
| 24 | + overwritePlugins = false, |
| 25 | + loadIncompatiblePlugins = true |
| 26 | + } |
| 27 | + var state = {thrown = false} |
| 28 | + try { |
| 29 | + pluginObj = $pluginObj(config) |
| 30 | + } catch (any e) { |
| 31 | + state.thrown = true |
| 32 | + } |
| 33 | + expect(state.thrown).toBeFalse() |
| 34 | + }) |
| 35 | + |
| 36 | + it("$folders() returns an empty query for a missing directory", () => { |
| 37 | + var config = { |
| 38 | + path = "wheels", fileName = "Plugins", method = "$init", pluginPath = missingPath, |
| 39 | + deletePluginDirectories = false, overwritePlugins = false, loadIncompatiblePlugins = true |
| 40 | + } |
| 41 | + var pluginObj = $pluginObj(config) |
| 42 | + expect(pluginObj.$folders().recordCount).toBe(0) |
| 43 | + }) |
| 44 | + |
| 45 | + it("$files() returns an empty query for a missing directory", () => { |
| 46 | + var config = { |
| 47 | + path = "wheels", fileName = "Plugins", method = "$init", pluginPath = missingPath, |
| 48 | + deletePluginDirectories = false, overwritePlugins = false, loadIncompatiblePlugins = true |
| 49 | + } |
| 50 | + var pluginObj = $pluginObj(config) |
| 51 | + expect(pluginObj.$files().recordCount).toBe(0) |
| 52 | + }) |
| 53 | + }) |
| 54 | + } |
| 55 | + |
| 56 | + // Mirror the sibling plugin specs (pluginsSpec.cfc:549, pluginsModernSpec, |
| 57 | + // pluginsSemverSpec, pluginsManifestIntegrationSpec): a component-level |
| 58 | + // helper that instantiates wheels.Plugins via $createObjectFromRoot and |
| 59 | + // dispatches $init with the full config — INCLUDING pluginPath. Without it, |
| 60 | + // $pluginObj(config) resolves to the parameterless Global.$pluginObj() that |
| 61 | + // WheelsTest auto-binds, which ignores config and returns the cached PluginObj |
| 62 | + // pointing at the real plugins/ dir — so the missing-path branch (the fix) |
| 63 | + // never runs and these specs pass for the wrong reason. |
| 64 | + function $pluginObj(required struct config) { |
| 65 | + return g.$createObjectFromRoot(argumentCollection = arguments.config) |
| 66 | + } |
| 67 | +} |
0 commit comments