Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

77 lines
2.3 KiB
Go

package languages
import (
"testing"
"github.com/zzet/gortex/internal/graph"
)
func TestScalaExtractor_Fields(t *testing.T) {
const scala = `package com.app
class Account {
val balance: Int = 0
var pending: List[Transaction] = Nil
def deposit(amount: Int): Boolean = {
true
}
}
`
res, err := NewScalaExtractor().Extract("Account.scala", []byte(scala))
if err != nil {
t.Fatal(err)
}
byName := map[string]*graph.Node{}
for _, n := range res.Nodes {
byName[n.Name] = n
}
typedAs := map[string]string{} // field id -> referenced type
for _, e := range res.Edges {
if e.Kind == graph.EdgeTypedAs {
typedAs[e.From] = e.To
}
}
// val field keeps its base type in meta, but a primitive annotation
// (Int) deliberately emits no typed_as usage edge — those would just
// clutter the graph with unresolved::Int edges that never land.
balance := byName["balance"]
if balance == nil || balance.Kind != graph.KindField {
t.Fatalf("val 'balance' should be a field node, got %+v", balance)
}
if balance.Meta["field_type"] != "Int" {
t.Errorf("balance field_type = %v, want Int", balance.Meta["field_type"])
}
if _, ok := typedAs[balance.ID]; ok {
t.Errorf("primitive-typed balance should NOT have a typed_as edge, got %q", typedAs[balance.ID])
}
// A container generic surfaces its element type as a usage edge:
// `List[Transaction]` references Transaction.
if p := byName["pending"]; p != nil && typedAs[p.ID] != "unresolved::Transaction" {
t.Errorf("pending (List[Transaction]) should typed_as unresolved::Transaction, got %q", typedAs[p.ID])
}
// var field is flagged mutable; generic type reduced to its base.
pending := byName["pending"]
if pending == nil || pending.Kind != graph.KindField {
t.Fatalf("var 'pending' should be a field node, got %+v", pending)
}
if pending.Meta["mutable"] != true {
t.Errorf("var pending should be mutable: meta=%v", pending.Meta)
}
if pending.Meta["field_type"] != "List" {
t.Errorf("pending field_type = %v, want List (generic stripped)", pending.Meta["field_type"])
}
// function gains a return type.
deposit := byName["deposit"]
if deposit == nil {
t.Fatal("method 'deposit' was not extracted")
}
if deposit.Meta["return_type"] != "Boolean" {
t.Errorf("deposit return_type = %v, want Boolean", deposit.Meta["return_type"])
}
}