Skip to content

Commit a78e71e

Browse files
committed
refactor: reduce reliance on implicit global state in Logo subsystem
1 parent 81cefcb commit a78e71e

File tree

3 files changed

+213
-88
lines changed

3 files changed

+213
-88
lines changed

js/LogoDependencies.js

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ class LogoDependencies {
7373
storage,
7474
config,
7575
callbacks,
76-
meSpeak = null
76+
meSpeak = null,
77+
instruments = null,
78+
instrumentsFilters = null,
79+
instrumentsEffects = null,
80+
widgetWindows = null,
81+
utils = null,
82+
Singer = null,
83+
Tone = null,
84+
classes = null
7785
}) {
7886
// Validate required dependencies
7987
if (!blocks) {
@@ -142,6 +150,39 @@ class LogoDependencies {
142150
* @type {Object|null}
143151
*/
144152
this.meSpeak = meSpeak;
153+
154+
// Audio and utility dependencies from Logo Subsystem refactor
155+
this.instruments =
156+
instruments || (typeof window !== "undefined" ? window.instruments : null);
157+
this.instrumentsFilters =
158+
instrumentsFilters ||
159+
(typeof window !== "undefined" ? window.instrumentsFilters : null);
160+
this.instrumentsEffects =
161+
instrumentsEffects ||
162+
(typeof window !== "undefined" ? window.instrumentsEffects : null);
163+
this.widgetWindows =
164+
widgetWindows || (typeof window !== "undefined" ? window.widgetWindows : null);
165+
this.Singer = Singer || (typeof window !== "undefined" ? window.Singer : null);
166+
this.Tone = Tone || (typeof window !== "undefined" ? window.Tone : null);
167+
this.utils = utils || {
168+
doUseCamera: typeof doUseCamera !== "undefined" ? doUseCamera : null,
169+
doStopVideoCam: typeof doStopVideoCam !== "undefined" ? doStopVideoCam : null,
170+
getIntervalDirection:
171+
typeof getIntervalDirection !== "undefined" ? getIntervalDirection : null,
172+
getIntervalNumber: typeof getIntervalNumber !== "undefined" ? getIntervalNumber : null,
173+
mixedNumber: typeof mixedNumber !== "undefined" ? mixedNumber : null,
174+
rationalToFraction:
175+
typeof rationalToFraction !== "undefined" ? rationalToFraction : null,
176+
getStatsFromNotation:
177+
typeof getStatsFromNotation !== "undefined" ? getStatsFromNotation : null,
178+
delayExecution: typeof delayExecution !== "undefined" ? delayExecution : null,
179+
last: typeof last !== "undefined" ? last : null
180+
};
181+
this.classes = classes || {
182+
Notation: typeof Notation !== "undefined" ? Notation : null,
183+
Synth: typeof Synth !== "undefined" ? Synth : null,
184+
StatusMatrix: typeof StatusMatrix !== "undefined" ? StatusMatrix : null
185+
};
145186
}
146187

147188
/**
@@ -179,7 +220,36 @@ class LogoDependencies {
179220
onStopTurtle: activity.onStopTurtle,
180221
onRunTurtle: activity.onRunTurtle
181222
},
182-
meSpeak: activity.meSpeak
223+
meSpeak: activity.meSpeak,
224+
// Pass globals for backward compatibility during migration
225+
instruments: typeof instruments !== "undefined" ? instruments : null,
226+
instrumentsFilters:
227+
typeof instrumentsFilters !== "undefined" ? instrumentsFilters : null,
228+
instrumentsEffects:
229+
typeof instrumentsEffects !== "undefined" ? instrumentsEffects : null,
230+
widgetWindows: typeof window !== "undefined" ? window.widgetWindows : null,
231+
Singer: typeof Singer !== "undefined" ? Singer : null,
232+
Tone: typeof Tone !== "undefined" ? Tone : null,
233+
utils: {
234+
doUseCamera: typeof doUseCamera !== "undefined" ? doUseCamera : null,
235+
doStopVideoCam: typeof doStopVideoCam !== "undefined" ? doStopVideoCam : null,
236+
getIntervalDirection:
237+
typeof getIntervalDirection !== "undefined" ? getIntervalDirection : null,
238+
getIntervalNumber:
239+
typeof getIntervalNumber !== "undefined" ? getIntervalNumber : null,
240+
mixedNumber: typeof mixedNumber !== "undefined" ? mixedNumber : null,
241+
rationalToFraction:
242+
typeof rationalToFraction !== "undefined" ? rationalToFraction : null,
243+
getStatsFromNotation:
244+
typeof getStatsFromNotation !== "undefined" ? getStatsFromNotation : null,
245+
delayExecution: typeof delayExecution !== "undefined" ? delayExecution : null,
246+
last: typeof last !== "undefined" ? last : null
247+
},
248+
classes: {
249+
Notation: typeof Notation !== "undefined" ? Notation : null,
250+
Synth: typeof Synth !== "undefined" ? Synth : null,
251+
StatusMatrix: typeof StatusMatrix !== "undefined" ? StatusMatrix : null
252+
}
183253
});
184254
}
185255

js/__tests__/logo-dependencies.test.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,22 @@ describe("Logo with LogoDependencies", () => {
101101
onStopTurtle: jest.fn(),
102102
onRunTurtle: jest.fn()
103103
},
104-
meSpeak: null
104+
meSpeak: null,
105+
instruments: {},
106+
Singer: { setSynthVolume: jest.fn() },
107+
Tone: {},
108+
utils: { last: jest.fn() },
109+
classes: {
110+
Notation: jest.fn(),
111+
Synth: jest.fn(),
112+
StatusMatrix: jest.fn()
113+
}
105114
};
106115
});
107116

108117
test("Logo accepts LogoDependencies object", () => {
109118
const logo = new Logo(mockDeps);
110-
expect(logo.deps).toBe(mockDeps);
119+
expect(logo._deps).toBe(mockDeps);
111120
expect(logo.activity.blocks).toBe(mockDeps.blocks);
112121
});
113122

@@ -127,14 +136,14 @@ describe("Logo with LogoDependencies", () => {
127136

128137
const logo = new Logo(mockActivity);
129138
expect(logo.activity).toBe(mockActivity);
130-
expect(logo.deps.blocks).toBe(mockActivity.blocks);
139+
expect(logo._deps.blocks).toBe(mockActivity.blocks);
131140
});
132141

133142
test("Error handler is called correctly", () => {
134143
const deps = new LogoDependencies(mockDeps);
135144
const logo = new Logo(deps);
136145
logo.activity.errorMsg("Test error");
137-
expect(mockDeps.errorHandler).toHaveBeenCalledWith("Test error");
146+
expect(mockDeps.errorHandler).toHaveBeenCalledWith("Test error", undefined);
138147
});
139148

140149
test("Config properties work with getters/setters", () => {
@@ -143,6 +152,12 @@ describe("Logo with LogoDependencies", () => {
143152
logo.activity.showBlocksAfterRun = true;
144153
expect(mockDeps.config.showBlocksAfterRun).toBe(true);
145154
});
155+
156+
test("Audio dependencies are correctly injected", () => {
157+
const logo = new Logo(mockDeps);
158+
expect(logo._deps.instruments).toBe(mockDeps.instruments);
159+
expect(logo._deps.Singer).toBe(mockDeps.Singer);
160+
});
146161
});
147162

148163
describe("LogoDependencies.fromActivity", () => {
@@ -163,5 +178,7 @@ describe("LogoDependencies.fromActivity", () => {
163178
const deps = LogoDependencies.fromActivity(mockActivity);
164179
expect(deps.blocks).toBe(mockActivity.blocks);
165180
expect(deps.turtles).toBe(mockActivity.turtles);
181+
expect(deps.instruments).toBe(global.instruments);
182+
expect(deps.Singer).toBe(global.Singer);
166183
});
167184
});

0 commit comments

Comments
 (0)