✨ feat(tsl-syntax): improve natural language topic routing
This commit is contained in:
@@ -14,7 +14,65 @@ lookup = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(lookup)
|
||||
|
||||
|
||||
NATURAL_LANGUAGE_CASES = (
|
||||
("帮我写个最简单能跑的天软脚本", "write", "01_quickstart.md"),
|
||||
("脚本和可复用函数文件有什么区别", "explain", "02_core_model.md"),
|
||||
("字符串和数组下标从几开始", "explain", "03_values_and_literals.md"),
|
||||
("常量怎么声明,变量能不能直接赋值", "explain", "04_variables_and_constants.md"),
|
||||
("函数怎么带默认参数", "write", "05_functions_and_calls.md"),
|
||||
("赋值和相等比较分别怎么写", "explain", "06_expressions_and_operators.md"),
|
||||
("循环里满足条件就跳出去", "write", "07_control_flow.md"),
|
||||
("怎么定义类并创建对象", "write", "08_objects_and_classes.md"),
|
||||
("多个文件复用一组函数怎么组织", "write", "09_units_and_scope.md"),
|
||||
("临时切换系统参数再调用函数", "write", "10_runtime_context_and_with.md"),
|
||||
("为什么声明函数后面写代码会报错", "diagnose", "11_pitfalls.md"),
|
||||
("二维数组怎么判断某行存在", "write", "12_matrix_and_collections.md"),
|
||||
("二维结果按某一列保留匹配行", "write", "13_resultset_and_filters.md"),
|
||||
("数据库左连接后分组排序", "write", "14_ts_sql.md"),
|
||||
("程序慢怎么计时找瓶颈", "diagnose", "15_debug_and_profiler.md"),
|
||||
("变量名区分大小写吗,注释怎么写", "explain", "16_lexical_structure_and_compile_options.md"),
|
||||
("字符串转整数失败怎么办", "diagnose", "17_types_and_conversions.md"),
|
||||
("调用 DLL 并开线程", "write", "18_external_calls_and_threads.md"),
|
||||
("找不到 tsf 文件怎么改搜索路径", "diagnose", "19_namespace_libpath_and_unit_runtime.md"),
|
||||
("运行时怎么查看对象属于哪个类", "explain", "20_object_runtime_and_introspection.md"),
|
||||
("内存流怎么读写", "write", "21_builtin_runtime_objects.md"),
|
||||
("矩阵求逆和转置", "write", "22_matrix_deep_dive.md"),
|
||||
("高性能矩阵怎么排序", "write", "23_fmarray.md"),
|
||||
("让自定义对象支持下标和 for in", "write", "24_object_overloads_and_iteration.md"),
|
||||
)
|
||||
|
||||
|
||||
class TslSyntaxLookupTests(unittest.TestCase):
|
||||
def test_natural_language_topic_matrix(self):
|
||||
top1 = 0
|
||||
top5 = 0
|
||||
misses = []
|
||||
for query, mode, expected_page in NATURAL_LANGUAGE_CASES:
|
||||
pages = [
|
||||
match.section.page.name
|
||||
for match in lookup.query_sections(query, mode).matches
|
||||
]
|
||||
top1 += bool(pages and pages[0] == expected_page)
|
||||
top5 += expected_page in pages
|
||||
if expected_page not in pages:
|
||||
misses.append((query, expected_page, pages))
|
||||
|
||||
self.assertGreaterEqual(top1, 20, (top1, misses))
|
||||
self.assertEqual(top5, len(NATURAL_LANGUAGE_CASES), (top5, misses))
|
||||
|
||||
def test_short_ascii_tokens_use_identifier_boundaries(self):
|
||||
result = lookup.query_sections("if", "explain")
|
||||
ids = "\n".join(match.section.id for match in result.matches)
|
||||
|
||||
self.assertIn("07_control_flow", ids)
|
||||
self.assertNotIn("tinifile", ids)
|
||||
self.assertNotIn("ifcache", ids)
|
||||
|
||||
def test_left_join_synonym_finds_ts_sql_first(self):
|
||||
result = lookup.query_sections("数据库左连接", "write")
|
||||
|
||||
self.assertEqual(result.matches[0].section.page.name, "14_ts_sql.md")
|
||||
|
||||
def test_query_renders_compact_candidates_without_bodies_or_absolute_paths(self):
|
||||
result = lookup.query_sections("函数 默认参数", "write", limit=5)
|
||||
rendered = lookup.render_candidates(result)
|
||||
|
||||
Reference in New Issue
Block a user