
# 오라클 테스트

Phasis의 모든 구현 결정은 한 가지 질문을 기준으로 합니다. **V8에서 동일한 출력이 나오는가?**

JavaScript에는 `NaN !== NaN`, `-0 === 0`, `[1] + 1 === "11"`, 속성 열거의 정확한 순서, `Promise` 마이크로태스크의 실행 시점처럼 미묘한 의미가 있습니다. 사양을 읽어 하나씩 다시 파악하는 일은 느리고 오류가 발생하기 쉽습니다. Phasis은 Node.js(V8)을 오라클로 삼아 이를 해결합니다. JS 시나리오를 작성하고 V8에서 실행해 출력을 기준값으로 저장한 다음, Phasis에서 실행해 출력을 다시 저장하고 비교합니다.

```
1. SETUP    → a JavaScript source file or snippet
2. ORACLE   → Node.js executes it, output captured as truth
3. ACTUAL   → Phasis executes it, output captured
4. COMPARE  → oracle vs actual, diff measures the gap
```

## 두 단계의 테스트

### 1단계 — 사용자 정의 시나리오

`scenarios/`의 각 시나리오는 출력이 정해진 작은 JS 프로그램입니다. 단일 시나리오를 실행합니다:

```bash
./bin/test-scenario operators/arithmetic
```

전체를 실행하거나, 한 카테고리만 실행하거나, 병렬로 실행합니다:

```bash
./bin/test-regression
./bin/test-regression --jobs 4
./bin/test-regression --category expressions
```

오라클을 새로 고칩니다(e.g. Node.js 버전 업데이트 후):

```bash
./bin/oracle --refresh operators/arithmetic
```

시나리오는 ECMAScript 장별로 구성됩니다. 리터럴, 연산자, 변수, 제어 흐름, 함수, 객체, 배열, 클래스, 내장 기능, 오류, 상호 운용성, 예외 사례가 있습니다.

### 레벨 2 — test262

공식 TC39 적합성 테스트 스위트는 `test262/` 아래에 git 서브모듈로 체크아웃되어 있습니다. 각 테스트는 자체적으로 결과를 검증합니다. 예외가 발생하지 않으면 통과하고, 발생하면 실패합니다(`negative` 테스트는 그 반대). 하네스는 각 테스트 전에 `assert.js`와 `sta.js`을 로드합니다.

```bash
./bin/test262                                    # full suite
./bin/test262 --category built-ins/Array         # subset
./bin/test262 --jobs 4                           # parallel
./bin/test262 --failures                         # one line per failing test
./bin/compat-report                              # full COMPAT.md + compat.json
```

전체 스위트 스냅샷은 [`COMPAT.md`](https://github.com/inline0/phasis/blob/main/COMPAT.md)에 있으며, `bin/compat-report`로 다시 생성합니다. CI에서는 `compat-matrix.yml` 워크플로가 이를 샤드별로 실행하고 결과를 커밋합니다. 이 워크플로는 수동으로 시작하며 푸시마다 실행되지는 않습니다.

## 로컬 푸시 전 검사

`./bin/verify-all`은 CI에서 적용하는 품질 게이트를 실행합니다:

```
=== PHPStan ===                  level 6, zero errors
=== Code Standards ===           PHPCS, zero warnings
=== PHPUnit ===                  unit suite passes
=== Oracle Regression ===        scenarios under `scenarios/` pass
```

이것만으로는 충분하지 않습니다. 파서, 인터프리터 또는 내장 기능에 영향을 주는 변경 사항은 test262도 샘플링해야 합니다. 모든 풀 리퀘스트에서 CI는 PHPStan, PHPCS, 단위 테스트 스위트와 오라클 회귀 테스트를 실행합니다. 풀 리퀘스트에서 `src/` 또는 해당 픽스처가 변경되면 WPT 및 인기 패키지 테스트 스위트도 실행합니다. 전체 test262 매트릭스는 풀 리퀘스트 CI에 포함되지 않으므로 영향을 받는 카테고리는 로컬에서 샘플링하세요.

## 작동 원리

V8을 단일 기준으로 삼으면 개발 과정에서 사양을 읽는 일이 거의 사라집니다. V8과의 불일치는 항상 Phasis 버그를 뜻합니다. 사양이 모호해서 논쟁할 여지는 없습니다. 수정이 반영되면 해당 test262 항목이 영구적인 회귀 테스트가 됩니다.

100%의 통과율은 이러한 규율을 따른 결과입니다. 모든 PR은 V8을 기준으로 평가되고, CI는 오라클, WPT 및 인기 패키지 테스트 스위트의 회귀를 거부하며, test262 매트릭스는 실행 시 전체 스위트 결과를 확인합니다.
