-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File Structure and Testing #13
Comments
Thanks for the kind words! What I would do is create the following file structure:
With the following contents: src/example.cr require "./example/*"
module Example
end src/compile.cr require "./example"
Example::CLI.run(ARGV) src/example/version.cr module Example
VERSION = "0.1.0"
end src/example/cli.cr require "commander"
module Example::CLI
extend self
def config
Commander::Command.new do |cmd|
cmd.use = "my_program"
cmd.long = "my program's (long) description."
cmd.flags.add do |flag|
flag.name = "env"
flag.short = "-e"
flag.long = "--env"
flag.default = "development"
flag.description = "The environment to run in."
end
cmd.flags.add do |flag|
flag.name = "port"
flag.short = "-p"
flag.long = "--port"
flag.default = 8080
flag.description = "The port to bind to."
end
cmd.flags.add do |flag|
flag.name = "timeout"
flag.short = "-t"
flag.long = "--timeout"
flag.default = 29.5
flag.description = "The wait time before dropping the connection."
end
cmd.flags.add do |flag|
flag.name = "verbose"
flag.short = "-v"
flag.long = "--verbose"
flag.default = false
flag.description = "Enable more verbose logging."
end
cmd.run do |options, arguments|
options.string["env"] # => "development"
options.int["port"] # => 8080
options.float["timeout"] # => 29.5
options.bool["verbose"] # => false
arguments # => Array(String)
puts cmd.help # => Render help screen
end
cmd.commands.add do |cmd|
cmd.use = "kill <pid>"
cmd.short = "Kills server by pid."
cmd.long = cmd.short
cmd.run do |options, arguments|
arguments # => ["62719"]
end
end
end
end
def run(argv)
Commander.run(config, argv)
end
end Now when you run your specs with Avoid doing this: cmd.commands.add do |cmd|
cmd.use = "kill <pid>"
cmd.short = "Kills server by pid."
cmd.long = cmd.short
cmd.run do |options, arguments|
# a lot of lines of code and logic here
# related to killing the <pid> process.
end
end Instead, do something like this: cmd.commands.add do |cmd|
cmd.use = "kill <pid>"
cmd.short = "Kills server by pid."
cmd.long = cmd.short
cmd.run do |options, arguments|
# Only validate the CLI input here.
# You could also delegate this validation logic to a separate testable and reusable function.
# For simple cases like this it might not be necessary. It's up to you.
if pid = arguments.first?
# Delegate the actual work for killing a process to separate function,
# which makes testing the process-killing logic easier, without having to go through Commander.
Example::Process.kill(pid.to_i)
else
# Notify user of erroneous input.
puts "Missing <pid> argument."
end
end
end Then create a spec Then, to compile your program with the CLI built-in, I'd create a separate file like require "./example"
Example::CLI.run(ARGV) Then compile your program with:
If, in addition to just testing individual functions, you do wish to actually run the CLI programmatically for certain tests, you can call require "./spec_helper"
describe Example::Process do
it "kills a process" do
process = Process.fork do
sleep 1000
end
Example::CLI.run(["kill", process.pid.to_s])
Process.exists?(process.pid).should eq(false)
end
end Hope this helps! |
WOW! What a comprehensive answer 😮 Thank you very much, I'll try that soon :) |
Sure thing! Let me know if you have any further questions. |
I've tried that and it works like a charm, thank you very much! <3 |
First I want to thank you for your work at this project, it helps me a lot! Kudos!
Just one question: How to actually write specs for a CLI tool built with commander?
I have currently one sourcefile
src/some_tool.cr
which contains:My
spec_helper.cr
contains:Which immediately runs the commander logic.
I'm thankful for any advice :)
The text was updated successfully, but these errors were encountered: