@ryuzaki13/react-foundation-lib 1.3.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -16
- package/dist/table/index.d.ts +1 -0
- package/dist/table/index.d.ts.map +1 -1
- package/dist/table/index.js +77 -64
- package/dist/table/index.js.map +1 -1
- package/dist/table/tanStackFeatures.d.ts +19 -0
- package/dist/table/tanStackFeatures.d.ts.map +1 -0
- package/dist/table/types.d.ts +17 -2
- package/dist/table/types.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/array/README.mdx +1630 -0
- package/src/binary/README.mdx +1405 -0
- package/src/copy/README.mdx +992 -0
- package/src/crypto/README.mdx +1052 -0
- package/src/dom/README.mdx +2179 -0
- package/src/file/README.mdx +1957 -0
- package/src/formatters/README.mdx +469 -0
- package/src/formatters/boolean/README.mdx +494 -0
- package/src/formatters/date/README.mdx +732 -0
- package/src/formatters/number/README.mdx +542 -0
- package/src/formatters/pipeline/README.mdx +629 -0
- package/src/formatters/rowBased/README.mdx +486 -0
- package/src/formatters/strings/README.mdx +442 -0
- package/src/formatters/valueState/README.mdx +459 -0
- package/src/formulas/README.mdx +1283 -0
- package/src/binary/README.md +0 -110
- package/src/docs/browserAndReact.mdx +0 -150
- package/src/docs/filesAndExcel.mdx +0 -163
- package/src/docs/formatters-runtime.mdx +0 -455
- package/src/docs/formatters.mdx +0 -380
- package/src/docs/odataAndTables.mdx +0 -178
- package/src/docs/pureUtilities.mdx +0 -96
- package/src/docs/runtimeAndState.mdx +0 -155
- package/src/file/README.md +0 -289
- package/src/formatters/date/README.md +0 -520
- package/src/formatters/number/README.md +0 -123
- package/src/formatters/valueState/README.md +0 -275
- package/src/formulas/README.md +0 -42
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="Foundation Lib/API/Formatters/Boolean" />
|
|
4
|
+
|
|
5
|
+
# Boolean и ABAP boolean через `@ryuzaki13/react-foundation-lib/formatters`
|
|
6
|
+
|
|
7
|
+
Подмодуль `boolean` преобразует значения между JavaScript `boolean` и двухсимвольным ABAP-контрактом:
|
|
8
|
+
|
|
9
|
+
- `"X"` — истина;
|
|
10
|
+
- один обычный пробел `" "` — ложь.
|
|
11
|
+
|
|
12
|
+
Также он предоставляет более широкий parser `parseBoolean` для простых пользовательских или transport-значений.
|
|
13
|
+
|
|
14
|
+
README рассчитан на разработчика без доступа к исходному коду. Ниже описано точное, местами неочевидное поведение всех трёх публичных функций. Особенно важно не путать строгий `parseAbapBoolean`, расширенный `parseBoolean` и truthy-семантику `toAbapBoolean`.
|
|
15
|
+
|
|
16
|
+
## Содержание
|
|
17
|
+
|
|
18
|
+
- [Назначение и границы](#назначение-и-границы)
|
|
19
|
+
- [Установка и импорт](#установка-и-импорт)
|
|
20
|
+
- [Минимальные понятия](#минимальные-понятия)
|
|
21
|
+
- [Как выбрать функцию](#как-выбрать-функцию)
|
|
22
|
+
- [`parseAbapBoolean`](#parseabapboolean)
|
|
23
|
+
- [`parseBoolean`](#parseboolean)
|
|
24
|
+
- [`toAbapBoolean`](#toabapboolean)
|
|
25
|
+
- [Практические рецепты](#практические-рецепты)
|
|
26
|
+
- [Ошибки и ограничения](#ошибки-и-ограничения)
|
|
27
|
+
- [Тестирование](#тестирование)
|
|
28
|
+
- [Краткий справочник](#краткий-справочник)
|
|
29
|
+
- [Вопросы и ответы](#вопросы-и-ответы)
|
|
30
|
+
|
|
31
|
+
## Назначение и границы
|
|
32
|
+
|
|
33
|
+
### Что делает подмодуль
|
|
34
|
+
|
|
35
|
+
- строго читает ABAP boolean `"X"`;
|
|
36
|
+
- распознаёт небольшой набор строковых true-значений;
|
|
37
|
+
- применяет стандартную JavaScript truthy/falsy-семантику к нестроковым значениям;
|
|
38
|
+
- формирует `AbapBoolean`, то есть `"X" | " "`.
|
|
39
|
+
|
|
40
|
+
### Чего подмодуль не делает
|
|
41
|
+
|
|
42
|
+
- не нормализует пробелы через `trim()`;
|
|
43
|
+
- не принимает `"да"`, `"нет"`, `"yes"`, `"no"`, `"on"`, `"off"`;
|
|
44
|
+
- не валидирует внешний DTO целиком;
|
|
45
|
+
- не сообщает, почему значение было интерпретировано как `false`;
|
|
46
|
+
- не отличает отсутствующее значение от явно переданного `false`;
|
|
47
|
+
- не сериализует JSON, URL или OData query;
|
|
48
|
+
- не гарантирует, что широкий `toAbapBoolean(unknown)` подходит конкретному backend-контракту.
|
|
49
|
+
|
|
50
|
+
## Установка и импорт
|
|
51
|
+
|
|
52
|
+
Установите пакет:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @ryuzaki13/react-foundation-lib
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Все boolean helpers импортируются из единственного опубликованного subpath `/formatters`:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { parseAbapBoolean, parseBoolean, toAbapBoolean } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
62
|
+
|
|
63
|
+
import type { AbapBoolean } from "@ryuzaki13/react-foundation-lib/types";
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Отдельного package export `/formatters/boolean` нет:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// Неправильно.
|
|
70
|
+
import { parseAbapBoolean } from "@ryuzaki13/react-foundation-lib/formatters/boolean";
|
|
71
|
+
|
|
72
|
+
// Правильно.
|
|
73
|
+
import { parseAbapBoolean } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Функции не зависят от React, DOM или browser API и могут выполняться в browser, Node.js и worker runtime.
|
|
77
|
+
|
|
78
|
+
## Минимальные понятия
|
|
79
|
+
|
|
80
|
+
### JavaScript boolean
|
|
81
|
+
|
|
82
|
+
Тип `boolean` имеет только два значения:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const enabled: boolean = true;
|
|
86
|
+
const disabled: boolean = false;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Строки `"true"` и `"false"` не являются boolean:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
typeof true; // "boolean"
|
|
93
|
+
typeof "true"; // "string"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Truthy и falsy
|
|
97
|
+
|
|
98
|
+
JavaScript умеет приводить произвольное значение к boolean:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
Boolean(1); // true
|
|
102
|
+
Boolean(0); // false
|
|
103
|
+
Boolean("text"); // true
|
|
104
|
+
Boolean(""); // false
|
|
105
|
+
Boolean({}); // true
|
|
106
|
+
Boolean([]); // true
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Основные falsy-значения:
|
|
110
|
+
|
|
111
|
+
- `false`;
|
|
112
|
+
- `0` и `-0`;
|
|
113
|
+
- `0n`;
|
|
114
|
+
- пустая строка `""`;
|
|
115
|
+
- `null`;
|
|
116
|
+
- `undefined`;
|
|
117
|
+
- `NaN`.
|
|
118
|
+
|
|
119
|
+
Почти всё остальное truthy. В частности, строки `"false"`, `"0 "`, объекты и массивы truthy.
|
|
120
|
+
|
|
121
|
+
### ABAP boolean
|
|
122
|
+
|
|
123
|
+
Публичный тип пакета:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
type AbapBoolean = "X" | " ";
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Ложь представлена не пустой строкой, а ровно одним пробелом. Это важно при сравнении, логировании и сериализации:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const value: AbapBoolean = " ";
|
|
133
|
+
|
|
134
|
+
console.log(value.length); // 1
|
|
135
|
+
console.log(value === ""); // false
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### `unknown`
|
|
139
|
+
|
|
140
|
+
Все три функции принимают `unknown`. Это означает, что caller может передать любое runtime-значение, а функция сама выберет ветку обработки.
|
|
141
|
+
|
|
142
|
+
Широкий вход удобен на transport boundary, но не превращает функцию в строгий validator. Если нужно отклонять неизвестные значения, сначала реализуйте явную validation policy.
|
|
143
|
+
|
|
144
|
+
## Как выбрать функцию
|
|
145
|
+
|
|
146
|
+
| Задача | Функция |
|
|
147
|
+
| ---------------------------------------------------- | ------------------ |
|
|
148
|
+
| Прочитать точное backend-значение `"X"`/`" "` | `parseAbapBoolean` |
|
|
149
|
+
| Прочитать `true`, `"true"`, `"X"`, `"x"`, `1`, `"1"` | `parseBoolean` |
|
|
150
|
+
| Записать JavaScript boolean в ABAP `"X"`/`" "` | `toAbapBoolean` |
|
|
151
|
+
|
|
152
|
+
Для DTO с известным ABAP-контрактом предпочтительная пара:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const enabled = parseAbapBoolean(dto.ENABLED);
|
|
156
|
+
const payload = { ENABLED: toAbapBoolean(enabled) };
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Не заменяйте строгий parser на `parseBoolean` без осознанного расширения контракта: lowercase `"x"` строгий parser отвергает, а расширенный принимает.
|
|
160
|
+
|
|
161
|
+
## `parseAbapBoolean`
|
|
162
|
+
|
|
163
|
+
### Сигнатура
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
function parseAbapBoolean(value: unknown): boolean;
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Функция возвращает `true` только для строки, которая в точности равна uppercase `"X"`.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
parseAbapBoolean("X"); // true
|
|
173
|
+
parseAbapBoolean(" "); // false
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Точная таблица поведения
|
|
177
|
+
|
|
178
|
+
| Вход | Результат | Причина |
|
|
179
|
+
| ----------- | --------- | -------------------------------- |
|
|
180
|
+
| `"X"` | `true` | точное допустимое значение |
|
|
181
|
+
| `"x"` | `false` | регистр отличается |
|
|
182
|
+
| `" X "` | `false` | функция не вызывает `trim()` |
|
|
183
|
+
| `"true"` | `false` | это не ABAP marker |
|
|
184
|
+
| `"1"` | `false` | это не ABAP marker |
|
|
185
|
+
| `" "` | `false` | ABAP false |
|
|
186
|
+
| `""` | `false` | пустая строка |
|
|
187
|
+
| `true` | `false` | функция требует строку `"X"` |
|
|
188
|
+
| `1` | `false` | функция требует строку `"X"` |
|
|
189
|
+
| `null` | `false` | любое другое значение даёт false |
|
|
190
|
+
| `undefined` | `false` | любое другое значение даёт false |
|
|
191
|
+
|
|
192
|
+
### Важное следствие
|
|
193
|
+
|
|
194
|
+
Функция не отличает несколько разных ситуаций:
|
|
195
|
+
|
|
196
|
+
- backend явно прислал `" "`;
|
|
197
|
+
- поле отсутствует;
|
|
198
|
+
- backend прислал ошибочное `"x"`;
|
|
199
|
+
- backend прислал число;
|
|
200
|
+
- caller передал `null`.
|
|
201
|
+
|
|
202
|
+
Во всех случаях результат равен `false`. Если различие важно, проверьте внешний контракт до вызова:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
function assertAbapBoolean(value: unknown): asserts value is AbapBoolean {
|
|
206
|
+
if (value !== "X" && value !== " ") {
|
|
207
|
+
throw new TypeError("Ожидалось ABAP boolean: 'X' или один пробел");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
assertAbapBoolean(dto.ENABLED);
|
|
212
|
+
const enabled = parseAbapBoolean(dto.ENABLED);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## `parseBoolean`
|
|
216
|
+
|
|
217
|
+
### Сигнатура
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
function parseBoolean(value: unknown): boolean;
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Алгоритм:
|
|
224
|
+
|
|
225
|
+
1. любое falsy-значение сразу превращается в `false`;
|
|
226
|
+
2. строка приводится к lowercase без `trim()`;
|
|
227
|
+
3. строка считается истинной только для `"true"`, `"x"` или `"1"`;
|
|
228
|
+
4. нестроковое truthy-значение обрабатывается через `Boolean(value)`.
|
|
229
|
+
|
|
230
|
+
### Строки
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
parseBoolean("true"); // true
|
|
234
|
+
parseBoolean("TRUE"); // true
|
|
235
|
+
parseBoolean("X"); // true
|
|
236
|
+
parseBoolean("x"); // true
|
|
237
|
+
parseBoolean("1"); // true
|
|
238
|
+
|
|
239
|
+
parseBoolean("false"); // false
|
|
240
|
+
parseBoolean("0"); // false
|
|
241
|
+
parseBoolean("yes"); // false
|
|
242
|
+
parseBoolean(" true "); // false: пробелы не обрезаются
|
|
243
|
+
parseBoolean(""); // false
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Для строк функция не использует общую truthy-семантику. Например, обычная JavaScript-строка `"false"` truthy, но `parseBoolean("false")` специально возвращает `false`.
|
|
247
|
+
|
|
248
|
+
### Нестроковые значения
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
parseBoolean(true); // true
|
|
252
|
+
parseBoolean(false); // false
|
|
253
|
+
parseBoolean(1); // true
|
|
254
|
+
parseBoolean(-1); // true
|
|
255
|
+
parseBoolean(0); // false
|
|
256
|
+
parseBoolean({}); // true
|
|
257
|
+
parseBoolean([]); // true
|
|
258
|
+
parseBoolean(null); // false
|
|
259
|
+
parseBoolean(undefined); // false
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Объект и массив не означают логическую истину предметной области. Они лишь truthy по правилам JavaScript. Не передавайте произвольный JSON object, если ожидается строгий boolean scalar.
|
|
263
|
+
|
|
264
|
+
### Когда применять
|
|
265
|
+
|
|
266
|
+
`parseBoolean` полезен, если входной контракт осознанно допускает несколько представлений:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
type FeatureFlagInput = boolean | 0 | 1 | "0" | "1" | "true" | "false" | "X" | " ";
|
|
270
|
+
|
|
271
|
+
function readFeatureFlag(value: FeatureFlagInput): boolean {
|
|
272
|
+
return parseBoolean(value);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Но обратите внимание: строка `" "` даст `false` не потому, что специально распознана как ABAP false, а потому что её нет в списке true-строк.
|
|
277
|
+
|
|
278
|
+
## `toAbapBoolean`
|
|
279
|
+
|
|
280
|
+
### Сигнатура
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
function toAbapBoolean(value: unknown): AbapBoolean;
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Алгоритм имеет отдельное правило для строк:
|
|
287
|
+
|
|
288
|
+
1. если вход — строка, false означает только точная строка `"0"`;
|
|
289
|
+
2. любая другая строка превращается в true;
|
|
290
|
+
3. нестроковое значение проверяется стандартной truthy/falsy-семантикой;
|
|
291
|
+
4. true возвращается как `"X"`, false — как один пробел `" "`.
|
|
292
|
+
|
|
293
|
+
### Рекомендуемый вход
|
|
294
|
+
|
|
295
|
+
Передавайте настоящий boolean:
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
toAbapBoolean(true); // "X"
|
|
299
|
+
toAbapBoolean(false); // " "
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Это самый понятный и устойчивый сценарий.
|
|
303
|
+
|
|
304
|
+
### Строки: важная ловушка
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
toAbapBoolean("0"); // " "
|
|
308
|
+
|
|
309
|
+
toAbapBoolean("1"); // "X"
|
|
310
|
+
toAbapBoolean("false"); // "X"
|
|
311
|
+
toAbapBoolean(""); // "X"
|
|
312
|
+
toAbapBoolean(" "); // "X"
|
|
313
|
+
toAbapBoolean("00"); // "X"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Здесь `"false"` не парсится как false. Функция проверяет только неравенство строке `"0"`.
|
|
317
|
+
|
|
318
|
+
Если внешний input может содержать текстовые boolean-значения, сначала примените нужный parser:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
const normalized = parseBoolean(rawValue);
|
|
322
|
+
const abapValue = toAbapBoolean(normalized);
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Результаты:
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
toAbapBoolean(parseBoolean("false")); // " "
|
|
329
|
+
toAbapBoolean(parseBoolean("true")); // "X"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Нестроковые значения
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
toAbapBoolean(1); // "X"
|
|
336
|
+
toAbapBoolean(0); // " "
|
|
337
|
+
toAbapBoolean(null); // " "
|
|
338
|
+
toAbapBoolean(undefined); // " "
|
|
339
|
+
toAbapBoolean({}); // "X"
|
|
340
|
+
toAbapBoolean([]); // "X"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Для объектов и массивов используется только truthiness. Функция не читает поля объекта и не проверяет длину массива.
|
|
344
|
+
|
|
345
|
+
## Практические рецепты
|
|
346
|
+
|
|
347
|
+
### DTO → domain model
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
type UserDto = {
|
|
351
|
+
IS_ACTIVE: "X" | " ";
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
type User = {
|
|
355
|
+
isActive: boolean;
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
function mapUserDto(dto: UserDto): User {
|
|
359
|
+
return {
|
|
360
|
+
isActive: parseAbapBoolean(dto.IS_ACTIVE)
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Domain model → DTO
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
type UpdateUserPayload = {
|
|
369
|
+
IS_ACTIVE: AbapBoolean;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
function createUpdateUserPayload(isActive: boolean): UpdateUserPayload {
|
|
373
|
+
return {
|
|
374
|
+
IS_ACTIVE: toAbapBoolean(isActive)
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Строгая проверка неизвестного transport-значения
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
function readRequiredAbapBoolean(value: unknown): boolean {
|
|
383
|
+
if (value !== "X" && value !== " ") {
|
|
384
|
+
throw new TypeError("Некорректное ABAP boolean");
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return parseAbapBoolean(value);
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Form value `"0"`/`"1"` → ABAP
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
function formValueToAbapBoolean(value: "0" | "1"): AbapBoolean {
|
|
395
|
+
return toAbapBoolean(value);
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Это безопасно только потому, что TypeScript contract заранее ограничил две допустимые строки.
|
|
400
|
+
|
|
401
|
+
### Form value `"true"`/`"false"` → ABAP
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
function textBooleanToAbap(value: "true" | "false"): AbapBoolean {
|
|
405
|
+
return toAbapBoolean(parseBoolean(value));
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Прямой `toAbapBoolean("false")` дал бы `"X"`.
|
|
410
|
+
|
|
411
|
+
## Ошибки и ограничения
|
|
412
|
+
|
|
413
|
+
Функции обычно не бросают исключения: для любого обычного значения они возвращают boolean или `AbapBoolean`.
|
|
414
|
+
|
|
415
|
+
Но это означает silent coercion:
|
|
416
|
+
|
|
417
|
+
- ошибочная форма не отклоняется;
|
|
418
|
+
- неизвестное ABAP-значение превращается в false;
|
|
419
|
+
- объект превращается в true в широких функциях;
|
|
420
|
+
- внешние пробелы не нормализуются;
|
|
421
|
+
- `toAbapBoolean("false")` возвращает true marker.
|
|
422
|
+
|
|
423
|
+
Рекомендации:
|
|
424
|
+
|
|
425
|
+
- используйте `parseAbapBoolean` для точного ABAP read;
|
|
426
|
+
- передавайте boolean в `toAbapBoolean`;
|
|
427
|
+
- валидируйте `unknown`, если неверное значение должно считаться ошибкой;
|
|
428
|
+
- не стройте бизнес-правило на общей truthy/falsy-семантике;
|
|
429
|
+
- не логируйте ABAP false без кавычек: один пробел визуально незаметен.
|
|
430
|
+
|
|
431
|
+
## Тестирование
|
|
432
|
+
|
|
433
|
+
Минимальная матрица consumer-теста:
|
|
434
|
+
|
|
435
|
+
```ts
|
|
436
|
+
expect(parseAbapBoolean("X")).toBe(true);
|
|
437
|
+
expect(parseAbapBoolean("x")).toBe(false);
|
|
438
|
+
expect(parseAbapBoolean(" ")).toBe(false);
|
|
439
|
+
|
|
440
|
+
expect(parseBoolean("true")).toBe(true);
|
|
441
|
+
expect(parseBoolean("X")).toBe(true);
|
|
442
|
+
expect(parseBoolean("0")).toBe(false);
|
|
443
|
+
expect(parseBoolean(" true ")).toBe(false);
|
|
444
|
+
|
|
445
|
+
expect(toAbapBoolean(true)).toBe("X");
|
|
446
|
+
expect(toAbapBoolean(false)).toBe(" ");
|
|
447
|
+
expect(toAbapBoolean("0")).toBe(" ");
|
|
448
|
+
expect(toAbapBoolean("false")).toBe("X");
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Если ваш DTO объявляет поле обязательным, отдельно тестируйте runtime validation отсутствующего и неизвестного значения. Успешный `parseAbapBoolean(undefined) === false` не доказывает корректность DTO.
|
|
452
|
+
|
|
453
|
+
## Краткий справочник
|
|
454
|
+
|
|
455
|
+
| API | Вход | Результат | Главное правило |
|
|
456
|
+
| ------------------ | --------- | ------------- | ----------------------------------------------------- |
|
|
457
|
+
| `parseAbapBoolean` | `unknown` | `boolean` | true только для точного `"X"` |
|
|
458
|
+
| `parseBoolean` | `unknown` | `boolean` | строки true только `true`, `x`, `1`; иначе truthiness |
|
|
459
|
+
| `toAbapBoolean` | `unknown` | `AbapBoolean` | строка false только при точном `"0"` |
|
|
460
|
+
|
|
461
|
+
## Вопросы и ответы
|
|
462
|
+
|
|
463
|
+
### Почему `parseAbapBoolean("x")` вернул false?
|
|
464
|
+
|
|
465
|
+
ABAP parser регистрозависим и принимает только uppercase `"X"`.
|
|
466
|
+
|
|
467
|
+
### Почему `parseBoolean(" true ")` вернул false?
|
|
468
|
+
|
|
469
|
+
Функция приводит строку к lowercase, но не вызывает `trim()`. Нормализуйте transport input заранее только если это разрешено его контрактом.
|
|
470
|
+
|
|
471
|
+
### Почему `toAbapBoolean("false")` вернул `"X"`?
|
|
472
|
+
|
|
473
|
+
Для строк функция считает ложью только точное значение `"0"`. Передайте boolean либо сначала вызовите `parseBoolean`.
|
|
474
|
+
|
|
475
|
+
### Почему ABAP false выглядит как пустота?
|
|
476
|
+
|
|
477
|
+
Это один обычный пробел. Проверяйте через строгое равенство и показывайте в diagnostics с кавычками или через `JSON.stringify`.
|
|
478
|
+
|
|
479
|
+
### Можно ли сделать round trip?
|
|
480
|
+
|
|
481
|
+
Для настоящего `AbapBoolean` — да:
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
toAbapBoolean(parseAbapBoolean("X")); // "X"
|
|
485
|
+
toAbapBoolean(parseAbapBoolean(" ")); // " "
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
Для произвольной строки round trip не определён, потому что parsers и serializer используют разные правила.
|
|
489
|
+
|
|
490
|
+
## Связанная документация
|
|
491
|
+
|
|
492
|
+
- [Обзор всего модуля `formatters`](../README.mdx)
|
|
493
|
+
- [Строковая нормализация](../strings/README.mdx)
|
|
494
|
+
- [Formatter pipeline](../pipeline/README.mdx)
|