Skip to content

Commit 770320f

Browse files
davidagustinclaude
andcommitted
fix(ui-patterns): fix password-strength false positive on hard refresh
The "Weak password shows low strength" test passed with blanked starter because `[] / 5 * 100 = 0` (JS coercion) and the test only checked `< 50`. Fixed by: (1) requiring `> 0 && < 50` in the test so 0% width from an unimplemented starter doesn't pass, (2) adding .length/.size override in the generator so `rules.filter(...).length` produces `0` not `[]` as default, (3) regenerating starters. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3911a68 commit 770320f

4 files changed

Lines changed: 10 additions & 4 deletions

File tree

lib/frontend-drills/ui-patterns/starters/react.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ function PasswordStrength() {
162162
163163
const rules = []; // TODO: Implement rules
164164
165-
const strength = []; // TODO: Strength
165+
const strength = 0; // TODO: Strength
166166
const colors = ['#ef4444', '#f97316', '#eab308', '#22c55e', '#10b981'];
167167
const labels = ['Very weak', 'Weak', 'Fair', 'Strong', 'Very strong'];
168168

lib/frontend-drills/ui-patterns/starters/vue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ createApp({
922922
error: ['Build failed', 'Connection lost', 'Payment declined'],
923923
};
924924
925-
const unread = []; // TODO: Unread — filter items, remove item
925+
const unread = 0; // TODO: Unread — filter items, remove item
926926
927927
const addNotification = (type) => {
928928
// TODO: Add notification — calculate values

lib/frontend-drills/ui-patterns/tests/react.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export const reactTests: Record<string, PatternTestCase[]> = {
6666
'react-password-strength': [
6767
{
6868
name: 'Weak password shows low strength',
69-
test: "(async function() { var input = document.querySelector('input[type=\"password\"]'); if (!input) return false; var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set; nativeInputValueSetter.call(input, 'abc'); input.dispatchEvent(new Event('input', {bubbles: true})); await new Promise(function(r) { setTimeout(r, 150); }); var fill = document.querySelector('.meter-fill'); return (fill && parseFloat(fill.style.width) < 50) || document.body.innerText.toLowerCase().includes('weak'); })()",
69+
test: "(async function() { var input = document.querySelector('input[type=\"password\"]'); if (!input) return false; var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set; nativeInputValueSetter.call(input, 'abc'); input.dispatchEvent(new Event('input', {bubbles: true})); await new Promise(function(r) { setTimeout(r, 150); }); var fill = document.querySelector('.meter-fill'); var w = fill ? parseFloat(fill.style.width) : 0; return (w > 0 && w < 50) || document.body.innerText.toLowerCase().includes('weak'); })()",
7070
},
7171
{
7272
name: 'Strong password shows high strength',

scripts/generate-starters.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ function blankFunctionBodies(
234234
else if (/\.toLocaleString|\.toFixed|\.join\(/.test(fullExpr)) defaultVal = "''";
235235
else if (/\[/.test(fullExpr)) defaultVal = '[]';
236236
else if (/\{/.test(fullExpr)) defaultVal = '{}';
237+
// Override: chain ending with .length/.size produces a number regardless
238+
if (/\.\s*(?:length|size)\s*[;,)}\s]*$/.test(fullExpr.trim())) defaultVal = '0';
237239

238240
const bodyContent = fullExpr;
239241
const todo = generateTodo(varName, bodyContent);
@@ -473,7 +475,11 @@ function blankFunctionBodies(
473475
let defaultVal = '[]';
474476
if (hasMethodChain) {
475477
const hasArrayMethod = /\.\s*(filter|map|flatMap|sort)\s*\(/.test(fullExpr);
476-
if (!hasArrayMethod) {
478+
// Check if chain ends with .length/.size (produces a number, not an array)
479+
const endsWithLength = /\.\s*(?:length|size)\s*[;,)}\s]*$/.test(fullExpr.trim());
480+
if (endsWithLength) {
481+
defaultVal = '0';
482+
} else if (!hasArrayMethod) {
477483
if (/\.\s*find\s*\(/.test(fullExpr)) defaultVal = 'null';
478484
else if (/\.\s*findIndex\s*\(/.test(fullExpr)) defaultVal = '-1';
479485
else if (/\.\s*(some|every)\s*\(/.test(fullExpr)) defaultVal = 'false';

0 commit comments

Comments
 (0)