Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions devel/216_2.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ tests/
├── alist-cons-test.scm
├── any-test.scm
├── append-map-test.scm
├── append-test.scm
├── circular-list-test.scm
├── cons-star-test.scm
├── count-test.scm
Expand Down Expand Up @@ -221,6 +222,53 @@ tests/
└── zip-test.scm
```

## 2026-04-01 复现 append 长列表 bug

### What
在 `tests/liii/list/append-test.scm` 中添加了 bug 复现测试:

1. **问题描述**:当使用 `append` 循环构建长列表(约 600+ 元素)时,列表结构会损坏变成 dotted pair

2. **复现代码**:
```scheme
(let* ((entries (map (lambda (i) (cons (number->string i) (list "lib"))) (iota 600)))
(result
(let loop ((entries entries)
(visible '()))
(if (null? entries)
visible
(let* ((entry (car entries))
(function-name (car entry)))
(loop (cdr entries)
(if (not (member function-name visible))
(append visible (list function-name))
visible)))))))
result)
```

3. **错误信息**:
```
;append first argument, ("0" "1" "2" ...), is a pair but should be a proper list
```

### 说明
- 错误发生在 `g_list_append` 函数中(src/s7.c)
- 示例代码逻辑正确,但触发了 Goldfish Scheme / S7 的 `append` 实现 bug
- 问题可能与 `member` 函数调用或垃圾回收有关

## 2026-03-31 新增 append-test.scm

### What
新增 `append` 函数的测试文件 `tests/liii/list/append-test.scm`:
1. 包含 26 个测试用例,覆盖 `append` 函数的各种使用场景
2. 测试覆盖基本功能、嵌套列表、空列表处理、不同类型元素、点对(dotted list)等情况
3. 文件遵循测试文件格式规范,无协议头,使用 `;; ` 风格注释

### 测试结果
```
; *** checks *** : 26 correct, 0 failed.
```

## 2026-03-29 完成拆分

### What
Expand Down
101 changes: 101 additions & 0 deletions tests/liii/list/append-test.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
(import (liii list)
(liii check)
) ;import

(check-set-mode! 'report-failed)

;; append 函数测试
;;
;; 连接多个列表并返回新列表。
;;
;; 语法
;; ----
;; (append list ...)
;;
;; 参数
;; ----
;; list : list?
;; 零个或多个要连接的列表。
;;
;; 返回值
;; ----
;; list
;; 一个新的列表,包含所有输入列表的元素。
;;
;; 说明
;; ----
;; append函数接受多个列表作为参数,返回一个新列表,其中包含所有输入列表的元素。
;; 最后一个参数可以是任意对象,此时返回的是一个点对(dotted list)。

; 基本功能测试
(check (append) => '())
(check (append '()) => '())
(check (append '(1 2 3)) => '(1 2 3))
(check (append '(1 2) '(3 4)) => '(1 2 3 4))
(check (append '(a b) '(c d) '(e f)) => '(a b c d e f))
(check (append '() '()) => '())
(check (append '() '(1) '()) => '(1))

; 嵌套列表测试
(check (append '((1 2)) '((3 4))) => '((1 2) (3 4)))
(check (append '(a b) '((c d) (e f))) => '(a b (c d) (e f)))

; 空列表处理
(check (append '() '(a b c)) => '(a b c))
(check (append '(a b c) '()) => '(a b c))
(check (append '() '() '(1 2) '()) => '(1 2))

; 不同类型元素测试
(check (append '(1 2) '("hello" 'symbol)) => '(1 2 "hello" 'symbol))
(check (append '(#t #f) '(42)) => '(#t #f 42))
(check (append '(1 2.5) '(#\a #\b)) => '(1 2.5 #\a #\b))

; 最后一个参数为点对(dotted list)
(check (append '(a b) 'c) => '(a b . c))
(check (append '(1 2) '(3 . 4)) => '(1 2 3 . 4))
(check (append '() 'x) => 'x)

; 单参数测试
; 注意:单参数append可能返回原列表或副本,取决于实现
(let ((original '(a b c)))
(let ((appended (append original)))
(check-true (list? appended))
(check (length appended) => (length original))
(check appended => '(a b c))
) ;let
) ;let

; 不修改原始列表测试
(let ((l1 '(1 2 3)))
(let ((l2 '(4 5 6)))
(let ((result (append l1 l2)))
(set-car! result 99)
(check l1 => '(1 2 3))
(check l2 => '(4 5 6))
(check result => '(99 2 3 4 5 6))
) ;let
) ;let
) ;let

; 复杂组合测试
(check (append '(1) '(2) '(3) '(4) '(5)) => '(1 2 3 4 5))
(check (append '(a b) '() '(c) '() '(d e)) => '(a b c d e))

; Bug 复现测试:使用 append 构建长列表时结构损坏问题
; 测试:使用 map + member(原始场景)
(let* ((entries (map (lambda (i) (cons (number->string i) (list "lib"))) (iota 600)))
(result
(let loop ((entries entries)
(visible '()))
(if (null? entries)
visible
(let* ((entry (car entries))
(function-name (car entry)))
(loop (cdr entries)
(if (not (member function-name visible))
(append visible (list function-name))
visible)))))))
(check-true (list? result))
(check (length result) => 600))

(check-report)
Loading