nimsuggest: fix and re-enable old tests (#16401)
A number of nimsuggest tests were disabled for various reasons, sometimes due to brittleness. These tests have been fixed where needed and most have are now enabled -- details below. The updates are meant to provide better regression coverage for future nimsuggest improvements. To avoid brittleness some tests were refactored. Impact: * test coverage has now increased * faster execution of the test suite * tests are less likely to break due to stdlib changes Re-enabled Test & Test Description: * `tchk1.nim`: check (chk) via nimsuggest works at end of file * `tdot4.nim`: prioritize already used completion * `tinclude.nim`: definition lookup (def) with includes * `tstrutils.nim` -> `tdef2.nim`: test template definition lookup (def) * `tsug_regression.nim`: regression test for [nimsuggest #52](https://github.com/nim-lang/nimsuggest/issues/52) * `ttemplate_highlight.nim`: per the file name * `twithin_macro_prefix.nim`: suggest within a macro with a prefix Tests Not Re-Enabled: * `twithin_macro.nim` still disabled as it doesn't provide a good test signal * EPC highlight tests remain disabled -- requires out of scope tester changes Additional Notes: * todos added in comments for follow-up work
This commit is contained in:
parent
fa1a04188f
commit
4cf605dcf6
19 changed files with 292 additions and 376 deletions
164
nimsuggest/tests/fixtures/mclass_macro.nim
vendored
Normal file
164
nimsuggest/tests/fixtures/mclass_macro.nim
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
import macros
|
||||
|
||||
macro class*(head, body: untyped): untyped =
|
||||
# The macro is immediate, since all its parameters are untyped.
|
||||
# This means, it doesn't resolve identifiers passed to it.
|
||||
|
||||
var typeName, baseName: NimNode
|
||||
|
||||
# flag if object should be exported
|
||||
var exported: bool
|
||||
|
||||
if head.kind == nnkInfix and head[0].kind == nnkIdent and $head[0] == "of":
|
||||
# `head` is expression `typeName of baseClass`
|
||||
# echo head.treeRepr
|
||||
# --------------------
|
||||
# Infix
|
||||
# Ident !"of"
|
||||
# Ident !"Animal"
|
||||
# Ident !"RootObj"
|
||||
typeName = head[1]
|
||||
baseName = head[2]
|
||||
|
||||
elif head.kind == nnkInfix and head[0].kind == nnkIdent and
|
||||
$head[0] == "*" and head[2].kind == nnkPrefix and
|
||||
head[2][0].kind == nnkIdent and $head[2][0] == "of":
|
||||
# `head` is expression `typeName* of baseClass`
|
||||
# echo head.treeRepr
|
||||
# --------------------
|
||||
# Infix
|
||||
# Ident !"*"
|
||||
# Ident !"Animal"
|
||||
# Prefix
|
||||
# Ident !"of"
|
||||
# Ident !"RootObj"
|
||||
typeName = head[1]
|
||||
baseName = head[2][1]
|
||||
exported = true
|
||||
|
||||
else:
|
||||
quit "Invalid node: " & head.lispRepr
|
||||
|
||||
# The following prints out the AST structure:
|
||||
#
|
||||
# import macros
|
||||
# dumptree:
|
||||
# type X = ref object of Y
|
||||
# z: int
|
||||
# --------------------
|
||||
# StmtList
|
||||
# TypeSection
|
||||
# TypeDef
|
||||
# Ident !"X"
|
||||
# Empty
|
||||
# RefTy
|
||||
# ObjectTy
|
||||
# Empty
|
||||
# OfInherit
|
||||
# Ident !"Y"
|
||||
# RecList
|
||||
# IdentDefs
|
||||
# Ident !"z"
|
||||
# Ident !"int"
|
||||
# Empty
|
||||
|
||||
# create a type section in the result
|
||||
result = newNimNode(nnkStmtList)
|
||||
result.add(
|
||||
if exported:
|
||||
# mark `typeName` with an asterisk
|
||||
quote do:
|
||||
type `typeName`* = ref object of `baseName`
|
||||
else:
|
||||
quote do:
|
||||
type `typeName` = ref object of `baseName`
|
||||
)
|
||||
|
||||
# echo treeRepr(body)
|
||||
# --------------------
|
||||
# StmtList
|
||||
# VarSection
|
||||
# IdentDefs
|
||||
# Ident !"name"
|
||||
# Ident !"string"
|
||||
# Empty
|
||||
# IdentDefs
|
||||
# Ident !"age"
|
||||
# Ident !"int"
|
||||
# Empty
|
||||
# MethodDef
|
||||
# Ident !"vocalize"
|
||||
# Empty
|
||||
# Empty
|
||||
# FormalParams
|
||||
# Ident !"string"
|
||||
# Empty
|
||||
# Empty
|
||||
# StmtList
|
||||
# StrLit ...
|
||||
# MethodDef
|
||||
# Ident !"age_human_yrs"
|
||||
# Empty
|
||||
# Empty
|
||||
# FormalParams
|
||||
# Ident !"int"
|
||||
# Empty
|
||||
# Empty
|
||||
# StmtList
|
||||
# DotExpr
|
||||
# Ident !"this"
|
||||
# Ident !"age"
|
||||
|
||||
# var declarations will be turned into object fields
|
||||
var recList = newNimNode(nnkRecList)
|
||||
|
||||
# expected name of constructor
|
||||
let ctorName = newIdentNode("new" & $typeName)
|
||||
|
||||
# Iterate over the statements, adding `this: T`
|
||||
# to the parameters of functions, unless the
|
||||
# function is a constructor
|
||||
for node in body.children:
|
||||
case node.kind:
|
||||
|
||||
of nnkMethodDef, nnkProcDef:
|
||||
# check if it is the ctor proc
|
||||
if node.name.kind != nnkAccQuoted and node.name.basename == ctorName:
|
||||
# specify the return type of the ctor proc
|
||||
node.params[0] = typeName
|
||||
else:
|
||||
# inject `self: T` into the arguments
|
||||
node.params.insert(1, newIdentDefs(ident("self"), typeName))
|
||||
result.add(node)
|
||||
|
||||
of nnkVarSection:
|
||||
# variables get turned into fields of the type.
|
||||
for n in node.children:
|
||||
recList.add(n)
|
||||
|
||||
else:
|
||||
result.add(node)
|
||||
|
||||
# Inspect the tree structure:
|
||||
#
|
||||
# echo result.treeRepr
|
||||
# --------------------
|
||||
# StmtList
|
||||
# TypeSection
|
||||
# TypeDef
|
||||
# Ident !"Animal"
|
||||
# Empty
|
||||
# RefTy
|
||||
# ObjectTy
|
||||
# Empty
|
||||
# OfInherit
|
||||
# Ident !"RootObj"
|
||||
# Empty <= We want to replace this
|
||||
# MethodDef
|
||||
# ...
|
||||
|
||||
result[0][0][2][0][2] = recList
|
||||
|
||||
# Lets inspect the human-readable version of the output
|
||||
#echo repr(result)
|
||||
8
nimsuggest/tests/fixtures/mdep_v1.nim
vendored
Normal file
8
nimsuggest/tests/fixtures/mdep_v1.nim
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
type
|
||||
Foo* = object
|
||||
x*, y*: int
|
||||
9
nimsuggest/tests/fixtures/mdep_v2.nim
vendored
Normal file
9
nimsuggest/tests/fixtures/mdep_v2.nim
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
type
|
||||
Foo* = object
|
||||
x*, y*: int
|
||||
z*: string
|
||||
5
nimsuggest/tests/fixtures/mfakeassert.nim
vendored
Normal file
5
nimsuggest/tests/fixtures/mfakeassert.nim
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Template for testing defs
|
||||
|
||||
template fakeAssert*(cond: untyped, msg: string = "") =
|
||||
## template to allow def lookup testing
|
||||
if not cond: quit(1)
|
||||
15
nimsuggest/tests/fixtures/minclude_import.nim
vendored
Normal file
15
nimsuggest/tests/fixtures/minclude_import.nim
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Creates an awkward set of dependencies between this, import, and include.
|
||||
# This pattern appears in the compiler, compiler/(sem|ast|semexprs).nim.
|
||||
|
||||
import mfakeassert
|
||||
import minclude_types
|
||||
|
||||
proc say*(g: Greet): string =
|
||||
fakeAssert(true, "always works")
|
||||
g.greeting & ", " & g.subject & "!"
|
||||
|
||||
include minclude_include
|
||||
|
||||
proc say*(): string =
|
||||
fakeAssert(1 + 1 == 2, "math works")
|
||||
say(create())
|
||||
4
nimsuggest/tests/fixtures/minclude_include.nim
vendored
Normal file
4
nimsuggest/tests/fixtures/minclude_include.nim
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# this file is included and relies on imports within the include
|
||||
|
||||
proc create*(greeting: string = "Hello", subject: string = "World"): Greet =
|
||||
Greet(greeting: greeting, subject: subject)
|
||||
6
nimsuggest/tests/fixtures/minclude_types.nim
vendored
Normal file
6
nimsuggest/tests/fixtures/minclude_types.nim
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# types used by minclude_* (import or include), to find with def in include
|
||||
|
||||
type
|
||||
Greet* = object
|
||||
greeting*: string
|
||||
subject*: string
|
||||
19
nimsuggest/tests/fixtures/mstrutils.nim
vendored
Normal file
19
nimsuggest/tests/fixtures/mstrutils.nim
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import mfakeassert
|
||||
|
||||
func rereplace*(s, sub: string; by: string = ""): string {.used.} =
|
||||
## competes for priority in suggestion, here first, but never used in test
|
||||
|
||||
fakeAssert(true, "always works")
|
||||
result = by
|
||||
|
||||
func replace*(s, sub: string; by: string = ""): string =
|
||||
## this is a test version of strutils.replace, it simply returns `by`
|
||||
|
||||
fakeAssert("".len == 0, "empty string is empty")
|
||||
result = by
|
||||
|
||||
func rerereplace*(s, sub: string; by: string = ""): string {.used.} =
|
||||
## isn't used and appears last, lowest priority
|
||||
|
||||
fakeAssert(false, "never works")
|
||||
result = by
|
||||
Loading…
Add table
Add a link
Reference in a new issue