線上課程觀課進度管理小工具開發日誌
Day 6:JavaScript 程式碼執行排序:遞迴函數、Call Stack、Task Queue
Call Stack;遞迴函數與 call stack 的關係;Task Queue(非同步的概念再釐清)
Day 9:「修煉圈圈 Practice Rings」Web app 開發日誌 - 2025 六角 AI Vibe Coding 體驗營期末大魔王作業
這份筆記旨在記錄 2025 六角 Vibe Coding 體驗營每日作業 Day 21 的期末專案成果,從一個簡單的個人痛點出發,透過與 AI(在我這個情境中是 Perplexity)協作,在一天內完成了一個包含前後端的全端網頁小工具:「修煉圈圈 Practice Rings」。
<100 subscribers
線上課程觀課進度管理小工具開發日誌
Day 6:JavaScript 程式碼執行排序:遞迴函數、Call Stack、Task Queue
Call Stack;遞迴函數與 call stack 的關係;Task Queue(非同步的概念再釐清)
Day 9:「修煉圈圈 Practice Rings」Web app 開發日誌 - 2025 六角 AI Vibe Coding 體驗營期末大魔王作業
這份筆記旨在記錄 2025 六角 Vibe Coding 體驗營每日作業 Day 21 的期末專案成果,從一個簡單的個人痛點出發,透過與 AI(在我這個情境中是 Perplexity)協作,在一天內完成了一個包含前後端的全端網頁小工具:「修煉圈圈 Practice Rings」。
今天身體狀態欠佳,輕量閱讀《Clean Craftsmanship 無暇的程式碼 軟體工匠篇》文字敘述的概念並回顧先前練習實作的程式碼。影片示範和程式碼實作都先跳過。
目前跳過的示範題(包含:質因數分解、整數大小排序、保齡球計分程式、自動換行問題)之後再補,Uncle Bob 書中都是用 Java 寫的,可以參考相同思路寫成 JavaScript 版本。
實作時可以先用白話三階段描述 GWT / AAA 內容,再轉成程式碼,讓「需求故事」和「測試程式」保持同樣的結構。
小步 TDD 實作可以透過紅–綠–重構的小循環,逐步完成一開始沒有明確完整輪廓的演算法或資料結構,例如先前實作書中一開始以 stack 命名、最後完成為 circular buffer 的示範,我用相同思路寫了 JavaScript 版本的 IntQueue。
練習題程式碼 GitHub repo: https://github.com/gcake119/clean-craftsmanship-katas-js
面向 | BDD:GWT 敘述 | TDD:AAA 結構 | 在 |
|---|---|---|---|
前置條件 | Given:系統目前在哪個狀態?有什麼資料? | Arrange:建立物件、準備輸入與狀態。 |
|
行為 | When:發生了什麼動作或事件? | Act:實際呼叫被測試的函式或觸發行為。 |
|
結果 | Then:外部可以觀察到什麼結果或狀態變化? | Assert:用斷言檢查回傳值、狀態是否符合預期。 |
|
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的整數 queue。When:當 queue 剛被建立。Then:它是空的(size 為 0, |
AAA + 程式 | Arrange: |
對應到測試程式:
it('create an empty queue', () => {
const queue = createIntQueue(3)
expect(queue.size).toBe(0)
expect(isEmpty(queue)).toBe(true)
expect(isFull(queue)).toBe(false)
})
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的空 queue。When:當我 enqueue 42 並再 dequeue 一次。Then:我先能用 |
AAA + 程式 | Arrange: |
這裡測試程式在同一個
it裡包含了兩段 Act + Assert(先 enqueue、再 dequeue),可以視為「同一個情境裡有多個步驟」。如果想更貼近「一個行為一個測試」的風格,也可以拆成兩個it(一個只驗證 enqueue 後狀態,一個只驗證 dequeue 行為)。
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的 queue,已經塞滿 3 個值。When:當我再 enqueue 一個值。Then:應該拋出 |
AAA + 程式 | Arrange:建立 queue 並連續 enqueue 3 次。Act:嘗試再 enqueue 一次。Assert:用 |
這個情境裡,
expect(() => enqueue(...)).toThrowError('queue is full')同時完成 Act 與 Assert。Act 是「在已滿的 queue 上呼叫enqueue」,Assert 是「應該丟出指定錯誤」。對於驗證錯誤的測試,這種把 Act / Assert 合在一行的寫法是很常見、也相對清晰的慣用模式。
程式片段:
it('throws error when enqueue to a full queue', () => {
const queue = createIntQueue(3)
enqueue(queue, 1)
enqueue(queue, 2)
enqueue(queue, 3)
expect(() => enqueue(queue, 4)).toThrowError('queue is full')
})
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的 queue,先 enqueue 1 和 2。When:我 dequeue 一次,再依序 enqueue 3 和 4,讓 head / tail 繞圈。Then:後面連續 dequeue 時,應該依序拿到 2、3、4,最後 queue 為空。 |
AAA + 程式 | Arrange: |
對應到測試程式:
it('在多次不規則的新增與取出後,索引繞圈時仍維持先進先出的正確順序', () => {
const queue = createIntQueue(3)
// 初次填入兩個
enqueue(queue, 1)
enqueue(queue, 2)
expect(dequeue(queue)).toBe(1)
expect(peek(queue)).toBe(2)
// 填滿剩下的空間,讓 tail 繞回 index 0
enqueue(queue, 3)
enqueue(queue, 4)
// 依序取出,確認順序仍然正確
expect(dequeue(queue)).toBe(2)
expect(dequeue(queue)).toBe(3)
expect(dequeue(queue)).toBe(4)
expect(isEmpty(queue)).toBe(true)
})
步驟 | TDD 小循環 | 在這個練習中的樣子 |
|---|---|---|
1 | Red:先寫一個描述行為的測試(通常可以先用 GWT 白話寫在註解,再轉成 AAA 測試)。 | 先寫「建立空 queue」或「enqueue / dequeue 一個值」的測試,還沒有完成 |
2 | Green:只寫剛好讓測試通過的最小實作,不管還沒處理到的情境。 | 先讓基本 enqueue / dequeue 動得起來,可能還沒處理滿載、繞圈等邊界。 |
3 | Refactor:在測試都綠的情況下整理設計與命名,確保程式碼清晰可讀。 | 把 queue 內部狀態抽成 |
4 | 重複 | 每次新增一個新的 GWT 情境,轉成新的 AAA 測試,再跑一輪紅–綠–重構。 |
同一個情境如果自然包含多個步驟,可以在一個 it 裡寫多段 Act + Assert,但要讓每個步驟的意圖清楚。
驗證錯誤時,常見的寫法是用 expect(() => someAct()).toThrowError(...),把 Act 與 Assert 合併,讓測試更精簡易讀。
這一套流程可以直接複製到之後的 kata(質因數分解、排序、保齡球計分、自動換行):
先用 GWT 說清楚行為,再用 AAA 寫測試,小步紅–綠–重構,把演算法一步一步刻出來。
《Clean Craftsmanship 無暇的程式碼 軟體工匠篇》紙本書
The Arrange, Act, and Assert (AAA) Pattern in Unit Test Automation
Using “Given-When-Then” to Discover and Validate Requirements
今天身體狀態欠佳,輕量閱讀《Clean Craftsmanship 無暇的程式碼 軟體工匠篇》文字敘述的概念並回顧先前練習實作的程式碼。影片示範和程式碼實作都先跳過。
目前跳過的示範題(包含:質因數分解、整數大小排序、保齡球計分程式、自動換行問題)之後再補,Uncle Bob 書中都是用 Java 寫的,可以參考相同思路寫成 JavaScript 版本。
實作時可以先用白話三階段描述 GWT / AAA 內容,再轉成程式碼,讓「需求故事」和「測試程式」保持同樣的結構。
小步 TDD 實作可以透過紅–綠–重構的小循環,逐步完成一開始沒有明確完整輪廓的演算法或資料結構,例如先前實作書中一開始以 stack 命名、最後完成為 circular buffer 的示範,我用相同思路寫了 JavaScript 版本的 IntQueue。
練習題程式碼 GitHub repo: https://github.com/gcake119/clean-craftsmanship-katas-js
面向 | BDD:GWT 敘述 | TDD:AAA 結構 | 在 |
|---|---|---|---|
前置條件 | Given:系統目前在哪個狀態?有什麼資料? | Arrange:建立物件、準備輸入與狀態。 |
|
行為 | When:發生了什麼動作或事件? | Act:實際呼叫被測試的函式或觸發行為。 |
|
結果 | Then:外部可以觀察到什麼結果或狀態變化? | Assert:用斷言檢查回傳值、狀態是否符合預期。 |
|
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的整數 queue。When:當 queue 剛被建立。Then:它是空的(size 為 0, |
AAA + 程式 | Arrange: |
對應到測試程式:
it('create an empty queue', () => {
const queue = createIntQueue(3)
expect(queue.size).toBe(0)
expect(isEmpty(queue)).toBe(true)
expect(isFull(queue)).toBe(false)
})
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的空 queue。When:當我 enqueue 42 並再 dequeue 一次。Then:我先能用 |
AAA + 程式 | Arrange: |
這裡測試程式在同一個
it裡包含了兩段 Act + Assert(先 enqueue、再 dequeue),可以視為「同一個情境裡有多個步驟」。如果想更貼近「一個行為一個測試」的風格,也可以拆成兩個it(一個只驗證 enqueue 後狀態,一個只驗證 dequeue 行為)。
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的 queue,已經塞滿 3 個值。When:當我再 enqueue 一個值。Then:應該拋出 |
AAA + 程式 | Arrange:建立 queue 並連續 enqueue 3 次。Act:嘗試再 enqueue 一次。Assert:用 |
這個情境裡,
expect(() => enqueue(...)).toThrowError('queue is full')同時完成 Act 與 Assert。Act 是「在已滿的 queue 上呼叫enqueue」,Assert 是「應該丟出指定錯誤」。對於驗證錯誤的測試,這種把 Act / Assert 合在一行的寫法是很常見、也相對清晰的慣用模式。
程式片段:
it('throws error when enqueue to a full queue', () => {
const queue = createIntQueue(3)
enqueue(queue, 1)
enqueue(queue, 2)
enqueue(queue, 3)
expect(() => enqueue(queue, 4)).toThrowError('queue is full')
})
角度 | 內容 |
|---|---|
GWT 白話 | Given:給定一個容量為 3 的 queue,先 enqueue 1 和 2。When:我 dequeue 一次,再依序 enqueue 3 和 4,讓 head / tail 繞圈。Then:後面連續 dequeue 時,應該依序拿到 2、3、4,最後 queue 為空。 |
AAA + 程式 | Arrange: |
對應到測試程式:
it('在多次不規則的新增與取出後,索引繞圈時仍維持先進先出的正確順序', () => {
const queue = createIntQueue(3)
// 初次填入兩個
enqueue(queue, 1)
enqueue(queue, 2)
expect(dequeue(queue)).toBe(1)
expect(peek(queue)).toBe(2)
// 填滿剩下的空間,讓 tail 繞回 index 0
enqueue(queue, 3)
enqueue(queue, 4)
// 依序取出,確認順序仍然正確
expect(dequeue(queue)).toBe(2)
expect(dequeue(queue)).toBe(3)
expect(dequeue(queue)).toBe(4)
expect(isEmpty(queue)).toBe(true)
})
步驟 | TDD 小循環 | 在這個練習中的樣子 |
|---|---|---|
1 | Red:先寫一個描述行為的測試(通常可以先用 GWT 白話寫在註解,再轉成 AAA 測試)。 | 先寫「建立空 queue」或「enqueue / dequeue 一個值」的測試,還沒有完成 |
2 | Green:只寫剛好讓測試通過的最小實作,不管還沒處理到的情境。 | 先讓基本 enqueue / dequeue 動得起來,可能還沒處理滿載、繞圈等邊界。 |
3 | Refactor:在測試都綠的情況下整理設計與命名,確保程式碼清晰可讀。 | 把 queue 內部狀態抽成 |
4 | 重複 | 每次新增一個新的 GWT 情境,轉成新的 AAA 測試,再跑一輪紅–綠–重構。 |
同一個情境如果自然包含多個步驟,可以在一個 it 裡寫多段 Act + Assert,但要讓每個步驟的意圖清楚。
驗證錯誤時,常見的寫法是用 expect(() => someAct()).toThrowError(...),把 Act 與 Assert 合併,讓測試更精簡易讀。
這一套流程可以直接複製到之後的 kata(質因數分解、排序、保齡球計分、自動換行):
先用 GWT 說清楚行為,再用 AAA 寫測試,小步紅–綠–重構,把演算法一步一步刻出來。
《Clean Craftsmanship 無暇的程式碼 軟體工匠篇》紙本書
The Arrange, Act, and Assert (AAA) Pattern in Unit Test Automation
Using “Given-When-Then” to Discover and Validate Requirements
Share Dialog
Share Dialog
No comments yet