open-code-review/internal/suggestdiff/diff_test.go
kite 533b526b4c
Some checks are pending
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
chore: add SPDX license headers and automated verification (#740)
* chore: add SPDX license headers to all source files

Add Apache-2.0 SPDX license identifiers and copyright notices to all
tracked .go, .sh, .js, .mjs, .ts, and .tsx source files.

Introduce scripts/verify-license.sh and scripts/add-license.sh for
automated verification and bulk addition of license headers. Integrate
the check into CI (ci.yml) and the Makefile (license-check target as
a prerequisite of the existing check target).

This satisfies the OpenSSF Best Practices Badge requirements for
copyright_per_file and license_per_file.

* fix: restore execute permissions on scripts

* docs: add license header instructions to CONTRIBUTING guides

* docs: add license header instructions to pages contributing guides

* fix(pages): strip unclosed HTML comment markers to satisfy CodeQL

* fix: apply code review suggestions for license scripts

- Fix portability: detect macOS vs Linux stat for permission copy
- Fix has_header: check both SPDX and copyright (match verify logic)
- Fix is_ignored: match on path boundaries to avoid false positives
- Fix year extraction: use consistent pipeline across both scripts
- Fix Bash 3.2 compat: quote array length expansion for set -u

* fix(pages): use loop-until-clean for HTML comment stripping (CodeQL)

* fix(pages): use split/join instead of replace to avoid CodeQL false positive

CodeQL's js/incomplete-multi-character-sanitization rule flags any
.replace() that removes multi-character sequences like '<!--...-->',
regardless of context. The data here comes from readFileSync on the
project's own index.html (no untrusted input), making this a false
positive. Using split(regex).join('') achieves the same result without
triggering the taint-tracking rule.
2026-08-05 21:26:27 +08:00

130 lines
2.7 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 alibaba/open-code-review Contributors
package suggestdiff
import (
"testing"
)
func TestComputeLineDiff(t *testing.T) {
tests := []struct {
name string
old []string
new []string
wantLen int
wantAdds int
wantDels int
}{
{
name: "both empty",
old: nil,
new: nil,
wantLen: 0,
wantAdds: 0,
wantDels: 0,
},
{
name: "identical single line",
old: []string{"hello"},
new: []string{"hello"},
wantLen: 1,
wantAdds: 0,
wantDels: 0,
},
{
name: "add lines to empty",
old: []string{},
new: []string{"a", "b"},
wantLen: 2,
wantAdds: 2,
wantDels: 0,
},
{
name: "delete all lines",
old: []string{"a", "b"},
new: []string{},
wantLen: 2,
wantAdds: 0,
wantDels: 2,
},
{
name: "replace single line",
old: []string{"old"},
new: []string{"new"},
wantLen: 2,
wantAdds: 1,
wantDels: 1,
},
{
name: "insert in middle",
old: []string{"a", "c"},
new: []string{"a", "b", "c"},
wantLen: 3,
wantAdds: 1,
wantDels: 0,
},
{
name: "delete from middle",
old: []string{"a", "b", "c"},
new: []string{"a", "c"},
wantLen: 3,
wantAdds: 0,
wantDels: 1,
},
{
name: "case insensitive match with whitespace",
old: []string{" Hello "},
new: []string{"hello"},
wantLen: 1,
wantAdds: 0,
wantDels: 0,
},
{
name: "multi-line edit",
old: []string{"func main() {", " fmt.Println(\"old\")", "}"},
new: []string{"func main() {", " fmt.Println(\"new\")", " return", "}"},
wantLen: 5,
wantAdds: 2,
wantDels: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ComputeLineDiff(tt.old, tt.new)
if len(got) != tt.wantLen {
t.Errorf("len = %d, want %d; diff = %v", len(got), tt.wantLen, got)
}
var adds, dels int
for _, l := range got {
switch l.Type {
case DiffAdded:
adds++
case DiffDeleted:
dels++
}
}
if adds != tt.wantAdds {
t.Errorf("adds = %d, want %d", adds, tt.wantAdds)
}
if dels != tt.wantDels {
t.Errorf("dels = %d, want %d", dels, tt.wantDels)
}
})
}
}
func TestComputeLineDiff_ContextContent(t *testing.T) {
old := []string{"a", "b", "c"}
new := []string{"a", "x", "c"}
got := ComputeLineDiff(old, new)
if got[0].Type != DiffContext || got[0].Content != "a" {
t.Errorf("first line should be context 'a', got %+v", got[0])
}
last := got[len(got)-1]
if last.Type != DiffContext || last.Content != "c" {
t.Errorf("last line should be context 'c', got %+v", last)
}
}