From 02d2efb1cdd56b39a1d51efd50383e13a4679fca Mon Sep 17 00:00:00 2001 From: Evan Battaglia Date: Thu, 5 Sep 2024 14:34:34 -0230 Subject: [PATCH] Tests from old tabry Some are not passing, put in 'TODO' directory for now --- .../arguments_and_possible_options__arg_.json | 52 +++++++ ...arguments_and_possible_options__arg_.tabry | 10 ++ .../multi_line_descriptions.json | 11 ++ .../multi_line_descriptions.tabry | 6 + .../argument_titles.json | 16 +++ .../argument_titles.tabry | 2 + .../flags__flag__flagarg__reqd_flagarg_.json | 71 ++++++++++ .../flags__flag__flagarg__reqd_flagarg_.tabry | 7 + .../getting_started.json | 31 +++++ .../getting_started.tabry | 13 ++ .../includes.json | 129 ++++++++++++++++++ .../includes.tabry | 25 ++++ ...rargs__opt_arg__varargs__opt_varargs_.json | 33 +++++ ...args__opt_arg__varargs__opt_varargs_.tabry | 3 + .../options.json | 53 +++++++ .../options.tabry | 8 ++ .../subcommands__sub__1.json | 46 +++++++ .../subcommands__sub__1.tabry | 7 + .../subcommands__sub__2.json | 36 +++++ .../subcommands__sub__2.tabry | 11 ++ src/lang/mod.rs | 22 +++ src/test_helpers.rs | 39 +++++- 22 files changed, 629 insertions(+), 2 deletions(-) create mode 100644 fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json create mode 100644 fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry create mode 100644 fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json create mode 100644 fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry create mode 100644 fixtures/examples_from_language_reference/argument_titles.json create mode 100644 fixtures/examples_from_language_reference/argument_titles.tabry create mode 100644 fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.json create mode 100644 fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.tabry create mode 100644 fixtures/examples_from_language_reference/getting_started.json create mode 100644 fixtures/examples_from_language_reference/getting_started.tabry create mode 100644 fixtures/examples_from_language_reference/includes.json create mode 100644 fixtures/examples_from_language_reference/includes.tabry create mode 100644 fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.json create mode 100644 fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.tabry create mode 100644 fixtures/examples_from_language_reference/options.json create mode 100644 fixtures/examples_from_language_reference/options.tabry create mode 100644 fixtures/examples_from_language_reference/subcommands__sub__1.json create mode 100644 fixtures/examples_from_language_reference/subcommands__sub__1.tabry create mode 100644 fixtures/examples_from_language_reference/subcommands__sub__2.json create mode 100644 fixtures/examples_from_language_reference/subcommands__sub__2.tabry diff --git a/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json b/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json new file mode 100644 index 0000000..3733dd5 --- /dev/null +++ b/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.json @@ -0,0 +1,52 @@ +{ + "cmd": null, + "main": { + "args": [ + { + "name": "vehicle_type1" + }, + { + "name": "vehicle_type3", + "description": "The type of vehicle" + }, + { + "name": "vehicle_type4", + "description": "The type of vehicle" + }, + { + "options": [ + { + "type": "const", + "value": "a" + } + ] + }, + { + "name": "bool1", + "options": [ + { + "type": "const", + "value": "T" + }, + { + "type": "const", + "value": "F" + } + ] + }, + { + "name": "bool2", + "options": [ + { + "type": "const", + "value": "T" + }, + { + "type": "const", + "value": "F" + } + ] + } + ] + } +} diff --git a/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry b/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry new file mode 100644 index 0000000..20c0924 --- /dev/null +++ b/fixtures/TODO_examples_from_language_reference/arguments_and_possible_options__arg_.tabry @@ -0,0 +1,10 @@ +arg vehicle_type1 +arg vehicle_type3 "The type of vehicle" +arg vehicle_type4 { + desc "The type of vehicle" +} +arg { opts const a } +arg (bool1 bool2) { + opts const T + opts const F +} diff --git a/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json b/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json new file mode 100644 index 0000000..2224b1d --- /dev/null +++ b/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.json @@ -0,0 +1,11 @@ +{ + "cmd": null, + "main": { + "subs": [ + { + "name": "mycmd", + "description": "My command:\n * It does stuff" + } + ] + } +} diff --git a/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry b/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry new file mode 100644 index 0000000..bb6b495 --- /dev/null +++ b/fixtures/TODO_examples_from_language_reference/multi_line_descriptions.tabry @@ -0,0 +1,6 @@ +sub mycmd { + desc " + My command: + * It does stuff + " +} diff --git a/fixtures/examples_from_language_reference/argument_titles.json b/fixtures/examples_from_language_reference/argument_titles.json new file mode 100644 index 0000000..c8434e7 --- /dev/null +++ b/fixtures/examples_from_language_reference/argument_titles.json @@ -0,0 +1,16 @@ +{ + "cmd": null, + "main": { + "args": [ + { + "name": "thing_to_search_for", + "title": "thing to search for" + }, + { + "name": "files_to_load", + "title": "file to load", + "varargs": true + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/argument_titles.tabry b/fixtures/examples_from_language_reference/argument_titles.tabry new file mode 100644 index 0000000..d4f253a --- /dev/null +++ b/fixtures/examples_from_language_reference/argument_titles.tabry @@ -0,0 +1,2 @@ +arg thing_to_search_for { title "thing to search for" } +varargs files_to_load { title "file to load" } diff --git a/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.json b/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.json new file mode 100644 index 0000000..1a7e1a9 --- /dev/null +++ b/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.json @@ -0,0 +1,71 @@ +{ + "cmd": null, + "main": { + "flags": [ + { + "name": "dry-run", + "aliases": [ + "d" + ] + }, + { + "name": "dry-run2", + "aliases": [ + "r" + ], + "description": "Don't act, only show what would be done" + }, + { + "name": "f", + "aliases": [ + "format" + ], + "arg": true, + "options": [ + { + "type": "const", + "value": "json" + }, + { + "type": "const", + "value": "yml" + } + ] + }, + { + "name": "env", + "aliases": [ + "e" + ], + "description": "The environment (this must be given)", + "arg": true, + "options": [ + { + "type": "const", + "value": "prod" + }, + { + "type": "const", + "value": "beta" + }, + { + "type": "const", + "value": "dev" + } + ] + }, + { + "name": "interactive", + "aliases": [ + "i" + ] + }, + { + "name": "force", + "aliases": [ + "f" + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.tabry b/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.tabry new file mode 100644 index 0000000..2cbbf7c --- /dev/null +++ b/fixtures/examples_from_language_reference/flags__flag__flagarg__reqd_flagarg_.tabry @@ -0,0 +1,7 @@ +flag dry-run,d +flag dry-run2,r "Don't act, only show what would be done" +flagarg f,format { opts const (json yml) } +flagarg env,e "The environment (this must be given)" { + opts const (prod beta dev) +} +flag (interactive,i force,f) diff --git a/fixtures/examples_from_language_reference/getting_started.json b/fixtures/examples_from_language_reference/getting_started.json new file mode 100644 index 0000000..56eb486 --- /dev/null +++ b/fixtures/examples_from_language_reference/getting_started.json @@ -0,0 +1,31 @@ +{ + "cmd": "control-vehicle", + "main": { + "args": [ + { + "options": [ + { + "type": "const", + "value": "car" + }, + { + "type": "const", + "value": "bike" + } + ] + }, + { + "options": [ + { + "type": "const", + "value": "go" + }, + { + "type": "const", + "value": "stop" + } + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/getting_started.tabry b/fixtures/examples_from_language_reference/getting_started.tabry new file mode 100644 index 0000000..3aca811 --- /dev/null +++ b/fixtures/examples_from_language_reference/getting_started.tabry @@ -0,0 +1,13 @@ +cmd control-vehicle + +# The vehicle argument +# Note: comments must be on a line of their own +arg { + opts const car + opts const bike +} + +arg { + opts const go + opts const stop +} diff --git a/fixtures/examples_from_language_reference/includes.json b/fixtures/examples_from_language_reference/includes.json new file mode 100644 index 0000000..ce34542 --- /dev/null +++ b/fixtures/examples_from_language_reference/includes.json @@ -0,0 +1,129 @@ +{ + "cmd": "mydeploy", + "main": { + "args": [ + { + "include": "project-and-environment" + } + ], + "flags": [ + { + "include": "project-and-environment" + } + ], + "subs": [ + { + "include": "project-and-environment" + }, + { + "name": "status", + "args": [ + { + "include": "project-and-environment" + }, + { + "include": "verbose" + } + ], + "flags": [ + { + "include": "project-and-environment" + }, + { + "include": "verbose" + } + ], + "subs": [ + { + "include": "project-and-environment" + }, + { + "include": "verbose" + } + ] + }, + { + "name": "list", + "args": [ + { + "include": "verbose" + } + ], + "flags": [ + { + "include": "verbose" + }, + { + "name": "env", + "options": [ + { + "type": "include", + "value": "environment" + } + ], + "arg": true + } + ], + "subs": [ + { + "include": "verbose" + } + ] + } + ] + }, + "option_includes": { + "environment": [ + { + "type": "const", + "value": "prod" + }, + { + "type": "const", + "value": "beta" + }, + { + "type": "const", + "value": "dev" + } + ] + }, + "arg_includes": { + "verbose": { + "flags": [ + { + "name": "verbose", + "description": "Show more info" + } + ] + }, + "project-and-environment": { + "args": [ + { + "name": "project", + "description": "The project", + "options": [ + { + "type": "const", + "value": "project1" + }, + { + "type": "const", + "value": "project2" + } + ] + }, + { + "name": "environment", + "options": [ + { + "type": "include", + "value": "environment" + } + ], + "description": "The environment" + } + ] + } + } +} diff --git a/fixtures/examples_from_language_reference/includes.tabry b/fixtures/examples_from_language_reference/includes.tabry new file mode 100644 index 0000000..3ba3c33 --- /dev/null +++ b/fixtures/examples_from_language_reference/includes.tabry @@ -0,0 +1,25 @@ +cmd mydeploy + +# Default command acts on project-and-environment +include @project-and-environment + +# status command acts and project-and-environment as well +sub status @project-and-environment @verbose + +# list command takes no position args, but takes an optional "env" flag +sub list @verbose { + flagarg env @environment +} + +defopts @environment { + opts const (prod beta dev) +} + +defargs @verbose { + flag verbose "Show more info" +} + +defargs @project-and-environment { + arg project "The project" { opts const (project1 project2) } + arg environment "The environment" @environment +} diff --git a/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.json b/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.json new file mode 100644 index 0000000..fb3afbe --- /dev/null +++ b/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.json @@ -0,0 +1,33 @@ +{ + "cmd": null, + "main": { + "args": [ + { + "name": "first-arg-mandatory" + }, + { + "name": "second-arg-optional", + "optional": true + }, + { + "name": "rest-args-optional", + "optional": true, + "varargs": true, + "options": [ + { + "type": "const", + "value": "foo" + }, + { + "type": "const", + "value": "bar" + }, + { + "type": "const", + "value": "waz" + } + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.tabry b/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.tabry new file mode 100644 index 0000000..3490d26 --- /dev/null +++ b/fixtures/examples_from_language_reference/optional_args_and_varargs__opt_arg__varargs__opt_varargs_.tabry @@ -0,0 +1,3 @@ +arg first-arg-mandatory +opt arg second-arg-optional +opt varargs rest-args-optional { opts const (foo bar waz) } diff --git a/fixtures/examples_from_language_reference/options.json b/fixtures/examples_from_language_reference/options.json new file mode 100644 index 0000000..951eac9 --- /dev/null +++ b/fixtures/examples_from_language_reference/options.json @@ -0,0 +1,53 @@ +{ + "cmd": null, + "main": { + "args": [ + { + "options": [ + { + "type": "const", + "value": "hello" + }, + { + "type": "const", + "value": "hello \"world\"" + }, + { + "type": "const", + "value": "T" + }, + { + "type": "const", + "value": "F" + }, + { + "type": "const", + "value": "true" + }, + { + "type": "const", + "value": "false" + }, + { + "type": "const", + "value": "yes" + }, + { + "type": "const", + "value": "no" + }, + { + "type": "shell", + "value": "mycmd list-things" + }, + { + "type": "file" + }, + { + "type": "dir" + } + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/options.tabry b/fixtures/examples_from_language_reference/options.tabry new file mode 100644 index 0000000..ed05afc --- /dev/null +++ b/fixtures/examples_from_language_reference/options.tabry @@ -0,0 +1,8 @@ +arg { + opts const hello + opts const "hello \"world\"" + opts const (T F true false yes no) + opts shell "mycmd list-things" + opts file + opts dir +} diff --git a/fixtures/examples_from_language_reference/subcommands__sub__1.json b/fixtures/examples_from_language_reference/subcommands__sub__1.json new file mode 100644 index 0000000..b4774dc --- /dev/null +++ b/fixtures/examples_from_language_reference/subcommands__sub__1.json @@ -0,0 +1,46 @@ +{ + "cmd": null, + "main": { + "subs": [ + { + "name": "list", + "description": "List the things" + }, + { + "name": "new", + "aliases": [ + "n" + ], + "description": "Create a thing" + }, + { + "name": "delete", + "aliases": [ + "d" + ], + "description": "Delete a thing", + "args": [ + { + "name": "thing", + "description": "The thing to delete", + "options": [ + { + "type": "shell", + "value": "mycmd list" + } + ] + } + ] + }, + { + "name": "do-something" + }, + { + "name": "do-something-else", + "aliases": [ + "dse" + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/subcommands__sub__1.tabry b/fixtures/examples_from_language_reference/subcommands__sub__1.tabry new file mode 100644 index 0000000..03f2fb7 --- /dev/null +++ b/fixtures/examples_from_language_reference/subcommands__sub__1.tabry @@ -0,0 +1,7 @@ +sub list "List the things" +sub new,n "Create a thing" +sub delete,d { + desc "Delete a thing" + arg thing "The thing to delete" { opts shell "mycmd list" } +} +sub (do-something do-something-else,dse) diff --git a/fixtures/examples_from_language_reference/subcommands__sub__2.json b/fixtures/examples_from_language_reference/subcommands__sub__2.json new file mode 100644 index 0000000..351530f --- /dev/null +++ b/fixtures/examples_from_language_reference/subcommands__sub__2.json @@ -0,0 +1,36 @@ +{ + "cmd": "foo", + "main": { + "args": [ + { + "name": "toplevel-arg" + } + ], + "flags": [ + { + "name": "dryrun" + } + ], + "subs": [ + { + "name": "mysub1", + "subs": [ + { + "name": "mysub2", + "flags": [ + { + "name": "someopt" + } + ], + "args": [ + { + "name": "mysub2-arg", + "optional": true + } + ] + } + ] + } + ] + } +} diff --git a/fixtures/examples_from_language_reference/subcommands__sub__2.tabry b/fixtures/examples_from_language_reference/subcommands__sub__2.tabry new file mode 100644 index 0000000..21f8293 --- /dev/null +++ b/fixtures/examples_from_language_reference/subcommands__sub__2.tabry @@ -0,0 +1,11 @@ +cmd foo +arg toplevel-arg + +flag dryrun + +sub mysub1 { + sub mysub2 { + flag someopt + opt arg mysub2-arg + } +} diff --git a/src/lang/mod.rs b/src/lang/mod.rs index 67af7de..22efb25 100644 --- a/src/lang/mod.rs +++ b/src/lang/mod.rs @@ -28,3 +28,25 @@ pub fn compile(tabry_file_str: &str) -> Result( + example.replace(".tabry", ".json").as_str(), + ); + eprintln!("checking example {example}"); + assert_json_eq!(res, expected); + } + } +} diff --git a/src/test_helpers.rs b/src/test_helpers.rs index 2a65471..f0031bf 100644 --- a/src/test_helpers.rs +++ b/src/test_helpers.rs @@ -1,7 +1,42 @@ use serde::Deserialize; +use std::borrow::Cow; use std::fs; +pub fn load_fixture_file_text(filename: &str) -> String { + let path: Cow = if filename.starts_with("fixtures/") { + Cow::Borrowed(filename) + } else { + Cow::Owned(format!("fixtures/{filename}")) + }; + fs::read_to_string(path.as_ref()) + .unwrap_or_else(|_| panic!("Failed to read fixtures/{filename}")) +} + +pub fn each_file_in_dir_with_extension<'a>( + dir: &'a str, + extension: &'a str, +) -> impl Iterator + 'a { + let dir_iter = fs::read_dir(dir).unwrap_or_else(|_| panic!("Failed to read dir {dir}")); + dir_iter + .filter(move |entry| { + let entry = entry + .as_ref() + .unwrap_or_else(|_| panic!("Error with DirEntry {entry:?}")); + match entry.path().extension() { + Some(ext) => { + let actual_ext = ext + .to_str() + .unwrap_or_else(|| panic!("Bad UTF-8 {entry:?}")); + actual_ext == extension + } + None => false, + } + }) + .map(|entry| entry.unwrap().path().to_str().unwrap().to_string()) +} + pub fn load_fixture_file Deserialize<'a>>(filename: &str) -> T { - let file_str = fs::read_to_string(format!("fixtures/{filename}")).unwrap(); - serde_json::from_str::(&file_str).unwrap() + let file_str = load_fixture_file_text(filename); + serde_json::from_str::(&file_str) + .unwrap_or_else(|_| panic!("Failed to parse fixtures/{filename}")) }