CoolFace
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 3d agoView on Hugging Face
0likes1.1kdownloads
test-json-schema-to-grammar.cpp1607 linesDownload Raw Back to tests
1#ifdef NDEBUG2#undef NDEBUG3#endif4 5#include "json-schema-to-grammar.h"6 7#include "../src/llama-grammar.h"8 9#include "json.h"10 11#include <cassert>12#include <regex>13 14static std::string trim(const std::string & source) {15    std::string s(source);16    s.erase(0,s.find_first_not_of(" \n\r\t"));17    s.erase(s.find_last_not_of(" \n\r\t")+1);18    return std::regex_replace(s, std::regex("(^|\n)[ \t]+"), "$1");19}20 21enum TestCaseStatus {22    SUCCESS,23    FAILURE24};25 26struct TestCase {27    TestCaseStatus expected_status;28    std::string name;29    std::string schema;30    std::string expected_grammar;31 32    void _print_failure_header() const {33        fprintf(stderr, "#\n# Test '%s' failed.\n#\n%s\n", name.c_str(), schema.c_str());34    }35    void verify(const std::string & actual_grammar) const {36        if (trim(actual_grammar) != trim(expected_grammar)) {37        _print_failure_header();38        fprintf(stderr, "# EXPECTED:\n%s\n# ACTUAL:\n%s\n", expected_grammar.c_str(), actual_grammar.c_str());39        assert(false);40        }41    }42    void verify_expectation_parseable() const {43        try {44            llama_grammar_parser state;45            state.parse(expected_grammar.c_str());46            if (state.symbol_ids.find("root") == state.symbol_ids.end()) {47                throw std::runtime_error("Grammar failed to parse:\n" + expected_grammar);48            }49        } catch (const std::runtime_error & ex) {50            _print_failure_header();51            fprintf(stderr, "# GRAMMAR ERROR: %s\n", ex.what());52            assert(false);53        }54    }55    void verify_status(TestCaseStatus status) const {56        if (status != expected_status) {57            _print_failure_header();58            fprintf(stderr, "# EXPECTED STATUS: %s\n", expected_status == SUCCESS ? "SUCCESS" : "FAILURE");59            fprintf(stderr, "# ACTUAL STATUS: %s\n", status == SUCCESS ? "SUCCESS" : "FAILURE");60            assert(false);61        }62    }63};64 65static void test_all(const std::string & title, std::function<void(const TestCase &)> runner) {66    fprintf(stderr, "#\n# %s\n#\n", title.c_str());67    auto test = [&](const TestCase & tc) {68        fprintf(stderr, "- %s%s\n", tc.name.c_str(), tc.expected_status == FAILURE ? " (failure expected)" : "");69        runner(tc);70    };71 72    test({73        SUCCESS,74        "min 0",75        R"""({76            "type": "integer",77            "minimum": 078        })""",79        R"""(80            root ::= ([0] | [1-9] [0-9]{0,15})81            space ::= | " " | "\n"{1,2} [ \t]{0,20}82        )"""83    });84 85    test({86        SUCCESS,87        "min 1",88        R"""({89            "type": "integer",90            "minimum": 191        })""",92        R"""(93            root ::= ([1-9] [0-9]{0,15})94            space ::= | " " | "\n"{1,2} [ \t]{0,20}95        )"""96    });97 98    test({99        SUCCESS,100        "min 3",101        R"""({102            "type": "integer",103            "minimum": 3104        })""",105        R"""(106            root ::= ([1-2] [0-9]{1,15} | [3-9] [0-9]{0,15})107            space ::= | " " | "\n"{1,2} [ \t]{0,20}108        )"""109    });110 111    test({112        SUCCESS,113        "min 9",114        R"""({115            "type": "integer",116            "minimum": 9117        })""",118        R"""(119            root ::= ([1-8] [0-9]{1,15} | [9] [0-9]{0,15})120            space ::= | " " | "\n"{1,2} [ \t]{0,20}121        )"""122    });123 124    test({125        SUCCESS,126        "min 10",127        R"""({128            "type": "integer",129            "minimum": 10130        })""",131        R"""(132            root ::= ([1] ([0-9]{1,15}) | [2-9] [0-9]{1,15})133            space ::= | " " | "\n"{1,2} [ \t]{0,20}134        )"""135    });136 137    test({138        SUCCESS,139        "min 25",140        R"""({141            "type": "integer",142            "minimum": 25143        })""",144        R"""(145            root ::= ([1] [0-9]{2,15} | [2] ([0-4] [0-9]{1,14} | [5-9] [0-9]{0,14}) | [3-9] [0-9]{1,15})146            space ::= | " " | "\n"{1,2} [ \t]{0,20}147        )"""148    });149 150    test({151        SUCCESS,152        "max 30",153        R"""({154            "type": "integer",155            "maximum": 30156        })""",157        R"""(158            root ::= ("-" [1-9] [0-9]{0,15} | [0-9] | ([1-2] [0-9] | [3] "0"))159            space ::= | " " | "\n"{1,2} [ \t]{0,20}160        )"""161    });162 163    test({164        SUCCESS,165        "min -5",166        R"""({167            "type": "integer",168            "minimum": -5169        })""",170        R"""(171            root ::= ("-" ([0-5]) | [0] | [1-9] [0-9]{0,15})172            space ::= | " " | "\n"{1,2} [ \t]{0,20}173        )"""174    });175 176    test({177        SUCCESS,178        "min -123",179        R"""({180            "type": "integer",181            "minimum": -123182        })""",183        R"""(184            root ::= ("-" ([0-9] | ([1-8] [0-9] | [9] [0-9]) | "1" ([0-1] [0-9] | [2] [0-3])) | [0] | [1-9] [0-9]{0,15})185            space ::= | " " | "\n"{1,2} [ \t]{0,20}186        )"""187    });188 189    test({190        SUCCESS,191        "max -5",192        R"""({193            "type": "integer",194            "maximum": -5195        })""",196        R"""(197            root ::= ("-" ([0-4] [0-9]{1,15} | [5-9] [0-9]{0,15}))198            space ::= | " " | "\n"{1,2} [ \t]{0,20}199        )"""200    });201 202    test({203        SUCCESS,204        "max 1",205        R"""({206            "type": "integer",207            "maximum": 1208        })""",209        R"""(210            root ::= ("-" [1-9] [0-9]{0,15} | [0-1])211            space ::= | " " | "\n"{1,2} [ \t]{0,20}212        )"""213    });214 215    test({216        SUCCESS,217        "max 100",218        R"""({219            "type": "integer",220            "maximum": 100221        })""",222        R"""(223            root ::= ("-" [1-9] [0-9]{0,15} | [0-9] | ([1-8] [0-9] | [9] [0-9]) | "100")224            space ::= | " " | "\n"{1,2} [ \t]{0,20}225        )"""226    });227 228    test({229        SUCCESS,230        "min 0 max 23",231        R"""({232            "type": "integer",233            "minimum": 0,234            "maximum": 23235        })""",236        R"""(237            root ::= ([0-9] | ([1] [0-9] | [2] [0-3]))238            space ::= | " " | "\n"{1,2} [ \t]{0,20}239        )"""240    });241 242    test({243        SUCCESS,244        "min 15 max 300",245        R"""({246            "type": "integer",247            "minimum": 15,248            "maximum": 300249        })""",250        R"""(251            root ::= (([1] ([5-9]) | [2-9] [0-9]) | ([1-2] [0-9]{2} | [3] "00"))252            space ::= | " " | "\n"{1,2} [ \t]{0,20}253        )"""254    });255 256    test({257        SUCCESS,258        "min 5 max 30",259        R"""({260            "type": "integer",261            "minimum": 5,262            "maximum": 30263        })""",264        R"""(265            root ::= ([5-9] | ([1-2] [0-9] | [3] "0"))266            space ::= | " " | "\n"{1,2} [ \t]{0,20}267        )"""268    });269 270    test({271        SUCCESS,272        "min -123 max 42",273        R"""({274            "type": "integer",275            "minimum": -123,276            "maximum": 42277        })""",278        R"""(279            root ::= ("-" ([0-9] | ([1-8] [0-9] | [9] [0-9]) | "1" ([0-1] [0-9] | [2] [0-3])) | [0-9] | ([1-3] [0-9] | [4] [0-2]))280            space ::= | " " | "\n"{1,2} [ \t]{0,20}281        )"""282    });283 284    test({285        SUCCESS,286        "min -10 max 10",287        R"""({288            "type": "integer",289            "minimum": -10,290            "maximum": 10291        })""",292        R"""(293            root ::= ("-" ([0-9] | "10") | [0-9] | "10")294            space ::= | " " | "\n"{1,2} [ \t]{0,20}295        )"""296    });297 298    test({299        FAILURE,300        "unknown type",301        R"""({302            "type": "kaboom"303        })""",304        ""305    });306 307    test({308        FAILURE,309        "invalid type",310        R"""({311            "type": 123312        })""",313        ""314    });315 316    test({317        SUCCESS,318        "empty schema (any value)",319        "{}",320        R"""(321            array ::= "[" space ( value ("," space value)* )? space "]"322            boolean ::= ("true" | "false")323            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})324            decimal-part ::= [0-9]{1,16}325            integral-part ::= [0] | [1-9] [0-9]{0,15}326            null ::= "null"327            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?328            object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? space "}"329            root ::= value330            space ::= | " " | "\n"{1,2} [ \t]{0,20}331            string ::= "\"" char* "\""332            value ::= object | array | string | number | boolean | null333        )"""334    });335 336    test({337        SUCCESS,338        "exotic formats",339        R"""({340            "items": [341                { "format": "date" },342                { "format": "uuid" },343                { "format": "time" },344                { "format": "date-time" }345            ]346        })""",347        R"""(348            date ::= [0-9]{4} "-" ( "0" [1-9] | "1" [0-2] ) "-" ( "0" [1-9] | [1-2] [0-9] | "3" [0-1] )349            date-string ::= "\"" date "\""350            date-time ::= date "T" time351            date-time-string ::= "\"" date-time "\""352            root ::= "[" space tuple-0 "," space uuid "," space tuple-2 "," space tuple-3 space "]"353            space ::= | " " | "\n"{1,2} [ \t]{0,20}354            time ::= ([01] [0-9] | "2" [0-3]) ":" [0-5] [0-9] ":" [0-5] [0-9] ( "." [0-9]{3} )? ( "Z" | ( "+" | "-" ) ( [01] [0-9] | "2" [0-3] ) ":" [0-5] [0-9] )355            time-string ::= "\"" time "\""356            tuple-0 ::= date-string357            tuple-2 ::= time-string358            tuple-3 ::= date-time-string359            uuid ::= "\"" [0-9a-fA-F]{8} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{4} "-" [0-9a-fA-F]{12} "\""360        )"""361    });362 363    test({364        SUCCESS,365        "string",366        R"""({367            "type": "string"368        })""",369        R"""(370            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})371            root ::= "\"" char* "\""372            space ::= | " " | "\n"{1,2} [ \t]{0,20}373        )"""374    });375 376    test({377        SUCCESS,378        "string w/ min length 1",379        R"""({380            "type": "string",381            "minLength": 1382        })""",383        R"""(384            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})385            root ::= "\"" char+ "\""386            space ::= | " " | "\n"{1,2} [ \t]{0,20}387        )"""388    });389 390    test({391        SUCCESS,392        "string w/ min length 3",393        R"""({394            "type": "string",395            "minLength": 3396        })""",397        R"""(398            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})399            root ::= "\"" char{3,} "\""400            space ::= | " " | "\n"{1,2} [ \t]{0,20}401        )"""402    });403 404    test({405        SUCCESS,406        "string w/ max length",407        R"""({408            "type": "string",409            "maxLength": 3410        })""",411        R"""(412            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})413            root ::= "\"" char{0,3} "\""414            space ::= | " " | "\n"{1,2} [ \t]{0,20}415        )"""416    });417 418    test({419        SUCCESS,420        "string w/ min & max length",421        R"""({422            "type": "string",423            "minLength": 1,424            "maxLength": 4425        })""",426        R"""(427            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})428            root ::= "\"" char{1,4} "\""429            space ::= | " " | "\n"{1,2} [ \t]{0,20}430        )"""431    });432 433    test({434        SUCCESS,435        "boolean",436        R"""({437            "type": "boolean"438        })""",439        R"""(440            root ::= ("true" | "false")441            space ::= | " " | "\n"{1,2} [ \t]{0,20}442        )"""443    });444 445    test({446        SUCCESS,447        "integer",448        R"""({449            "type": "integer"450        })""",451        R"""(452            integral-part ::= [0] | [1-9] [0-9]{0,15}453            root ::= ("-"? integral-part)454            space ::= | " " | "\n"{1,2} [ \t]{0,20}455        )"""456    });457 458    test({459        SUCCESS,460        "string const",461        R"""({462            "const": "foo"463        })""",464        R"""(465            root ::= "\"foo\""466            space ::= | " " | "\n"{1,2} [ \t]{0,20}467        )"""468    });469 470    test({471        SUCCESS,472        "non-string const",473        R"""({474            "const": 123475        })""",476        R"""(477            root ::= "123"478            space ::= | " " | "\n"{1,2} [ \t]{0,20}479        )"""480    });481 482    test({483        SUCCESS,484        "non-string enum",485        R"""({486            "enum": ["red", "amber", "green", null, 42, ["foo"]]487        })""",488        R"""(489            root ::= ("\"red\"" | "\"amber\"" | "\"green\"" | "null" | "42" | "[\"foo\"]")490            space ::= | " " | "\n"{1,2} [ \t]{0,20}491        )"""492    });493 494    test({495        SUCCESS,496        "string array",497        R"""({498            "type": "array",499            "prefixItems": { "type": "string" }500        })""",501        R"""(502            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})503            root ::= "[" space (string ("," space string)*)? space "]"504            space ::= | " " | "\n"{1,2} [ \t]{0,20}505            string ::= "\"" char* "\""506        )"""507    });508 509    test({510        SUCCESS,511        "nullable string array",512        R"""({513            "type": ["array", "null"],514            "prefixItems": { "type": "string" }515        })""",516        R"""(517            alternative-0 ::= "[" space (string ("," space string)*)? space "]"518            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})519            null ::= "null"520            root ::= alternative-0 | null521            space ::= | " " | "\n"{1,2} [ \t]{0,20}522            string ::= "\"" char* "\""523        )"""524    });525 526    test({527        SUCCESS,528        "tuple1",529        R"""({530            "prefixItems": [{ "type": "string" }]531        })""",532        R"""(533            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})534            root ::= "[" space string space "]"535            space ::= | " " | "\n"{1,2} [ \t]{0,20}536            string ::= "\"" char* "\""537        )"""538    });539 540    test({541        SUCCESS,542        "tuple2",543        R"""({544            "prefixItems": [{ "type": "string" }, { "type": "number" }]545        })""",546        R"""(547            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})548            decimal-part ::= [0-9]{1,16}549            integral-part ::= [0] | [1-9] [0-9]{0,15}550            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?551            root ::= "[" space string "," space number space "]"552            space ::= | " " | "\n"{1,2} [ \t]{0,20}553            string ::= "\"" char* "\""554        )"""555    });556 557    // items {} constrains nothing, the same as no items at all558    test({559        SUCCESS,560        "array with empty items",561        R"""({562            "type": "array",563            "items": {}564        })""",565        R"""(566            array ::= "[" space ( value ("," space value)* )? space "]"567            boolean ::= ("true" | "false")568            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})569            decimal-part ::= [0-9]{1,16}570            integral-part ::= [0] | [1-9] [0-9]{0,15}571            null ::= "null"572            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?573            object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? space "}"574            root ::= "[" space ( value ("," space value)* )? space "]"575            space ::= | " " | "\n"{1,2} [ \t]{0,20}576            string ::= "\"" char* "\""577            value ::= object | array | string | number | boolean | null578        )"""579    });580 581    test({582        SUCCESS,583        "array with empty items and prefixItems",584        R"""({585            "type": "array",586            "items": {},587            "prefixItems": { "type": "string" }588        })""",589        R"""(590            array ::= "[" space ( value ("," space value)* )? space "]"591            boolean ::= ("true" | "false")592            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})593            decimal-part ::= [0-9]{1,16}594            integral-part ::= [0] | [1-9] [0-9]{0,15}595            null ::= "null"596            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?597            object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? space "}"598            root ::= "[" space ( value ("," space value)* )? space "]"599            space ::= | " " | "\n"{1,2} [ \t]{0,20}600            string ::= "\"" char* "\""601            value ::= object | array | string | number | boolean | null602        )"""603    });604 605    test({606        SUCCESS,607        "number",608        R"""({609            "type": "number"610        })""",611        R"""(612            decimal-part ::= [0-9]{1,16}613            integral-part ::= [0] | [1-9] [0-9]{0,15}614            root ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?615            space ::= | " " | "\n"{1,2} [ \t]{0,20}616        )"""617    });618 619    test({620        SUCCESS,621        "minItems",622        R"""({623            "items": {624                "type": "boolean"625            },626            "minItems": 2627        })""",628        R"""(629            boolean ::= ("true" | "false")630            root ::= "[" space boolean ("," space boolean)+ space "]"631            space ::= | " " | "\n"{1,2} [ \t]{0,20}632        )"""633    });634 635    test({636        SUCCESS,637        "maxItems 0",638        R"""({639            "items": {640                "type": "boolean"641            },642            "maxItems": 0643        })""",644        R"""(645            boolean ::= ("true" | "false")646            root ::= "[" space  space "]"647            space ::= | " " | "\n"{1,2} [ \t]{0,20}648        )"""649    });650 651    test({652        SUCCESS,653        "maxItems 1",654        R"""({655            "items": {656                "type": "boolean"657            },658            "maxItems": 1659        })""",660        R"""(661            boolean ::= ("true" | "false")662            root ::= "[" space boolean? space "]"663            space ::= | " " | "\n"{1,2} [ \t]{0,20}664        )"""665    });666 667    test({668        SUCCESS,669        "maxItems 2",670        R"""({671            "items": {672                "type": "boolean"673            },674            "maxItems": 2675        })""",676        R"""(677            boolean ::= ("true" | "false")678            root ::= "[" space (boolean ("," space boolean)?)? space "]"679            space ::= | " " | "\n"{1,2} [ \t]{0,20}680        )"""681    });682 683    test({684        SUCCESS,685        "min + maxItems",686        R"""({687            "items": {688                "type": ["number", "integer"]689            },690            "minItems": 3,691            "maxItems": 5692        })""",693        R"""(694            decimal-part ::= [0-9]{1,16}695            integer ::= ("-"? integral-part)696            integral-part ::= [0] | [1-9] [0-9]{0,15}697            item ::= number | integer698            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?699            root ::= "[" space item ("," space item){2,4} space "]"700            space ::= | " " | "\n"{1,2} [ \t]{0,20}701        )"""702    });703 704    test({705        SUCCESS,706        "min + max items with min + max values across zero",707        R"""({708            "items": {709                "type": "integer",710                "minimum": -12,711                "maximum": 207712            },713            "minItems": 3,714            "maxItems": 5715        })""",716        R"""(717            item ::= ("-" ([0-9] | "1" [0-2]) | [0-9] | ([1-8] [0-9] | [9] [0-9]) | ([1] [0-9]{2} | [2] "0" [0-7]))718            root ::= "[" space item ("," space item){2,4} space "]"719            space ::= | " " | "\n"{1,2} [ \t]{0,20}720        )"""721    });722 723    test({724        SUCCESS,725        "min + max items with min + max values",726        R"""({727            "items": {728                "type": "integer",729                "minimum": 12,730                "maximum": 207731            },732            "minItems": 3,733            "maxItems": 5734        })""",735        R"""(736            item ::= (([1] ([2-9]) | [2-9] [0-9]) | ([1] [0-9]{2} | [2] "0" [0-7]))737            root ::= "[" space item ("," space item){2,4} space "]"738            space ::= | " " | "\n"{1,2} [ \t]{0,20}739        )"""740    });741 742    test({743        SUCCESS,744        "simple regexp",745        R"""({746            "type": "string",747            "pattern": "^abc?d*efg+(hij)?kl$"748        })""",749        R"""(750            root ::= "\"" ("ab" "c"? "d"* "ef" "g"+ ("hij")? "kl") "\""751            space ::= | " " | "\n"{1,2} [ \t]{0,20}752        )"""753    });754 755    test({756        SUCCESS,757        "regexp escapes",758        R"""({759            "type": "string",760            "pattern": "^\\[\\]\\{\\}\\(\\)\\|\\+\\*\\?$"761        })""",762        R"""(763            root ::= "\"" ("[]{}()|+*?") "\""764            space ::= | " " | "\n"{1,2} [ \t]{0,20}765        )"""766    });767 768    test({769        SUCCESS,770        "regexp quote",771        R"""({772            "type": "string",773            "pattern": "^\"$"774        })""",775        R"""(776            root ::= "\"" ("\"") "\""777            space ::= | " " | "\n"{1,2} [ \t]{0,20}778        )"""779    });780 781    test({782        SUCCESS,783        "regexp with top-level alternation",784        R"""({785            "type": "string",786            "pattern": "^A|B|C|D$"787        })""",788        R"""(789            root ::= "\"" ("A" | "B" | "C" | "D") "\""790            space ::= | " " | "\n"{1,2} [ \t]{0,20}791        )"""792    });793 794    test({795        SUCCESS,796        "regexp",797        R"""({798            "type": "string",799            "pattern": "^(\\([0-9]{1,3}\\))?[0-9]{3}-[0-9]{4} a{3,5}nd...$"800        })""",801        R"""(802            dot ::= [^\x0A\x0D]803            root ::= "\"" (("(" root-1{1,3} ")")? root-1{3,3} "-" root-1{4,4} " " "a"{3,5} "nd" dot dot dot) "\""804            root-1 ::= [0-9]805            space ::= | " " | "\n"{1,2} [ \t]{0,20}806        )"""807    });808 809    test({810        SUCCESS,811        "required props in original order",812        R"""({813            "type": "object",814            "properties": {815                "b": {"type": "string"},816                "c": {"type": "string"},817                "a": {"type": "string"}818            },819            "required": [820                "a",821                "b",822                "c"823            ],824            "additionalProperties": false,825            "definitions": {}826        })""",827        R"""(828            a-kv ::= "\"a\"" space ":" space string829            b-kv ::= "\"b\"" space ":" space string830            c-kv ::= "\"c\"" space ":" space string831            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})832            root ::= "{" space b-kv "," space c-kv "," space a-kv space "}"833            space ::= | " " | "\n"{1,2} [ \t]{0,20}834            string ::= "\"" char* "\""835        )"""836    });837 838    test({839        SUCCESS,840        "1 optional prop",841        R"""({842            "properties": {843                "a": {844                "type": "string"845                }846            },847            "additionalProperties": false848        })""",849        R"""(850            a-kv ::= "\"a\"" space ":" space string851            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})852            root ::= "{" space  (a-kv )? space "}"853            space ::= | " " | "\n"{1,2} [ \t]{0,20}854            string ::= "\"" char* "\""855        )"""856    });857 858    test({859        SUCCESS,860        "N optional props",861        R"""({862            "properties": {863                "a": {"type": "string"},864                "b": {"type": "string"},865                "c": {"type": "string"}866            },867            "additionalProperties": false868        })""",869        R"""(870            a-kv ::= "\"a\"" space ":" space string871            a-rest ::= ( "," space b-kv )? b-rest872            b-kv ::= "\"b\"" space ":" space string873            b-rest ::= ( "," space c-kv )?874            c-kv ::= "\"c\"" space ":" space string875            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})876            root ::= "{" space  (a-kv a-rest | b-kv b-rest | c-kv )? space "}"877            space ::= | " " | "\n"{1,2} [ \t]{0,20}878            string ::= "\"" char* "\""879        )"""880    });881 882    test({883        SUCCESS,884        "required + optional props each in original order",885        R"""({886            "properties": {887                "b": {"type": "string"},888                "a": {"type": "string"},889                "d": {"type": "string"},890                "c": {"type": "string"}891            },892            "required": ["a", "b"],893            "additionalProperties": false894        })""",895        R"""(896            a-kv ::= "\"a\"" space ":" space string897            b-kv ::= "\"b\"" space ":" space string898            c-kv ::= "\"c\"" space ":" space string899            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})900            d-kv ::= "\"d\"" space ":" space string901            d-rest ::= ( "," space c-kv )?902            root ::= "{" space b-kv "," space a-kv ( "," space ( d-kv d-rest | c-kv ) )? space "}"903            space ::= | " " | "\n"{1,2} [ \t]{0,20}904            string ::= "\"" char* "\""905        )"""906    });907 908    test({909        SUCCESS,910        "additional props",911        R"""({912            "type": "object",913            "additionalProperties": {"type": "array", "items": {"type": "number"}}914        })""",915        R"""(916            additional-kv ::= string ":" space additional-value917            additional-value ::= "[" space (number ("," space number)*)? space "]"918            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})919            decimal-part ::= [0-9]{1,16}920            integral-part ::= [0] | [1-9] [0-9]{0,15}921            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?922            root ::= "{" space  (additional-kv ( "," space additional-kv )* )? space "}"923            space ::= | " " | "\n"{1,2} [ \t]{0,20}924            string ::= "\"" char* "\""925        )"""926    });927 928    test({929        SUCCESS,930        "additional props (true)",931        R"""({932            "type": "object",933            "additionalProperties": true934        })""",935        R"""(936            array ::= "[" space ( value ("," space value)* )? space "]"937            boolean ::= ("true" | "false")938            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})939            decimal-part ::= [0-9]{1,16}940            integral-part ::= [0] | [1-9] [0-9]{0,15}941            null ::= "null"942            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?943            object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? space "}"944            root ::= object945            space ::= | " " | "\n"{1,2} [ \t]{0,20}946            string ::= "\"" char* "\""947            value ::= object | array | string | number | boolean | null948        )"""949    });950 951    test({952        SUCCESS,953        "additional props (implicit)",954        R"""({955            "type": "object"956        })""",957        R"""(958            array ::= "[" space ( value ("," space value)* )? space "]"959            boolean ::= ("true" | "false")960            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})961            decimal-part ::= [0-9]{1,16}962            integral-part ::= [0] | [1-9] [0-9]{0,15}963            null ::= "null"964            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?965            object ::= "{" space ( string ":" space value ("," space string ":" space value)* )? space "}"966            root ::= object967            space ::= | " " | "\n"{1,2} [ \t]{0,20}968            string ::= "\"" char* "\""969            value ::= object | array | string | number | boolean | null970        )"""971    });972 973    test({974        SUCCESS,975        "empty w/o additional props",976        R"""({977            "type": "object",978            "additionalProperties": false979        })""",980        R"""(981            root ::= "{" space "}"982            space ::= | " " | "\n"{1,2} [ \t]{0,20}983        )"""984    });985 986    test({987        SUCCESS,988        "required + additional props",989        R"""({990            "type": "object",991            "properties": {992                "a": {"type": "number"}993            },994            "required": ["a"],995            "additionalProperties": {"type": "string"}996        })""",997        R"""(998            a-kv ::= "\"a\"" space ":" space number999            additional-k ::= ["] ( [a] char+ | [^"a] char* )? ["]1000            additional-kv ::= additional-k ":" space string1001            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1002            decimal-part ::= [0-9]{1,16}1003            integral-part ::= [0] | [1-9] [0-9]{0,15}1004            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?1005            root ::= "{" space a-kv ( "," space ( additional-kv ( "," space additional-kv )* ) )? space "}"1006            space ::= | " " | "\n"{1,2} [ \t]{0,20}1007            string ::= "\"" char* "\""1008        )"""1009    });1010 1011    test({1012        SUCCESS,1013        "optional + additional props",1014        R"""({1015            "type": "object",1016            "properties": {1017                "a": {"type": "number"}1018            },1019            "additionalProperties": {"type": "number"}1020        })""",1021        R"""(1022            a-kv ::= "\"a\"" space ":" space number1023            a-rest ::= ( "," space additional-kv )*1024            additional-k ::= ["] ( [a] char+ | [^"a] char* )? ["]1025            additional-kv ::= additional-k ":" space number1026            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1027            decimal-part ::= [0-9]{1,16}1028            integral-part ::= [0] | [1-9] [0-9]{0,15}1029            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?1030            root ::= "{" space  (a-kv a-rest | additional-kv ( "," space additional-kv )* )? space "}"1031            space ::= | " " | "\n"{1,2} [ \t]{0,20}1032        )"""1033    });1034 1035    test({1036        SUCCESS,1037        "required + optional + additional props",1038        R"""({1039            "type": "object",1040            "properties": {1041                "and": {"type": "number"},1042                "also": {"type": "number"}1043            },1044            "required": ["and"],1045            "additionalProperties": {"type": "number"}1046        })""",1047        R"""(1048            additional-k ::= ["] ( [a] ([l] ([s] ([o] char+ | [^"o] char*) | [^"s] char*) | [n] ([d] char+ | [^"d] char*) | [^"ln] char*) | [^"a] char* )? ["]1049            additional-kv ::= additional-k ":" space number1050            also-kv ::= "\"also\"" space ":" space number1051            also-rest ::= ( "," space additional-kv )*1052            and-kv ::= "\"and\"" space ":" space number1053            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1054            decimal-part ::= [0-9]{1,16}1055            integral-part ::= [0] | [1-9] [0-9]{0,15}1056            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?1057            root ::= "{" space and-kv ( "," space ( also-kv also-rest | additional-kv ( "," space additional-kv )* ) )? space "}"1058            space ::= | " " | "\n"{1,2} [ \t]{0,20}1059        )"""1060    });1061 1062    test({1063        SUCCESS,1064        "optional props with empty name",1065        R"""({1066            "properties": {1067                "": {"type": "integer"},1068                "a": {"type": "integer"}1069            },1070            "additionalProperties": {"type": "integer"}1071        })""",1072        R"""(1073            -kv ::= "\"\"" space ":" space root1074            -rest ::= ( "," space a-kv )? a-rest1075            a-kv ::= "\"a\"" space ":" space integer1076            a-rest ::= ( "," space additional-kv )*1077            additional-k ::= ["] ( [a] char+ | [^"a] char* ) ["]1078            additional-kv ::= additional-k ":" space integer1079            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1080            integer ::= ("-"? integral-part)1081            integral-part ::= [0] | [1-9] [0-9]{0,15}1082            root ::= ("-"? integral-part)1083            root0 ::= "{" space  (-kv -rest | a-kv a-rest | additional-kv ( "," space additional-kv )* )? space "}"1084            space ::= | " " | "\n"{1,2} [ \t]{0,20}1085        )"""1086    });1087 1088    test({1089        SUCCESS,1090        "optional props with nested names",1091        R"""({1092            "properties": {1093                "a": {"type": "integer"},1094                "aa": {"type": "integer"}1095            },1096            "additionalProperties": {"type": "integer"}1097        })""",1098        R"""(1099            a-kv ::= "\"a\"" space ":" space integer1100            a-rest ::= ( "," space aa-kv )? aa-rest1101            aa-kv ::= "\"aa\"" space ":" space integer1102            aa-rest ::= ( "," space additional-kv )*1103            additional-k ::= ["] ( [a] ([a] char+ | [^"a] char*) | [^"a] char* )? ["]1104            additional-kv ::= additional-k ":" space integer1105            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1106            integer ::= ("-"? integral-part)1107            integral-part ::= [0] | [1-9] [0-9]{0,15}1108            root ::= "{" space  (a-kv a-rest | aa-kv aa-rest | additional-kv ( "," space additional-kv )* )? space "}"1109            space ::= | " " | "\n"{1,2} [ \t]{0,20}1110        )"""1111    });1112 1113    test({1114        SUCCESS,1115        "optional props with common prefix",1116        R"""({1117            "properties": {1118                "ab": {"type": "integer"},1119                "ac": {"type": "integer"}1120            },1121            "additionalProperties": {"type": "integer"}1122        })""",1123        R"""(1124            ab-kv ::= "\"ab\"" space ":" space integer1125            ab-rest ::= ( "," space ac-kv )? ac-rest1126            ac-kv ::= "\"ac\"" space ":" space integer1127            ac-rest ::= ( "," space additional-kv )*1128            additional-k ::= ["] ( [a] ([b] char+ | [c] char+ | [^"bc] char*) | [^"a] char* )? ["]1129            additional-kv ::= additional-k ":" space integer1130            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1131            integer ::= ("-"? integral-part)1132            integral-part ::= [0] | [1-9] [0-9]{0,15}1133            root ::= "{" space  (ab-kv ab-rest | ac-kv ac-rest | additional-kv ( "," space additional-kv )* )? space "}"1134            space ::= | " " | "\n"{1,2} [ \t]{0,20}1135        )"""1136    });1137 1138    test({1139        SUCCESS,1140        "top-level $ref",1141        R"""({1142            "$ref": "#/definitions/foo",1143            "definitions": {1144                "foo": {1145                    "type": "object",1146                    "properties": {1147                        "a": {1148                            "type": "string"1149                        }1150                    },1151                    "required": [1152                        "a"1153                    ],1154                    "additionalProperties": false1155                }1156            }1157        })""",1158        R"""(1159            char ::= [^"\\\x7F\x00-\x1F] | [\\] (["\\bfnrt] | "u" [0-9a-fA-F]{4})1160            ref-definitions-foo ::= "{" space ref-definitions-foo-a-kv space "}"1161            ref-definitions-foo-a-kv ::= "\"a\"" space ":" space string1162            root ::= ref-definitions-foo1163            space ::= | " " | "\n"{1,2} [ \t]{0,20}1164            string ::= "\"" char* "\""1165        )"""1166    });1167 1168    test({1169        SUCCESS,1170        "anyOf",1171        R"""({1172            "anyOf": [1173                {"$ref": "#/definitions/foo"},1174                {"$ref": "#/definitions/bar"}1175            ],1176            "definitions": {1177                "foo": {1178                    "properties": {"a": {"type": "number"}}1179                },1180                "bar": {1181                    "properties": {"b": {"type": "number"}}1182                }1183            },1184            "type": "object"1185        })""",1186        R"""(1187            alternative-0 ::= ref-definitions-foo1188            alternative-1 ::= ref-definitions-bar1189            decimal-part ::= [0-9]{1,16}1190            integral-part ::= [0] | [1-9] [0-9]{0,15}1191            number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)?1192            ref-definitions-bar ::= "{" space  (ref-definitions-bar-b-kv )? space "}"1193            ref-definitions-bar-b-kv ::= "\"b\"" space ":" space number1194            ref-definitions-foo ::= "{" space  (ref-definitions-foo-a-kv )? space "}"1195            ref-definitions-foo-a-kv ::= "\"a\"" space ":" space number1196            root ::= alternative-0 | alternative-11197            space ::= | " " | "\n"{1,2} [ \t]{0,20}1198        )"""1199    });1200 

Showing the first 1,200 of 1607 lines. Download the file for the rest.