import Pantograph.Delate import Pantograph.Environment import Repl import Test.Common import LSpec open Lean namespace Pantograph.Test.Environment open Pantograph deriving instance DecidableEq, Repr for Protocol.InductInfo deriving instance DecidableEq, Repr for Protocol.ConstructorInfo deriving instance DecidableEq, Repr for Protocol.RecursorRule deriving instance DecidableEq, Repr for Protocol.RecursorInfo deriving instance DecidableEq, Repr for Protocol.EnvInspectResult def test_catalog (env : Environment) : IO LSpec.TestSeq := do let symbolsWithNum := env.constants.fold (init := #[]) (λ acc name info => match (toFilteredSymbol name info).isSome && (name matches .num _ _) with | false => acc | true => acc.push name ) return LSpec.check "No num symbols" (symbolsWithNum.size == 0) def test_symbol_visibility: IO LSpec.TestSeq := do let entries: List (Name × Bool) := [ ("Nat.add_comm".toName, false), ("foo.bla.Init.Data.List.Basic.2.1.Init.Lean.Expr._hyg.4".toName, true), ] let suite := entries.foldl (λ suites (symbol, target) => let test := LSpec.check symbol.toString ((isNameInternal symbol) == target) LSpec.TestSeq.append suites test) LSpec.TestSeq.done return suite inductive ConstantCat where | induct (info: Protocol.InductInfo) | ctor (info: Protocol.ConstructorInfo) | recursor (info: Protocol.RecursorInfo) def test_inspect (env : Environment) : IO LSpec.TestSeq := do let testCases: List (Name × ConstantCat) := [ (`Or, ConstantCat.induct { numParams := 2, numIndices := 0, all := #[`Or], ctors := #[`Or.inl, `Or.inr], }), (`Except.ok, ConstantCat.ctor { induct := `Except, cidx := 1, numParams := 2, numFields := 1, }), (`Eq.rec, ConstantCat.recursor { all := #[`Eq], numParams := 2, numIndices := 1, numMotives := 1, numMinors := 1, rules := #[{ ctor := `Eq.refl, nFields := 0, rhs := { pp? := .some "fun {α} a motive refl => refl" } }] k := true, }), (`ForM.rec, ConstantCat.recursor { all := #[`ForM], numParams := 3, numIndices := 0, numMotives := 1, numMinors := 1, rules := #[{ ctor := `ForM.mk, nFields := 1, rhs := { pp? := .some "fun m γ α motive mk forM => mk forM" } }] k := false, }) ] let inner: CoreM LSpec.TestSeq := do let coreContext ← readThe Core.Context testCases.foldlM (λ acc (name, cat) => do let args: Protocol.EnvInspect := { name } let result ← match ← Repl.env_inspect args |>.run { coreContext } |>.run' { env := ← getEnv } with | .ok result => pure $ result | .error e => panic! s!"Error: {e.desc}" let testName := name.toString let p := match cat with | .induct info => LSpec.test testName (result.inductInfo? == .some info) | .ctor info => LSpec.test testName (result.constructorInfo? == .some info) | .recursor info => LSpec.test testName (result.recursorInfo? == .some info) return LSpec.TestSeq.append acc p ) LSpec.TestSeq.done runCoreMSeq env inner def test_symbol_location (env : Environment) : TestT IO Unit := do addTest $ ← runTestCoreM env do let .ok result ← Repl.env_inspect { name := `Nat.le_of_succ_le, source? := .some true } |>.run { coreContext := ← readThe Core.Context } |>.run' { env := ← getEnv } | fail "Inspect failed" checkEq "module" result.module? <| .some `Init.Data.Nat.Basic -- Extraction of source doesn't work for symbols in `Init` for some reason checkTrue "file" result.sourceUri?.isNone checkEq "sourceStart" (result.sourceStart?.map (·.column)) <| .some 0 checkEq "sourceEnd" (result.sourceEnd?.map (·.column)) <| .some 88 let .ok { imports, constNames, .. } ← Repl.env_module_read ⟨`Init.Data.Nat.Basic⟩ |>.run { coreContext := ← readThe Core.Context } |>.run' { env := ← getEnv } | fail "Module read failed" checkEq "imports" imports #[`Init.SimpLemmas, `Init.Data.NeZero, `Init.Grind.Tactics] checkTrue "constNames" $ constNames.contains `Nat.succ_add def test_matcher (env : Environment) : TestT IO Unit := do checkTrue "not matcher" $ ¬ Meta.isMatcherCore env `Nat.strongRecOn def suite (env : Environment) : List (String × IO LSpec.TestSeq) := [ ("Catalog", test_catalog env), ("Symbol Visibility", test_symbol_visibility), ("Inspect", test_inspect env), ("Symbol Location", runTest $ test_symbol_location env), ("Matcher", runTest $ test_matcher env), ]