#!/usr/bin/env node /** * TDD Test for Document Controls Component Extraction * * Tests the extraction of DocumentControls from the monolithic editor.js * DocumentControls handles the floating control panel and its actions. */ const RefactorTestRunner = require('./refactor-test-runner.js'); const runner = new RefactorTestRunner(); // Define expected DocumentControls API const EXPECTED_DOCUMENTCONTROLS_API = [ 'constructor', 'create', 'destroy', 'show', 'hide', 'addButton', 'removeButton', 'setEventHandlers', 'updateStatus', 'getControlPanel' ]; runner.describe('DocumentControls Component Extraction', () => { runner.it('should define expected API methods', () => { const expectedMethods = EXPECTED_DOCUMENTCONTROLS_API; runner.expect(expectedMethods.length).toBe(10); runner.expect(expectedMethods).toContain('create'); runner.expect(expectedMethods).toContain('addButton'); runner.expect(expectedMethods).toContain('setEventHandlers'); }); runner.it('should load extracted DocumentControls component', () => { // Load the extracted component delete require.cache[require.resolve('../components/document-controls.js')]; try { const module = require('../components/document-controls.js'); runner.expect(module.DocumentControls).toBeTruthy(); // Set global for other tests global.ExtractedDocumentControls = module.DocumentControls; } catch (error) { throw new Error(`Failed to load extracted DocumentControls: ${error.message}`); } }); runner.it('should preserve constructor functionality', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); runner.expect(controls).toBeInstanceOf(DocumentControls); runner.expect(controls.controlPanel).toBeFalsy(); // Initially null runner.expect(controls.buttons).toBeInstanceOf(Map); }); runner.it('should preserve control panel creation functionality', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); const panel = controls.getControlPanel(); runner.expect(panel).toBeTruthy(); runner.expect(panel.id).toBe('markitect-global-controls'); // Check that panel is added to DOM const domPanel = document.getElementById('markitect-global-controls'); runner.expect(domPanel).toBeTruthy(); // Cleanup controls.destroy(); }); runner.it('should preserve button creation functionality', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); // Default buttons should be created runner.expect(controls.buttons.has('save-document')).toBeTruthy(); runner.expect(controls.buttons.has('reset-all')).toBeTruthy(); runner.expect(controls.buttons.has('show-status')).toBeTruthy(); runner.expect(controls.buttons.has('toggle-debug')).toBeTruthy(); // Check DOM elements exist runner.expect(document.getElementById('save-document')).toBeTruthy(); runner.expect(document.getElementById('reset-all')).toBeTruthy(); runner.expect(document.getElementById('show-status')).toBeTruthy(); runner.expect(document.getElementById('toggle-debug')).toBeTruthy(); // Cleanup controls.destroy(); }); runner.it('should support custom button addition', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); // Add custom button const customButton = controls.addButton('custom-test', '๐ŸŽฏ Test', '#ff6600'); runner.expect(customButton).toBeTruthy(); runner.expect(customButton.id).toBe('custom-test'); runner.expect(customButton.textContent).toBe('๐ŸŽฏ Test'); // Check button is in map and DOM runner.expect(controls.buttons.has('custom-test')).toBeTruthy(); runner.expect(document.getElementById('custom-test')).toBeTruthy(); // Cleanup controls.destroy(); }); runner.it('should support event handler configuration', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); let saveClicked = false; let resetClicked = false; const handlers = { 'save-document': () => { saveClicked = true; }, 'reset-all': () => { resetClicked = true; } }; controls.setEventHandlers(handlers); // Simulate button clicks const saveBtn = document.getElementById('save-document'); const resetBtn = document.getElementById('reset-all'); saveBtn.click(); resetBtn.click(); runner.expect(saveClicked).toBeTruthy(); runner.expect(resetClicked).toBeTruthy(); // Cleanup controls.destroy(); }); runner.it('should support show/hide functionality', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); const panel = controls.getControlPanel(); // Test hiding controls.hide(); runner.expect(panel.style.display).toBe('none'); // Test showing controls.show(); runner.expect(panel.style.display).toBe('block'); // Cleanup controls.destroy(); }); runner.it('should preserve destroy functionality', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); // Verify panel exists runner.expect(document.getElementById('markitect-global-controls')).toBeTruthy(); // Destroy controls.destroy(); // Verify panel is removed runner.expect(document.getElementById('markitect-global-controls')).toBeFalsy(); runner.expect(controls.controlPanel).toBeFalsy(); }); runner.it('should support status updates', () => { const DocumentControls = global.ExtractedDocumentControls; const controls = new DocumentControls(); controls.create(); // Test status update controls.updateStatus({ totalSections: 5, editingSections: 2 }); // The status should be reflected in the panel (implementation specific) const panel = controls.getControlPanel(); runner.expect(panel).toBeTruthy(); // Cleanup controls.destroy(); }); }); module.exports = { runner, EXPECTED_DOCUMENTCONTROLS_API }; // Run tests if called directly if (require.main === module) { console.log('๐Ÿงช Testing DocumentControls Component Extraction'); runner.run().then(() => { console.log('โœ… DocumentControls extraction tests completed'); }); }