From 10f5c095b2ec2c828c0dd6bff9523488e3909412 Mon Sep 17 00:00:00 2001 From: IgorVolochay Date: Sun, 25 Oct 2026 10:49:23 +0300 Subject: [PATCH] feat: add VidIQ badge reader with unset selector Co-Authored-By: Claude Sonnet 5.5 --- src/lib/vidiq.js | 14 ++++++++++++++ test/vidiq.test.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/lib/vidiq.js create mode 100644 test/vidiq.test.js diff --git a/src/lib/vidiq.js b/src/lib/vidiq.js new file mode 100644 index 0000000..b2b1942 --- /dev/null +++ b/src/lib/vidiq.js @@ -0,0 +1,14 @@ +// CSS selector of VidIQ's outlier badge on a video card. It stays null until the real +// markup is captured (Task 15); until then readVidiqScore returns null for every card. +export const VIDIQ_BADGE_SELECTOR = null; + +export function parseVidiqScore(text) { + const match = /(\d+(?:[.,]\d+)?)/.exec(text ?? ''); + return match ? Number(match[1].replace(',', '.')) : null; +} + +export function readVidiqScore(card, selector = VIDIQ_BADGE_SELECTOR) { + if (!selector || !card) return null; + const badge = card.querySelector(selector); + return badge ? parseVidiqScore(badge.textContent) : null; +} diff --git a/test/vidiq.test.js b/test/vidiq.test.js new file mode 100644 index 0000000..b274d71 --- /dev/null +++ b/test/vidiq.test.js @@ -0,0 +1,32 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { VIDIQ_BADGE_SELECTOR, parseVidiqScore, readVidiqScore } from '../src/lib/vidiq.js'; + +test('parseVidiqScore extracts the first number', () => { + assert.equal(parseVidiqScore('12.5x'), 12.5); + assert.equal(parseVidiqScore('5,2x'), 5.2); + assert.equal(parseVidiqScore('Outlier 8'), 8); +}); + +test('parseVidiqScore returns null when there is no number', () => { + assert.equal(parseVidiqScore('no digits here'), null); + assert.equal(parseVidiqScore(''), null); + assert.equal(parseVidiqScore(null), null); + assert.equal(parseVidiqScore(undefined), null); +}); + +test('readVidiqScore returns null while no selector is configured', () => { + assert.equal(VIDIQ_BADGE_SELECTOR, null); + const card = { querySelector: () => ({ textContent: '9x' }) }; + assert.equal(readVidiqScore(card), null); +}); + +test('readVidiqScore reads the badge inside a card', () => { + const card = { querySelector: (selector) => (selector === '.badge' ? { textContent: '7.5x' } : null) }; + assert.equal(readVidiqScore(card, '.badge'), 7.5); +}); + +test('readVidiqScore returns null when the card has no badge or no card is given', () => { + assert.equal(readVidiqScore({ querySelector: () => null }, '.badge'), null); + assert.equal(readVidiqScore(null, '.badge'), null); +});