test: свод 2 — JS-оракул поиска, фильтров и вариантов экрана «до» и векторы
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dbf90477d2
commit
adcb9d1d3b
86
api/tests/fixtures/js_number_text_vectors.json
vendored
Normal file
86
api/tests/fixtures/js_number_text_vectors.json
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"js": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "-0",
|
||||||
|
"js": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"js": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "-1",
|
||||||
|
"js": "-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "100",
|
||||||
|
"js": "100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "100.00",
|
||||||
|
"js": "100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1234.50",
|
||||||
|
"js": "1234.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "12.34",
|
||||||
|
"js": "12.34"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0.5",
|
||||||
|
"js": "0.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0.30000000000000004",
|
||||||
|
"js": "0.30000000000000004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0.000001",
|
||||||
|
"js": "0.000001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1e-7",
|
||||||
|
"js": "1e-7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "-1.5e-10",
|
||||||
|
"js": "-1.5e-10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "123e-20",
|
||||||
|
"js": "1.23e-18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1e15",
|
||||||
|
"js": "1000000000000000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1e20",
|
||||||
|
"js": "100000000000000000000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1e21",
|
||||||
|
"js": "1e+21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "123456789012345680000",
|
||||||
|
"js": "123456789012345680000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "9007199254740993",
|
||||||
|
"js": "9007199254740992"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "5e-324",
|
||||||
|
"js": "5e-324"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1.7976931348623157e308",
|
||||||
|
"js": "1.7976931348623157e+308"
|
||||||
|
}
|
||||||
|
]
|
||||||
962
api/tests/fixtures/svod2_screen_vectors.json
vendored
Normal file
962
api/tests/fixtures/svod2_screen_vectors.json
vendored
Normal file
@ -0,0 +1,962 @@
|
|||||||
|
{
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 1,
|
||||||
|
"header": {
|
||||||
|
"name": "Аренда помещения",
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": "Развитие",
|
||||||
|
"org_name": "Филиал Ёлки"
|
||||||
|
},
|
||||||
|
"contract_summary": {
|
||||||
|
"counterparty": "ООО Ромашка"
|
||||||
|
},
|
||||||
|
"contract_detail": {
|
||||||
|
"counterparty": null,
|
||||||
|
"ceiling_amount": 1234.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 2,
|
||||||
|
"header": {
|
||||||
|
"name": "АРЕНДА склада",
|
||||||
|
"smeta_type": "АХР",
|
||||||
|
"smeta_direction": "Поддержка",
|
||||||
|
"org_name": "Филиал Ёлки"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"counterparty": "ООО Ромашка Плюс",
|
||||||
|
"ceiling_amount": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 3,
|
||||||
|
"header": {
|
||||||
|
"name": "Ёлка новогодняя",
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": null,
|
||||||
|
"org_name": "филиал ёлки "
|
||||||
|
},
|
||||||
|
"contract_summary": {
|
||||||
|
"counterparty": "ИП Ёж"
|
||||||
|
},
|
||||||
|
"contract_detail": {
|
||||||
|
"ceiling_amount": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 4,
|
||||||
|
"header": {
|
||||||
|
"name": "ёжик",
|
||||||
|
"smeta_type": "кв ",
|
||||||
|
"smeta_direction": "Развитие",
|
||||||
|
"org_name": "Центр"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"ceiling_amount": 1e-7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 5,
|
||||||
|
"header": {
|
||||||
|
"name": "Услуги связи",
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": "Поддержка",
|
||||||
|
"org_name": "Центр"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"note": "a b"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 6,
|
||||||
|
"header": {
|
||||||
|
"name": "Без маркера",
|
||||||
|
"smeta_type": "АХР",
|
||||||
|
"smeta_direction": "Развитие",
|
||||||
|
"org_name": "Север"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"note": "xy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 7,
|
||||||
|
"header": {
|
||||||
|
"name": "Флаг",
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": "Развитие",
|
||||||
|
"org_name": "Север",
|
||||||
|
"is_active": true
|
||||||
|
},
|
||||||
|
"contract_summary": {
|
||||||
|
"flag": true
|
||||||
|
},
|
||||||
|
"contract_detail": {
|
||||||
|
"note": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 8,
|
||||||
|
"header": {
|
||||||
|
"name": null,
|
||||||
|
"smeta_type": null,
|
||||||
|
"smeta_direction": null,
|
||||||
|
"org_name": null
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 9,
|
||||||
|
"header": {
|
||||||
|
"name": "Итого 1",
|
||||||
|
"smeta_type": "АХР",
|
||||||
|
"smeta_direction": "Поддержка",
|
||||||
|
"org_name": "Центр"
|
||||||
|
},
|
||||||
|
"contract_summary": {
|
||||||
|
"counterparty": "ООО Ромашка"
|
||||||
|
},
|
||||||
|
"contract_detail": {
|
||||||
|
"counterparty": "ООО Ромашка",
|
||||||
|
"ceiling_amount": 1234.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 10,
|
||||||
|
"header": {
|
||||||
|
"name": "Прочее",
|
||||||
|
"smeta_type": "ПР",
|
||||||
|
"smeta_direction": "Развитие",
|
||||||
|
"org_name": "Филиал Ёлки"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"ceiling_amount": 1e-7,
|
||||||
|
"note": "Договор №1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"line_id": 11,
|
||||||
|
"header": {
|
||||||
|
"name": "Лицензии",
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": "Поддержка",
|
||||||
|
"org_name": "Юг"
|
||||||
|
},
|
||||||
|
"contract_summary": {},
|
||||||
|
"contract_detail": {
|
||||||
|
"ceiling_amount": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"search": "",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
5
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "аРЕНДА",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 2,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 2,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "ё",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 5,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 5,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
3
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "ромаш",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
2,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 2,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 2,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "1234.5",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 2,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 2,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "1234.50",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [],
|
||||||
|
"found": {
|
||||||
|
"found": 0,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 0,
|
||||||
|
"smeta_type": [],
|
||||||
|
"smeta_direction": [],
|
||||||
|
"org_name": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": " аренда ",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 2,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 2,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": " ",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
5
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "1",
|
||||||
|
"filters": {},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 6,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 6,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
3
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "",
|
||||||
|
"filters": {
|
||||||
|
"smeta_type": "кв "
|
||||||
|
},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
7,
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
5
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
3
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "",
|
||||||
|
"filters": {
|
||||||
|
"org_name": "Филиал Ёлки"
|
||||||
|
},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "",
|
||||||
|
"filters": {
|
||||||
|
"smeta_type": "КВ",
|
||||||
|
"smeta_direction": "Развитие"
|
||||||
|
},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
7
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
3
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "ё",
|
||||||
|
"filters": {
|
||||||
|
"smeta_type": "КВ"
|
||||||
|
},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 5,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 5,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"кв ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"search": "",
|
||||||
|
"filters": {
|
||||||
|
"org_name": "филиал ёлки"
|
||||||
|
},
|
||||||
|
"line_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
"found": {
|
||||||
|
"found": 11,
|
||||||
|
"total": 11
|
||||||
|
},
|
||||||
|
"facets": {
|
||||||
|
"total": 11,
|
||||||
|
"search_total": 11,
|
||||||
|
"smeta_type": [
|
||||||
|
[
|
||||||
|
"АХР",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"КВ",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ПР",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"smeta_direction": [
|
||||||
|
[
|
||||||
|
"Поддержка",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Развитие",
|
||||||
|
2
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"org_name": [
|
||||||
|
[
|
||||||
|
"Север",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Филиал Ёлки",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"филиал ёлки ",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Центр",
|
||||||
|
3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Юг",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
149
perf/analysis/svod2_search_oracle.mjs
Normal file
149
perf/analysis/svod2_search_oracle.mjs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Оракул экрана «до» свода 2 (Svod2Page на коммите 399234a + material-react-table). Копии дословные.
|
||||||
|
// matchesSearch: Svod2Page.jsx:283-294; equals: material-react-table/dist/index.esm.js:663-667.
|
||||||
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const matchesSearch = (row, query) => {
|
||||||
|
const searchableData = {
|
||||||
|
...row.data?.header,
|
||||||
|
...row.data?.contract_summary,
|
||||||
|
...row.data?.contract_detail,
|
||||||
|
};
|
||||||
|
return Object.values(searchableData).some((value) =>
|
||||||
|
String(value ?? '')
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(query),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const equals = (row, id, filterValue) => {
|
||||||
|
var _a;
|
||||||
|
return ((_a = row.getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim()) ===
|
||||||
|
filterValue.toString().toLowerCase().trim();
|
||||||
|
};
|
||||||
|
equals.autoRemove = (val) => !val;
|
||||||
|
|
||||||
|
export { matchesSearch, equals };
|
||||||
|
|
||||||
|
export const FILTER_COLUMNS = ['smeta_type', 'smeta_direction', 'org_name'];
|
||||||
|
|
||||||
|
// accessorFn колонок: valueAt(row, ['header', id])
|
||||||
|
const asTableRow = (row, id) => ({ getValue: () => row.data?.header?.[id] });
|
||||||
|
const cellValue = (row, id) => row.data?.header?.[id];
|
||||||
|
|
||||||
|
const activeFilters = (filters, skipId) =>
|
||||||
|
FILTER_COLUMNS.filter((id) => id !== skipId && filters[id] && !equals.autoRemove(filters[id]));
|
||||||
|
|
||||||
|
const bySearch = (rows, search) => {
|
||||||
|
const normalizedSearch = String(search ?? '').trim().toLowerCase();
|
||||||
|
return normalizedSearch ? rows.filter((row) => matchesSearch(row, normalizedSearch)) : rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
const byFilters = (rows, filters, skipId) => {
|
||||||
|
const ids = activeFilters(filters, skipId);
|
||||||
|
return rows.filter((row) => ids.every((id) => equals({ getValue: () => cellValue(row, id) }, id, filters[id])));
|
||||||
|
};
|
||||||
|
|
||||||
|
export function screenRows(rows, { search = '', filters = {} } = {}) {
|
||||||
|
return byFilters(bySearch(rows, search), filters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function screenFound(rows, search) {
|
||||||
|
return { found: bySearch(rows, search).length, total: rows.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function screenFacets(rows, { search = '', filters = {} } = {}) {
|
||||||
|
const searched = bySearch(rows, search);
|
||||||
|
const result = { total: rows.length, search_total: searched.length };
|
||||||
|
for (const id of FILTER_COLUMNS) {
|
||||||
|
const counts = new Map();
|
||||||
|
for (const row of byFilters(searched, filters, id)) {
|
||||||
|
const value = asTableRow(row, id).getValue(id);
|
||||||
|
counts.set(value, (counts.get(value) ?? 0) + 1);
|
||||||
|
}
|
||||||
|
result[id] = Array.from(counts.keys())
|
||||||
|
.filter((value) => value !== null && value !== undefined)
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
.map((value) => [value, counts.get(value)]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NUMBER_VECTOR_INPUTS = [
|
||||||
|
'0', '-0', '1', '-1', '100', '100.00', '1234.50', '12.34', '0.5', '0.30000000000000004',
|
||||||
|
'0.000001', '1e-7', '-1.5e-10', '123e-20', '1e15', '1e20', '1e21', '123456789012345680000',
|
||||||
|
'9007199254740993', '5e-324', '1.7976931348623157e308',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Числа в строках берём через JSON.parse, чтобы запись была как у JSON-ответа API.
|
||||||
|
const J = (text) => JSON.parse(text);
|
||||||
|
|
||||||
|
export const SYNTHETIC_ROWS = [
|
||||||
|
{ data: { line_id: 1, header: { name: 'Аренда помещения', smeta_type: 'КВ', smeta_direction: 'Развитие', org_name: 'Филиал Ёлки' },
|
||||||
|
contract_summary: { counterparty: 'ООО Ромашка' }, contract_detail: { counterparty: null, ceiling_amount: J('1234.50') } } },
|
||||||
|
{ data: { line_id: 2, header: { name: 'АРЕНДА склада', smeta_type: 'АХР', smeta_direction: 'Поддержка', org_name: 'Филиал Ёлки' },
|
||||||
|
contract_summary: {}, contract_detail: { counterparty: 'ООО Ромашка Плюс', ceiling_amount: J('100') } } },
|
||||||
|
{ data: { line_id: 3, header: { name: 'Ёлка новогодняя', smeta_type: 'КВ', smeta_direction: null, org_name: 'филиал ёлки ' },
|
||||||
|
contract_summary: { counterparty: 'ИП Ёж' }, contract_detail: { ceiling_amount: J('0') } } },
|
||||||
|
{ data: { line_id: 4, header: { name: 'ёжик', smeta_type: 'кв ', smeta_direction: 'Развитие', org_name: 'Центр' },
|
||||||
|
contract_summary: {}, contract_detail: { ceiling_amount: J('1e-7') } } },
|
||||||
|
{ data: { line_id: 5, header: { name: 'Услуги связи', smeta_type: 'КВ', smeta_direction: 'Поддержка', org_name: 'Центр' },
|
||||||
|
contract_summary: {}, contract_detail: { note: 'a b' } } },
|
||||||
|
{ data: { line_id: 6, header: { name: 'Без маркера', smeta_type: 'АХР', smeta_direction: 'Развитие', org_name: 'Север' },
|
||||||
|
contract_summary: {}, contract_detail: { note: 'xy' } } },
|
||||||
|
{ data: { line_id: 7, header: { name: 'Флаг', smeta_type: 'КВ', smeta_direction: 'Развитие', org_name: 'Север', is_active: true },
|
||||||
|
contract_summary: { flag: true }, contract_detail: { note: null } } },
|
||||||
|
{ data: { line_id: 8, header: { name: null, smeta_type: null, smeta_direction: null, org_name: null },
|
||||||
|
contract_summary: {}, contract_detail: {} } },
|
||||||
|
{ data: { line_id: 9, header: { name: 'Итого 1', smeta_type: 'АХР', smeta_direction: 'Поддержка', org_name: 'Центр' },
|
||||||
|
contract_summary: { counterparty: 'ООО Ромашка' }, contract_detail: { counterparty: 'ООО Ромашка', ceiling_amount: J('1234.5') } } },
|
||||||
|
{ data: { line_id: 10, header: { name: 'Прочее', smeta_type: 'ПР', smeta_direction: 'Развитие', org_name: 'Филиал Ёлки' },
|
||||||
|
contract_summary: {}, contract_detail: { ceiling_amount: J('1e-7'), note: 'Договор №1' } } },
|
||||||
|
{ data: { line_id: 11, header: { name: 'Лицензии', smeta_type: 'КВ', smeta_direction: 'Поддержка', org_name: 'Юг' },
|
||||||
|
contract_summary: {}, contract_detail: { ceiling_amount: J('100.00') } } },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const SCREEN_CASES = [
|
||||||
|
{ search: '', filters: {} },
|
||||||
|
{ search: 'аРЕНДА', filters: {} },
|
||||||
|
{ search: 'ё', filters: {} },
|
||||||
|
{ search: 'ромаш', filters: {} },
|
||||||
|
{ search: '1234.5', filters: {} },
|
||||||
|
{ search: '1234.50', filters: {} },
|
||||||
|
{ search: ' аренда ', filters: {} },
|
||||||
|
{ search: ' ', filters: {} },
|
||||||
|
{ search: '1', filters: {} },
|
||||||
|
{ search: '', filters: { smeta_type: 'кв ' } },
|
||||||
|
{ search: '', filters: { org_name: 'Филиал Ёлки' } },
|
||||||
|
{ search: '', filters: { smeta_type: 'КВ', smeta_direction: 'Развитие' } },
|
||||||
|
{ search: 'ё', filters: { smeta_type: 'КВ' } },
|
||||||
|
{ search: '', filters: { org_name: 'филиал ёлки' } },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function emitNumberVectors() {
|
||||||
|
return NUMBER_VECTOR_INPUTS.map((input) => ({ input, js: String(JSON.parse(input)) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function emitScreenVectors() {
|
||||||
|
return {
|
||||||
|
rows: SYNTHETIC_ROWS,
|
||||||
|
cases: SCREEN_CASES.map(({ search, filters }) => ({
|
||||||
|
search,
|
||||||
|
filters,
|
||||||
|
line_ids: screenRows(SYNTHETIC_ROWS, { search, filters }).map((r) => r.data.line_id),
|
||||||
|
found: screenFound(SYNTHETIC_ROWS, search),
|
||||||
|
facets: screenFacets(SYNTHETIC_ROWS, { search, filters }),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
|
const i = process.argv.indexOf('--emit-vectors');
|
||||||
|
if (i > 0 && process.argv[i + 1]) {
|
||||||
|
const dir = process.argv[i + 1];
|
||||||
|
mkdirSync(dir, { recursive: true });
|
||||||
|
writeFileSync(path.join(dir, 'js_number_text_vectors.json'), `${JSON.stringify(emitNumberVectors(), null, 2)}\n`);
|
||||||
|
writeFileSync(path.join(dir, 'svod2_screen_vectors.json'), `${JSON.stringify(emitScreenVectors(), null, 2)}\n`);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
perf/analysis/svod2_search_oracle.test.mjs
Normal file
60
perf/analysis/svod2_search_oracle.test.mjs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import {
|
||||||
|
emitNumberVectors,
|
||||||
|
emitScreenVectors,
|
||||||
|
equals,
|
||||||
|
matchesSearch,
|
||||||
|
screenFacets,
|
||||||
|
screenFound,
|
||||||
|
screenRows,
|
||||||
|
} from './svod2_search_oracle.mjs';
|
||||||
|
|
||||||
|
const mk = (id, type, dir, org) => ({ data: { line_id: id, header: { smeta_type: type, smeta_direction: dir, org_name: org } } });
|
||||||
|
const rows2 = [mk(1, 'КВ', 'Развитие', 'А'), mk(2, 'АХР', 'Поддержка', 'Б')];
|
||||||
|
const rows3 = [mk(1, 'КВ', 'Р', 'Филиал Ёлки'), mk(2, 'КВ', 'Р', 'Филиал Ёлки'), mk(3, 'КВ', 'Р', null)];
|
||||||
|
|
||||||
|
test('перекрытое поле contract_summary не ищется', () => {
|
||||||
|
const row = { data: { header: { name: 'x' }, contract_summary: { counterparty: 'ООО Ромашка' }, contract_detail: { counterparty: null } } };
|
||||||
|
assert.equal(matchesSearch(row, 'ромаш'), false);
|
||||||
|
});
|
||||||
|
test('число ищется в записи JS', () => {
|
||||||
|
const row = { data: { header: {}, contract_summary: {}, contract_detail: JSON.parse('{"ceiling_amount": 1234.50}') } };
|
||||||
|
assert.equal(matchesSearch(row, '1234.5'), true);
|
||||||
|
assert.equal(matchesSearch(row, '1234.50'), false);
|
||||||
|
});
|
||||||
|
test('screenRows: trim + lower, NBSP по краям', () => {
|
||||||
|
const rows = [{ data: { line_id: 1, header: { name: 'Аренда помещения' } } }];
|
||||||
|
assert.deepEqual(screenRows(rows, { search: ' АРЕНДА ' }).map((r) => r.data.line_id), [1]);
|
||||||
|
assert.deepEqual(screenRows(rows, { search: ' аренда ' }).map((r) => r.data.line_id), [1]);
|
||||||
|
});
|
||||||
|
test('equals: регистр и пробелы по краям, null не проходит', () => {
|
||||||
|
const r = (v) => ({ getValue: () => v });
|
||||||
|
assert.equal(equals(r('КВ'), 'smeta_type', 'кв '), true);
|
||||||
|
assert.equal(equals(r(null), 'smeta_type', 'кв'), false);
|
||||||
|
});
|
||||||
|
test('screenFacets: свой фильтр не применяется, чужие — да', () => {
|
||||||
|
const f = screenFacets(rows2, { filters: { smeta_type: 'КВ' } });
|
||||||
|
assert.deepEqual(f.smeta_type, [['АХР', 1], ['КВ', 1]]);
|
||||||
|
assert.deepEqual(f.smeta_direction, [['Развитие', 1]]);
|
||||||
|
});
|
||||||
|
test('screenFacets: одинаковые названия — один вариант, null не выдаётся', () => {
|
||||||
|
assert.deepEqual(screenFacets(rows3).org_name, [['Филиал Ёлки', 2]]);
|
||||||
|
});
|
||||||
|
test('screenFound считает только поиск', () => {
|
||||||
|
assert.deepEqual(screenFound(rows2, ''), { found: 2, total: 2 });
|
||||||
|
});
|
||||||
|
test('векторы чисел', () => {
|
||||||
|
const v = Object.fromEntries(emitNumberVectors().map(({ input, js }) => [input, js]));
|
||||||
|
assert.equal(v['1e21'], '1e+21');
|
||||||
|
assert.equal(v['-0'], '0');
|
||||||
|
assert.equal(v['1e-7'], '1e-7');
|
||||||
|
assert.equal(v['0.000001'], '0.000001');
|
||||||
|
assert.equal(v['100.00'], '100');
|
||||||
|
assert.equal(v['9007199254740993'], '9007199254740992');
|
||||||
|
});
|
||||||
|
test('векторы экрана: не меньше 12 случаев', () => {
|
||||||
|
const s = emitScreenVectors();
|
||||||
|
assert.ok(s.cases.length >= 12);
|
||||||
|
assert.ok(s.rows.length >= 10 && s.rows.length <= 15);
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user