@yuneta/gobj-ui 7.23.195 → 7.23.197
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 +42 -11
- package/dist/gobj-ui.cjs.js +336 -161
- package/dist/gobj-ui.es.js +336 -161
- package/package.json +1 -1
- package/src/c_yui_schema_editor.js +57 -122
- package/src/schema_to_c.js +49 -9
- package/src/schema_to_c.test.js +21 -3
- package/src/schema_to_diagram.js +301 -0
- package/src/schema_to_diagram.test.js +107 -0
- package/src/schema_validate.js +5 -17
- package/src/schema_validate.test.js +4 -24
- package/src/schema_version_bump.test.js +14 -71
package/package.json
CHANGED
|
@@ -19,13 +19,15 @@
|
|
|
19
19
|
* fkey, the order of a new sibling, the version that publishes
|
|
20
20
|
* the change.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
22
|
+
* AN EDIT IS A DRAFT. A write here moves no version and reaches no
|
|
23
|
+
* treedb: the host SAVES it (C_TREEDB's save-schema raises the
|
|
24
|
+
* topic_version of what changed and the schema_version, once) and
|
|
25
|
+
* APPLIES it (apply-schema + a restart of the owning yuno). Until
|
|
26
|
+
* the owner's design of M36 (2026-09-21 review) every write here
|
|
27
|
+
* raised both versions, so an edit half made was already the
|
|
28
|
+
* schema of the next start. The topic list marks what this session
|
|
29
|
+
* wrote and has not saved; the host's EV_REFRESH after a save is
|
|
30
|
+
* what forgets it.
|
|
29
31
|
*
|
|
30
32
|
* WHAT ELSE IS HERE, and why each is here and not somewhere else:
|
|
31
33
|
*
|
|
@@ -572,21 +574,23 @@ function start_measuring(gobj)
|
|
|
572
574
|
}
|
|
573
575
|
|
|
574
576
|
/***************************************************************
|
|
575
|
-
* "This topic was written
|
|
577
|
+
* "This topic was written in this session and is not saved."
|
|
576
578
|
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
579
|
+
* An edit is a DRAFT: it moves no version and reaches no treedb
|
|
580
|
+
* until the host saves it (C_TREEDB's save-schema, which raises the
|
|
581
|
+
* versions of what changed) -- and the save makes the host send
|
|
582
|
+
* EV_REFRESH, whose reload is what forgets the drafts.
|
|
583
|
+
*
|
|
584
|
+
* ONE predicate, because it is asked in three places -- the topic
|
|
585
|
+
* list draws a chip with it, the column view a banner, the export
|
|
586
|
+
* a warning -- and copies of a rule are how they drift.
|
|
580
587
|
***************************************************************/
|
|
581
|
-
function
|
|
588
|
+
function topic_is_draft(written, topic)
|
|
582
589
|
{
|
|
583
|
-
if(!topic || !written
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
if(!written[topic.id]) {
|
|
590
|
+
if(!topic || !written) {
|
|
587
591
|
return false;
|
|
588
592
|
}
|
|
589
|
-
return
|
|
593
|
+
return written[topic.id]? true: false;
|
|
590
594
|
}
|
|
591
595
|
|
|
592
596
|
/***************************************************************
|
|
@@ -1041,7 +1045,7 @@ function render_topics(gobj, $body)
|
|
|
1041
1045
|
let twice = repeated_names(treedb.topics);
|
|
1042
1046
|
let $rows = [];
|
|
1043
1047
|
for(let topic of treedb.topics) {
|
|
1044
|
-
let pending =
|
|
1048
|
+
let pending = topic_is_draft(priv.written, topic);
|
|
1045
1049
|
/* Two topics of one name: the id is what tells them apart, and
|
|
1046
1050
|
* it is what the url has to carry — addressing by name would
|
|
1047
1051
|
* open the first one whichever row was clicked. */
|
|
@@ -1192,7 +1196,7 @@ function render_columns(gobj, $body)
|
|
|
1192
1196
|
* The version banner: the one thing that makes
|
|
1193
1197
|
* an edit succeed and change nothing.
|
|
1194
1198
|
*----------------------------------------------*/
|
|
1195
|
-
let $banner =
|
|
1199
|
+
let $banner = draft_banner(gobj, topic);
|
|
1196
1200
|
if($banner) {
|
|
1197
1201
|
$wrap.appendChild($banner);
|
|
1198
1202
|
}
|
|
@@ -1235,48 +1239,34 @@ function render_columns(gobj, $body)
|
|
|
1235
1239
|
}
|
|
1236
1240
|
|
|
1237
1241
|
/***************************************************************
|
|
1238
|
-
* "This topic
|
|
1242
|
+
* "This topic has changes that are not saved."
|
|
1239
1243
|
*
|
|
1240
|
-
*
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
*
|
|
1244
|
+
* A draft, not an error: the edit is in __system__ and moves no
|
|
1245
|
+
* version, so the treedb does not see it until the host saves it
|
|
1246
|
+
* (and applies it). The banner says so and offers nothing -- the
|
|
1247
|
+
* save is the host's, one level up, because it publishes the whole
|
|
1248
|
+
* treedb and not one topic.
|
|
1245
1249
|
***************************************************************/
|
|
1246
|
-
function
|
|
1250
|
+
function draft_banner(gobj, topic)
|
|
1247
1251
|
{
|
|
1248
1252
|
let priv = gobj.priv;
|
|
1249
1253
|
|
|
1250
|
-
if(!
|
|
1254
|
+
if(!topic_is_draft(priv.written, topic)) {
|
|
1251
1255
|
return null;
|
|
1252
1256
|
}
|
|
1253
1257
|
if(is_readonly(gobj)) {
|
|
1254
1258
|
return null;
|
|
1255
1259
|
}
|
|
1256
1260
|
|
|
1257
|
-
|
|
1258
|
-
["div", {class: "
|
|
1261
|
+
return createElement2(
|
|
1262
|
+
["div", {class: "SCHEMA_DRAFT_BANNER notification is-warning is-light p-3 mb-3 " +
|
|
1259
1263
|
"is-flex is-align-items-center", style: "gap:.5rem;"}, [
|
|
1260
1264
|
["span", {class: "icon"}, [["i", {class: "yi-triangle-exclamation"}]]],
|
|
1261
|
-
["span", {class: "
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
type: "button",
|
|
1265
|
-
style: "margin-left:auto;",
|
|
1266
|
-
title: t("raise the version"), "aria-label": t("raise the version"),
|
|
1267
|
-
"data-i18n-title": "raise the version",
|
|
1268
|
-
"data-i18n-aria-label": "raise the version"}, [
|
|
1269
|
-
["span", {class: "icon"}, [["i", {class: "yi-circle-up"}]]],
|
|
1270
|
-
["span", {i18n: "raise"}, t("raise")]
|
|
1271
|
-
]]
|
|
1265
|
+
["span", {class: "SCHEMA_DRAFT_TEXT is-size-7",
|
|
1266
|
+
i18n: "unsaved schema changes: save to publish them"},
|
|
1267
|
+
t("unsaved schema changes: save to publish them")]
|
|
1272
1268
|
]]
|
|
1273
1269
|
);
|
|
1274
|
-
let $bump = $banner.querySelector(".SCHEMA_VERSION_BUMP");
|
|
1275
|
-
$bump.addEventListener("click", (evt) => {
|
|
1276
|
-
evt.stopPropagation();
|
|
1277
|
-
gobj_send_event(gobj, "EV_BUMP_VERSION", {topic: topic.name}, gobj);
|
|
1278
|
-
});
|
|
1279
|
-
return $banner;
|
|
1280
1270
|
}
|
|
1281
1271
|
|
|
1282
1272
|
/***************************************************************
|
|
@@ -2001,6 +1991,8 @@ function open_report(gobj, findings, treedb_id)
|
|
|
2001
1991
|
***************************************************************/
|
|
2002
1992
|
function open_export(gobj, treedb)
|
|
2003
1993
|
{
|
|
1994
|
+
let priv = gobj.priv;
|
|
1995
|
+
let drafts = treedb.topics.some((topic) => topic_is_draft(priv.written, topic));
|
|
2004
1996
|
let c_text = schema_to_c(treedb);
|
|
2005
1997
|
let json_text = JSON.stringify(schema_to_json(treedb), null, 4);
|
|
2006
1998
|
|
|
@@ -2017,11 +2009,20 @@ function open_export(gobj, treedb)
|
|
|
2017
2009
|
["p", {class: "SCHEMA_EXPORT_HELP help mb-2",
|
|
2018
2010
|
i18n: "an edit made here works and lives in no source: this is what to paste back"},
|
|
2019
2011
|
t("an edit made here works and lives in no source: this is what to paste back")],
|
|
2012
|
+
drafts
|
|
2013
|
+
? ["p", {class: "SCHEMA_EXPORT_DRAFTS notification is-warning is-light p-2 mb-2 is-size-7",
|
|
2014
|
+
i18n: "unsaved changes: save first, so the literal carries the versions that publish it"},
|
|
2015
|
+
t("unsaved changes: save first, so the literal carries the versions that publish it")]
|
|
2016
|
+
: ["span", {}, ""],
|
|
2020
2017
|
["textarea", {class: "SCHEMA_EXPORT_TEXT textarea is-small is-family-monospace",
|
|
2021
|
-
rows: "18", readonly: "readonly", spellcheck: "false"
|
|
2018
|
+
rows: "18", readonly: "readonly", spellcheck: "false",
|
|
2019
|
+
title: t("schema"), "data-i18n-title": "schema",
|
|
2020
|
+
"aria-label": t("schema"), "data-i18n-aria-label": "schema"}, c_text],
|
|
2022
2021
|
["div", {class: "SCHEMA_EXPORT_ACTIONS is-flex mt-3",
|
|
2023
2022
|
style: "gap:.5rem; justify-content:flex-end;"}, [
|
|
2024
|
-
["button", {class: "SCHEMA_EXPORT_COPY button", type: "button"
|
|
2023
|
+
["button", {class: "SCHEMA_EXPORT_COPY button", type: "button",
|
|
2024
|
+
title: t("copy"), "data-i18n-title": "copy",
|
|
2025
|
+
"aria-label": t("copy"), "data-i18n-aria-label": "copy"}, [
|
|
2025
2026
|
["span", {class: "icon"}, [["i", {class: "yi-copy"}]]],
|
|
2026
2027
|
["span", {i18n: "copy"}, t("copy")]
|
|
2027
2028
|
]]
|
|
@@ -2240,51 +2241,6 @@ function open_orphans(gobj)
|
|
|
2240
2241
|
|
|
2241
2242
|
|
|
2242
2243
|
|
|
2243
|
-
/***************************************************************
|
|
2244
|
-
* THE TWO VERSIONS A SCHEMA EDIT HAS TO RAISE, and why both.
|
|
2245
|
-
*
|
|
2246
|
-
* `topic_version` is what publishes a change of a topic's
|
|
2247
|
-
* columns: leave it and the persisted `topic_cols.json` masks
|
|
2248
|
-
* the edit, the restart succeeds and nothing moved.
|
|
2249
|
-
*
|
|
2250
|
-
* `schema_version` is what publishes the schema as a whole —
|
|
2251
|
-
* "the stored one wins on ties, and the incoming one has to be
|
|
2252
|
-
* strictly newer to take over" (c_treedb.c). It is safe to
|
|
2253
|
-
* raise: re-projection from C compares `c_schema_version`, the
|
|
2254
|
-
* version of the LITERAL, precisely so that an edit made here
|
|
2255
|
-
* survives every start until a newer literal arrives.
|
|
2256
|
-
*
|
|
2257
|
-
* So every write that changes a schema carries both, and the
|
|
2258
|
-
* operator is never asked to remember either.
|
|
2259
|
-
***************************************************************/
|
|
2260
|
-
function version_writes(gobj, topic)
|
|
2261
|
-
{
|
|
2262
|
-
let treedb = current_treedb(gobj);
|
|
2263
|
-
let writes = [];
|
|
2264
|
-
|
|
2265
|
-
if(topic) {
|
|
2266
|
-
let version = Number(topic.topic_version);
|
|
2267
|
-
if(!isFinite(version)) {
|
|
2268
|
-
version = 0;
|
|
2269
|
-
}
|
|
2270
|
-
writes.push({
|
|
2271
|
-
op: "update", topic_name: T_TOPICS,
|
|
2272
|
-
record: {id: topic.id, topic_version: version + 1}
|
|
2273
|
-
});
|
|
2274
|
-
}
|
|
2275
|
-
if(treedb) {
|
|
2276
|
-
let version = Number(treedb.schema_version);
|
|
2277
|
-
if(!isFinite(version)) {
|
|
2278
|
-
version = 0;
|
|
2279
|
-
}
|
|
2280
|
-
writes.push({
|
|
2281
|
-
op: "update", topic_name: T_TREEDBS,
|
|
2282
|
-
record: {id: treedb.id, schema_version: version + 1}
|
|
2283
|
-
});
|
|
2284
|
-
}
|
|
2285
|
-
return writes;
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
2244
|
/***************************************************************
|
|
2289
2245
|
* WHERE THE COLUMNS WERE before this session started moving them.
|
|
2290
2246
|
*
|
|
@@ -2968,7 +2924,7 @@ function ac_save_column(gobj, event, kw, src)
|
|
|
2968
2924
|
op: kw.creating ? "create" : "update",
|
|
2969
2925
|
topic_name: T_COLS,
|
|
2970
2926
|
record: column_record(gobj, topic, col, values)
|
|
2971
|
-
}]
|
|
2927
|
+
}]);
|
|
2972
2928
|
}
|
|
2973
2929
|
|
|
2974
2930
|
function ac_delete_column(gobj, event, kw, src)
|
|
@@ -3026,7 +2982,7 @@ function ac_move_column(gobj, event, kw, src)
|
|
|
3026
2982
|
if(writes.length === 0) {
|
|
3027
2983
|
return 0; /* dropped where it already was */
|
|
3028
2984
|
}
|
|
3029
|
-
return queue_writes(gobj, writes
|
|
2985
|
+
return queue_writes(gobj, writes);
|
|
3030
2986
|
}
|
|
3031
2987
|
|
|
3032
2988
|
/***************************************************************
|
|
@@ -3055,7 +3011,7 @@ function ac_undo_order(gobj, event, kw, src)
|
|
|
3055
3011
|
}
|
|
3056
3012
|
/* Spent: what it named is where the columns are about to be. */
|
|
3057
3013
|
delete priv.order_undo[topic.id];
|
|
3058
|
-
return queue_writes(gobj, writes
|
|
3014
|
+
return queue_writes(gobj, writes);
|
|
3059
3015
|
}
|
|
3060
3016
|
|
|
3061
3017
|
/***************************************************************
|
|
@@ -3127,7 +3083,7 @@ function ac_save_topic(gobj, event, kw, src)
|
|
|
3127
3083
|
op: kw.creating ? "create" : "update",
|
|
3128
3084
|
topic_name: T_TOPICS,
|
|
3129
3085
|
record: topic_record(gobj, treedb, topic, values)
|
|
3130
|
-
}]
|
|
3086
|
+
}]);
|
|
3131
3087
|
}
|
|
3132
3088
|
|
|
3133
3089
|
function ac_delete_topic(gobj, event, kw, src)
|
|
@@ -3148,25 +3104,6 @@ function ac_delete_topic(gobj, event, kw, src)
|
|
|
3148
3104
|
return 0;
|
|
3149
3105
|
}
|
|
3150
3106
|
|
|
3151
|
-
/***************************************************************
|
|
3152
|
-
* Raising a version by hand: what the banner offers when
|
|
3153
|
-
* something else wrote the topic and left its version alone.
|
|
3154
|
-
***************************************************************/
|
|
3155
|
-
function ac_bump_version(gobj, event, kw, src)
|
|
3156
|
-
{
|
|
3157
|
-
let priv = gobj.priv;
|
|
3158
|
-
let topic = find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
3159
|
-
|
|
3160
|
-
if(refuse_if_readonly(gobj, event)) {
|
|
3161
|
-
return -1;
|
|
3162
|
-
}
|
|
3163
|
-
if(!topic) {
|
|
3164
|
-
log_error(`${gobj_short_name(gobj)}: ${event} names no topic: ${kw.topic}`);
|
|
3165
|
-
return -1;
|
|
3166
|
-
}
|
|
3167
|
-
return queue_writes(gobj, version_writes(gobj, topic));
|
|
3168
|
-
}
|
|
3169
|
-
|
|
3170
3107
|
/***************************************************************
|
|
3171
3108
|
* Deleting a leftover.
|
|
3172
3109
|
***************************************************************/
|
|
@@ -3339,7 +3276,7 @@ function ac_confirmed(gobj, event, kw, src)
|
|
|
3339
3276
|
return {op: "delete", topic_name: T_COLS, record: {id: col.id}};
|
|
3340
3277
|
});
|
|
3341
3278
|
writes.push({op: "delete", topic_name: T_TOPICS, record: {id: topic.id}});
|
|
3342
|
-
return queue_writes(gobj, writes
|
|
3279
|
+
return queue_writes(gobj, writes);
|
|
3343
3280
|
}
|
|
3344
3281
|
if(kw.what === "column") {
|
|
3345
3282
|
let topic = find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
@@ -3350,7 +3287,7 @@ function ac_confirmed(gobj, event, kw, src)
|
|
|
3350
3287
|
}
|
|
3351
3288
|
return queue_writes(gobj, [{
|
|
3352
3289
|
op: "delete", topic_name: T_COLS, record: {id: col.id}
|
|
3353
|
-
}]
|
|
3290
|
+
}]);
|
|
3354
3291
|
}
|
|
3355
3292
|
|
|
3356
3293
|
log_error(`${gobj_short_name(gobj)}: ${event} of nothing this view asked about: ${kw.what}`);
|
|
@@ -3450,8 +3387,7 @@ function create_gclass(gclass_name)
|
|
|
3450
3387
|
["EV_DELETE_COLUMN", ac_delete_column, null],
|
|
3451
3388
|
["EV_SAVE_COLUMN", ac_save_column, null],
|
|
3452
3389
|
["EV_MOVE_COLUMN", ac_move_column, null],
|
|
3453
|
-
["EV_UNDO_ORDER", ac_undo_order, null]
|
|
3454
|
-
["EV_BUMP_VERSION", ac_bump_version, null]
|
|
3390
|
+
["EV_UNDO_ORDER", ac_undo_order, null]
|
|
3455
3391
|
])],
|
|
3456
3392
|
|
|
3457
3393
|
/* A write, or a plan of them, in flight. Only the answers and
|
|
@@ -3494,7 +3430,6 @@ function create_gclass(gclass_name)
|
|
|
3494
3430
|
["EV_SAVE_COLUMN", 0],
|
|
3495
3431
|
["EV_MOVE_COLUMN", 0],
|
|
3496
3432
|
["EV_UNDO_ORDER", 0],
|
|
3497
|
-
["EV_BUMP_VERSION", 0],
|
|
3498
3433
|
["EV_VALIDATE", 0],
|
|
3499
3434
|
["EV_EXPORT", 0],
|
|
3500
3435
|
["EV_IMPORT", 0],
|
|
@@ -3549,5 +3484,5 @@ export {
|
|
|
3549
3484
|
register_c_yui_schema_editor,
|
|
3550
3485
|
/* Exported for its test: the rule that decides whether a topic still
|
|
3551
3486
|
* owes a version bump, which is asked in two places. */
|
|
3552
|
-
|
|
3487
|
+
topic_is_draft
|
|
3553
3488
|
};
|
package/src/schema_to_c.js
CHANGED
|
@@ -19,13 +19,19 @@
|
|
|
19
19
|
* Two outputs, because they answer different questions:
|
|
20
20
|
* schema_to_json() — the schema as a value: to diff, to keep, to
|
|
21
21
|
* feed back in.
|
|
22
|
-
* schema_to_c() — the same value as the
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* schema_to_c() — the same value as the WHOLE file
|
|
23
|
+
* `treedb_schema_<db>.c`: the graph of the
|
|
24
|
+
* schema as a comment (schema_to_diagram()),
|
|
25
|
+
* then the literal — single quotes, `\n\`
|
|
26
|
+
* continuations, padded. The file holds that
|
|
27
|
+
* and nothing else, so an export replaces it
|
|
28
|
+
* whole. json_to_c() does the same from the
|
|
29
|
+
* literal's own JSON.
|
|
25
30
|
*
|
|
26
31
|
* Copyright (c) 2026, ArtGins.
|
|
27
32
|
* All Rights Reserved.
|
|
28
33
|
***********************************************************************/
|
|
34
|
+
import { schema_to_diagram } from "./schema_to_diagram.js";
|
|
29
35
|
import {
|
|
30
36
|
col_flags,
|
|
31
37
|
col_hook,
|
|
@@ -326,15 +332,25 @@ function c_pair(lines, key, value, indent, trailing)
|
|
|
326
332
|
/***************************************************************
|
|
327
333
|
* schema_to_c(treedb, options) -> the C source text
|
|
328
334
|
*
|
|
329
|
-
* options {var_name, pad}
|
|
330
|
-
* var_name
|
|
331
|
-
*
|
|
332
|
-
* pad
|
|
335
|
+
* options {var_name, pad, with_diagram}
|
|
336
|
+
* var_name the array's name; defaults to
|
|
337
|
+
* `treedb_schema_<treedb id without its prefix>`
|
|
338
|
+
* pad column of the `\n\` continuation
|
|
339
|
+
* with_diagram the graph as a comment above the array
|
|
340
|
+
* (default true)
|
|
333
341
|
***************************************************************/
|
|
334
342
|
function schema_to_c(treedb, options)
|
|
343
|
+
{
|
|
344
|
+
return json_to_c(schema_to_json(treedb), options);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/***************************************************************
|
|
348
|
+
* json_to_c(json, options) -> the C source text, from the schema
|
|
349
|
+
* as its literal holds it. Same options as schema_to_c().
|
|
350
|
+
***************************************************************/
|
|
351
|
+
function json_to_c(json, options)
|
|
335
352
|
{
|
|
336
353
|
let opts = options || {};
|
|
337
|
-
let json = schema_to_json(treedb);
|
|
338
354
|
|
|
339
355
|
if(!json) {
|
|
340
356
|
return "";
|
|
@@ -368,7 +384,30 @@ function schema_to_c(treedb, options)
|
|
|
368
384
|
return `${line}${padding}\\n\\`;
|
|
369
385
|
});
|
|
370
386
|
|
|
371
|
-
|
|
387
|
+
let literal = `static char ${name}[]= "\\\n${body.join("\n")}\n";\n`;
|
|
388
|
+
if(opts.with_diagram === false) {
|
|
389
|
+
return literal;
|
|
390
|
+
}
|
|
391
|
+
return c_diagram_comment(schema_to_diagram(json)) + "\n" + literal;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/***************************************************************
|
|
395
|
+
* The diagram as the comment that heads the file.
|
|
396
|
+
***************************************************************/
|
|
397
|
+
function c_diagram_comment(diagram)
|
|
398
|
+
{
|
|
399
|
+
let lines = [
|
|
400
|
+
"/*",
|
|
401
|
+
" Generated from the literal below by schema_to_diagram() (gobj-ui).",
|
|
402
|
+
" This file holds this comment and the literal, nothing else: replace",
|
|
403
|
+
" it whole with an export of the schema editor.",
|
|
404
|
+
"",
|
|
405
|
+
];
|
|
406
|
+
for(let line of diagram.split("\n")) {
|
|
407
|
+
lines.push(line ? " " + line : "");
|
|
408
|
+
}
|
|
409
|
+
lines.push("*/");
|
|
410
|
+
return lines.join("\n") + "\n";
|
|
372
411
|
}
|
|
373
412
|
|
|
374
413
|
|
|
@@ -378,4 +417,5 @@ export {
|
|
|
378
417
|
COL_KEY_ORDER,
|
|
379
418
|
schema_to_json,
|
|
380
419
|
schema_to_c,
|
|
420
|
+
json_to_c,
|
|
381
421
|
};
|
package/src/schema_to_c.test.js
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
***********************************************************************/
|
|
13
13
|
import { describe, test, expect } from "vitest";
|
|
14
14
|
import { build_schema_model } from "./schema_model.js";
|
|
15
|
-
import { schema_to_json, schema_to_c } from "./schema_to_c.js";
|
|
15
|
+
import { schema_to_json, schema_to_c, json_to_c } from "./schema_to_c.js";
|
|
16
|
+
import { schema_to_diagram } from "./schema_to_diagram.js";
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
/***************************************************************
|
|
@@ -134,7 +135,24 @@ describe("schema_to_json", () => {
|
|
|
134
135
|
});
|
|
135
136
|
|
|
136
137
|
describe("schema_to_c — the round trip", () => {
|
|
137
|
-
const
|
|
138
|
+
const file = schema_to_c(TREEDB);
|
|
139
|
+
const source = file.slice(file.indexOf("static char"));
|
|
140
|
+
|
|
141
|
+
test("the file is the diagram as a comment, then the literal, nothing else", () => {
|
|
142
|
+
expect(file.startsWith("/*\n")).toBe(true);
|
|
143
|
+
const close = file.indexOf("\n*/\n");
|
|
144
|
+
expect(close).toBeGreaterThan(0);
|
|
145
|
+
expect(file.slice(close + 4)).toBe("\n" + source);
|
|
146
|
+
expect(file).toContain(schema_to_diagram(schema_to_json(TREEDB)).split("\n")[0]);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("without the diagram it is the literal alone", () => {
|
|
150
|
+
expect(schema_to_c(TREEDB, {with_diagram: false})).toBe(source);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("json_to_c() writes the same file from the literal's JSON", () => {
|
|
154
|
+
expect(json_to_c(schema_to_json(TREEDB))).toBe(file);
|
|
155
|
+
});
|
|
138
156
|
|
|
139
157
|
test("it is a C array declaration with the conventional name", () => {
|
|
140
158
|
expect(source.startsWith("static char treedb_schema_sample[]= \"\\\n")).toBe(true);
|
|
@@ -153,7 +171,7 @@ describe("schema_to_c — the round trip", () => {
|
|
|
153
171
|
});
|
|
154
172
|
|
|
155
173
|
test("the caller can name the array and set the continuation column", () => {
|
|
156
|
-
const custom = schema_to_c(TREEDB, {var_name: "my_schema", pad: 40});
|
|
174
|
+
const custom = schema_to_c(TREEDB, {var_name: "my_schema", pad: 40, with_diagram: false});
|
|
157
175
|
expect(custom.startsWith("static char my_schema[]=")).toBe(true);
|
|
158
176
|
expect(load_like_the_yuno(custom)).toEqual(schema_to_json(TREEDB));
|
|
159
177
|
});
|