From 405a68053a59ccb2e6cd2f1c042448bd662ff578 Mon Sep 17 00:00:00 2001 From: Beng Guan <118246443+bengguankoay@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:16:01 +0800 Subject: [PATCH] fix(curriculum): accept both gradient syntax formats in lab availability table test (#65725) --- .../66b36358ed4f261d64840c24.md | 74 +++++++++++++++++-- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/curriculum/challenges/english/blocks/lab-availability-table/66b36358ed4f261d64840c24.md b/curriculum/challenges/english/blocks/lab-availability-table/66b36358ed4f261d64840c24.md index eda9474f994..bef5a237620 100644 --- a/curriculum/challenges/english/blocks/lab-availability-table/66b36358ed4f261d64840c24.md +++ b/curriculum/challenges/english/blocks/lab-availability-table/66b36358ed4f261d64840c24.md @@ -19,7 +19,7 @@ demoType: onClick 1. In your `:root` selector, you should define six CSS variables named `--color#`, where `#` is a number from `0` to `5`, and assign them each a color value. Use these variables to set the background color of the corresponding `.available-#` elements. 1. In your `:root` selector, you should define CSS variables named `--solid-border` and `--dashed-border`. Use these variables to style the bottom borders of your data cells, alternating between solid and dashed borders depending on the row. Give the rows either the class of `sharp` or `half` to style them. 1. You should have a `div` element with the `id` of `legend`. It should contain a `span` element with the text `Availability` and a `div` element with the `id` of `legend-gradient`. -1. You should give the `#legend-gradient` element a linear gradient that transitions between all the colors from `--color0` to `--color5`. Each color value should have two color stops (expressed as percentages) to make the transition between colors a hard line. +1. You should give the `#legend-gradient` element a linear gradient that transitions between all the colors from `--color0` to `--color5` with hard lines. **Note:** Be sure to link your stylesheet in your HTML to apply your CSS. @@ -286,16 +286,76 @@ assert.exists(legendGradient); assert.include(legendGradient.backgroundImage, "linear-gradient(") ``` -You should use two color-stops (expressed in percentage) to make the transition from one color to the following color a hard line for your `#legend-gradient`. Remember to use your `--color#` variables. +You should have the transitions from one color to the following color as a hard line for your `#legend-gradient`. Make sure your percentages are whole numbers. ```js const legendGradient = new __helpers.CSSHelp(document).getStyle('#legend-gradient'); assert.exists(legendGradient); -const matched = legendGradient.backgroundImage.match(/var\(\s*--color[0-5]\s*\)\s+\d+%(\s+\d+%)?/g); -assert.lengthOf(matched, 6); -matched.forEach((arg, i) => { - if (i !== 0 && i !== 5) assert.lengthOf(arg.match(/%/g), 2); -}) +const gradientStr = legendGradient.backgroundImage; + +const COLOR_COUNT = 6; +const EXPECTED_SHORTHAND_STOPS = 6; +const EXPECTED_EXPANDED_STOPS = 12; + +for (let i = 0; i < COLOR_COUNT; i++) { + assert.include(gradientStr, `--color${i}`, `gradient should include --color${i}`); +} + +const GRADIENT_PATTERNS = { + SHORTHAND: /var\(\s*--color[0-5]\s*\)\s+\d+%\s+\d+%/g, + EXPANDED: /var\(\s*--color[0-5]\s*\)\s+\d+%(?!\s+\d+%)/g +}; + +const matchGradientFormat = (gradientStr, pattern) => gradientStr.match(pattern); + +const shorthandMatches = matchGradientFormat(gradientStr, GRADIENT_PATTERNS.SHORTHAND); +const expandedMatches = matchGradientFormat(gradientStr, GRADIENT_PATTERNS.EXPANDED); + +const colorPattern = /var\(\s*--color(\d)\s*\)/g; +const allColorMatches = [...gradientStr.matchAll(colorPattern)]; +const colorNumbers = allColorMatches.map(match => parseInt(match[1])); + +if (shorthandMatches?.length === EXPECTED_SHORTHAND_STOPS) { + for (let i = 0; i < COLOR_COUNT; i++) { + const count = colorNumbers.filter(num => num === i).length; + assert.equal(count, 1, `In shorthand format, --color${i} should appear exactly once, but it appears ${count} times`); + } + + for (let i = 0; i < COLOR_COUNT; i++) { + const idx = colorNumbers.indexOf(i); + assert.isAtLeast(idx, 0, `--color${i} should be in the gradient`); + if (i > 0) { + const prevIdx = colorNumbers.indexOf(i - 1); + assert.isBelow(prevIdx, idx, `--color${i - 1} should appear before --color${i}`); + } + } +} else if (expandedMatches?.length === EXPECTED_EXPANDED_STOPS) { + for (let i = 0; i < COLOR_COUNT; i++) { + const count = colorNumbers.filter(num => num === i).length; + assert.equal(count, 2, `In expanded format, --color${i} should appear exactly twice, but it appears ${count} times`); + } + + for (let i = 0; i < COLOR_COUNT; i++) { + const firstIdx = colorNumbers.indexOf(i); + const lastIdx = colorNumbers.lastIndexOf(i); + assert.equal(lastIdx - firstIdx, 1, `--color${i} should appear in consecutive positions for hard lines`); + + if (i > 0) { + const prevLastIdx = colorNumbers.lastIndexOf(i - 1); + assert.isBelow(prevLastIdx, firstIdx, `--color${i - 1} should complete before --color${i} starts`); + } + } + + const percentPattern = /var\(\s*--color\d\s*\)\s+(\d+)%/g; + const percentMatches = [...gradientStr.matchAll(percentPattern)]; + const percentages = percentMatches.map(match => parseInt(match[1])); + + for (let i = 1; i < percentages.length - 1; i += 2) { + assert.equal(percentages[i], percentages[i + 1], `For hard lines, percentage at position ${i} (${percentages[i]}%) should equal percentage at position ${i + 1} (${percentages[i + 1]}%) where colors meet`); + } +} else { + assert.fail('Gradient must use either shorthand format (6 stops with two percentages each) or expanded format (12 stops with one percentage each)'); +} ``` # --seed--