UNPKG

jdoms

Version:

jDoms is a fast, powerful, and zero-dependency JavaScript library for modern DOM manipulation, traversal, event handling, and more

350 lines (299 loc) 11.8 kB
<!DOCTYPE html> <html> <head> <title>jDoms Test Page</title> </head> <body> <h1 id="main-title" class="title header" data-test="main-header">jDoms Test Suite</h1> <div id="container"> <p class="para">Please open console developer tools (F12) to view results.</p> <ul id="list-1"> <li class="item item-1">Item 1</li> <li class="item item-2" style="color: blue;">Item 2</li> <li class="item item-3" data-id="3">Item 3</li> </ul> <div id="event-box"> <button class="btn">Button 1</button> <button class="btn">Button 2</button> </div> <form id="test-form"> <input type="text" id="text-input" name="username" value="initial"> <input type="checkbox" id="checkbox-input" name="confirm" checked> </form> </div> <div id="empty-div"></div> <div id="clone-source"><p><span>Clone me</span></p></div> <script src="./src/jdoms-latest.js"></script> <!--<script src="./src/jdoms-v1.1.0.js"></script>--> <!--<script src="./src/jdoms-v1.0.0.js"></script>--> <script> const assert = { strictEqual(actual, expected, message) { if (actual !== expected) { throw new Error(message || `Assertion failed: expected ${expected}, but got ${actual}`); } else { console.log("✅ Assert passed:", message || `${actual} === ${expected}`); } }, notStrictEqual(actual, expected, message) { if (actual === expected) { throw new Error(message || `Assertion failed: value should not be ${actual}`); } else { console.log("✅ Assert passed:", message || `${actual} !== ${expected}`); } }, deepStrictEqual(actual, expected, message) { const isObject = (obj) => obj !== null && typeof obj === "object"; function deepEqual(a, b) { if (a === b) return true; // Handle arrays if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; return a.every((val, i) => deepEqual(val, b[i])); } // Handle objects if (isObject(a) && isObject(b)) { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every((key) => deepEqual(a[key], b[key])); } return false; } if (!deepEqual(actual, expected)) { throw new Error( message || `Assertion failed: expected ${JSON.stringify(expected)}, but got ${JSON.stringify(actual)}` ); } else { console.log("✅ Assert passed:", message || "Objects are deeply equal"); } } }; </script> <script> // 2. Simple Test Runner let passCount = 0; let failCount = 0; const tests = []; function test(description, fn) { tests.push({ description, fn }); } function run() { tests.forEach((t, i) => { try { t.fn(); console.log(`\x1b[32m✓ PASS(${i+1}):\x1b[0m ${t.description}`); passCount++; } catch (e) { console.error(`\x1b[31m✗ FAIL(${i+1}):\x1b[0m ${t.description}`); console.error(e.message); failCount++; } }); console.log('================================'); console.log(`\nTest Summary:`); console.log(`\x1b[32m${passCount} passing\x1b[0m`); console.log(`\x1b[31m${failCount} failing\x1b[0m`); // Exit with a non-zero code if any tests failed if (failCount > 0) { } } // 3. Define the Tests // == Core & Selectors == test('Core: Select element by ID', () => { const title = jDoms('#main-title'); assert.strictEqual(title.length, 1, 'Should select one element'); assert.strictEqual(title.index(0).tagName, 'H1', 'Selected element should be an H1 tag'); }); test('Core: Select elements by class', () => { const items = jDoms('.item'); assert.strictEqual(items.length, 3, 'Should select three elements'); }); test('Core: Select elements by tag name', () => { const paragraphs = jDoms('p'); assert.strictEqual(paragraphs.length > 0, true, 'Should select one paragraph'); }); test('Core: Create a new element', () => { const newDiv = jDoms('div', { id: 'new-div', class: 'box' }).create(); assert.strictEqual(newDiv.length, 1); assert.strictEqual(newDiv.attr('id'), 'new-div'); assert.strictEqual(newDiv.hasClass('box'), true); }); // == DOM Traversal == test('Traversal: .find() should find descendants', () => { const listItems = jDoms('#container').find('.item'); assert.strictEqual(listItems.length, 3); }); test('Traversal: .parent() should get the parent element', () => { const list = jDoms('.item-1').parent(); assert.strictEqual(list.attr('id'), 'list-1'); }); test('Traversal: .children() should get direct children', () => { const listChildren = jDoms('#list-1').children(); assert.strictEqual(listChildren.length, 3); }); test('Traversal: .closest() should find the nearest ancestor', () => { const container = jDoms('.item-2').closest('#container'); assert.strictEqual(container.length, 1); assert.strictEqual(container.attr('id'), 'container'); }); test('Traversal: .next() and .previous() should navigate siblings', () => { const item2 = jDoms('.item-1').next(); assert.strictEqual(item2.hasClass('item-2'), true); const item1 = item2.previous(); assert.strictEqual(item1.hasClass('item-1'), true); }); test('Traversal: .first() and .last() should filter the set', () => { const firstItem = jDoms('.item').first(); assert.strictEqual(firstItem.hasClass('item-1'), true); const lastItem = jDoms('.item').last(); assert.strictEqual(lastItem.hasClass('item-3'), true); }); // == DOM Manipulation == test('Manipulation: .html() should get and set HTML content', () => { const p = jDoms('.para'); const originalHtml = p.html(); assert.strictEqual(originalHtml, 'Please open console developer tools (F12) to view results.'); p.html('<strong>New content</strong>'); assert.strictEqual(p.html(), '<strong>New content</strong>'); p.html(originalHtml); // Reset for other tests }); test('Manipulation: .text() should get and set text content', () => { jDoms('#main-title').text('New Title'); assert.strictEqual(jDoms('#main-title').text(), 'New Title'); jDoms('#main-title').text('jDoms Test Suite'); // Reset }); test('Manipulation: .append() and .prepend() should add content', () => { jDoms('#list-1').append('<li id="new-last">Last</li>'); assert.strictEqual(jDoms('#list-1').children().length, 4); assert.strictEqual(jDoms('#list-1').children().last().attr('id'), 'new-last'); jDoms('#list-1').prepend('<li id="new-first">First</li>'); assert.strictEqual(jDoms('#list-1').children().length, 5); assert.strictEqual(jDoms('#list-1').children().first().attr('id'), 'new-first'); }); test('Manipulation: .remove() should remove an element', () => { jDoms('#new-first').remove(); jDoms('#new-last').remove(); assert.strictEqual(jDoms('#list-1').children().length, 3); }); test('Manipulation: .clone() should create a copy of an element', () => { const clone = jDoms('#clone-source').clone(); clone.attr('id', 'clone-dest'); jDoms('body').append(clone); assert.strictEqual(jDoms('#clone-dest').length, 1); assert.strictEqual(jDoms('#clone-dest').find('p').length, 1); }); // == Attributes, Properties & Values == test('Attributes: .attr() should get and set attributes', () => { const title = jDoms('#main-title'); assert.strictEqual(title.attr('data-test'), 'main-header'); title.attr('data-new', 'added'); assert.strictEqual(title.attr('data-new'), 'added'); }); test('Attributes: .removeAttr() should remove an attribute', () => { jDoms('#main-title').removeAttr('data-new'); assert.strictEqual(jDoms('#main-title').attr('data-new'), null); }); test('Properties: .prop() should get and set properties', () => { const checkbox = jDoms('#checkbox-input'); assert.strictEqual(checkbox.prop('checked'), true); checkbox.prop('checked', false); assert.strictEqual(checkbox.prop('checked'), false); }); test('Values: .val() should get and set input values', () => { const input = jDoms('#text-input'); assert.strictEqual(input.val(), 'initial'); input.val('new-value'); assert.strictEqual(input.val(), 'new-value'); }); // == CSS & Styling == test('CSS: .css() should get and set styles', () => { const item2 = jDoms('.item-2'); assert.strictEqual(item2.css('color'), 'blue'); item2.css('font-weight', 'bold'); assert.strictEqual(item2.css('font-weight'), 'bold'); }); test('CSS: .addClass(), .removeClass(), .hasClass()', () => { const title = jDoms('#main-title'); assert.strictEqual(title.hasClass('header'), true); title.addClass('extra-class'); assert.strictEqual(title.hasClass('extra-class'), true); title.removeClass('extra-class'); assert.strictEqual(title.hasClass('extra-class'), false); }); test('CSS: .hide() and .show() should toggle display', () => { const p = jDoms('.para'); p.hide(); assert.strictEqual(p.css('display'), 'none'); p.show(); assert.strictEqual(p.css('display'), 'block'); }); // == Event Handling == test('Events: .on() and .trigger() for direct events', () => { let clicked = false; const btn = jDoms('.btn').first(); btn.on('click', () => { clicked = true; }); btn.trigger('click'); assert.strictEqual(clicked, true, 'Click event handler should have been called'); }); test('Events: .on() and .trigger() for delegated events', () => { let delegatedClickCount = 0; const eventBox = jDoms('#event-box'); eventBox.on('click', '.btn', function() { delegatedClickCount++; }); // Trigger on a matching child jDoms('#event-box .btn').first().trigger('click'); assert.strictEqual(delegatedClickCount, 1, 'Delegated handler should fire once'); // Add a new button and trigger click on it eventBox.append('<button class="btn" id="new-btn">New</button>'); jDoms('#new-btn').trigger('click'); assert.strictEqual(delegatedClickCount, 2, 'Delegated handler should fire on dynamically added element'); }); test('Events: .off() should remove an event handler', () => { let clickCount = 0; const handler = () => { clickCount++; }; const btn = jDoms('.btn').first(); btn.on('click', handler); btn.trigger('click'); assert.strictEqual(clickCount, 1, 'Handler should be attached and fire'); btn.off('click', handler); btn.trigger('click'); assert.strictEqual(clickCount, 1, 'Handler should be detached and not fire again'); }); // == Static Utilities == test('Utilities: jDoms.ready() should execute a callback', (done) => { let ready = false; jDoms.ready(() => { ready = true; assert.strictEqual(ready, true); }); // In JSDOM, ready fires synchronously if the doc is already loaded }); test('Utilities: jDoms.isString() should correctly identify strings', () => { assert.strictEqual(jDoms.isString('hello'), true); assert.strictEqual(jDoms.isString(123), false); }); test('Utilities: jDoms.isArray() should correctly identify arrays', () => { assert.strictEqual(jDoms.isArray([1, 2]), true); assert.strictEqual(jDoms.isArray({}), false); }); test('Utilities: jDoms.jsonParse() should safely parse JSON', () => { const obj = jDoms.jsonParse('{"a": 1}'); assert.deepStrictEqual(obj, { a: 1 }); const invalid = jDoms.jsonParse('{a: 1}'); assert.deepStrictEqual(invalid, {}); }); test('Utilities: jDoms.unique() should remove duplicates from an array', () => { const arr = [1, 2, 2, 3, 1, 4]; const uniqueArr = jDoms.unique(arr); assert.deepStrictEqual(uniqueArr, [1, 2, 3, 4]); }); // 4. Run the tests run(); </script> </body> </html>