我正在编写一个简单的命令行gem。
执行实际工作的库是使用rspec开发的,到目前为止都有效。
我正在尝试使用Aruba / Cucumber测试命令行部分,但我遇到了一些奇怪的行为。
为了测试这个,我有一个二进制文件到puts ARGV
,我在tmp/aruba
当我运行bundle exec gem_name tmp/aruba/*.*
时,我会看到shell扩展文件名列表。
现在我的功能文件有:
Given files to work on # I set up files in tmp/aruba in this step
When I run `gem_name *.*` # standard step
Then the output should contain "Wibble"
最后一步显然会失败,但它向我展示了它所期望的与实际输出之间的差异。我得到的只是"*.*"
所以我离开了让应用程序实际按预期工作的位置,但我无法通过测试。我可以使用“。”并从那里生成文件列表,但是我正在编写额外的生产代码,只是为了让应用程序在测试中工作 - 我认为这不是正确的方法去做。所有这些都是因为没有发生shell扩展。
如果你看一下我的个人资料,你会发现Ruby不是我的主要包,随时可以指出我可能错过的任何资源,但这只是我遗漏了某些东西或预期的行为有人知道如何解决?
答案 0 :(得分:2)
在Aruba source进行了一些挖掘后,我发现When I run
步骤最终会出现在这样的代码块中:
def run!(&block)
@process = ChildProcess.build(*shellwords(@cmd))
...
begin
@process.start
...
进一步深入ChildProcess
结束here:
def launch_process
...
begin
exec(*@args)
...
这就是问题所在。当参数列表拆分为多个数组元素时,exec
不会进行shell扩展:
如果给exec一个参数,那么该参数是 作为一个在进行shell扩展之前的行 执行。如果给出了多个参数,则第二个和 后续参数作为参数传递给没有的命令 壳膨胀。
然而,我们找到了shellwords
,我们发现:
Shellwords.shellwords('gem_name *.*')
=> ["gem_name", "*.*"] # No good
Shellwords.shellwords('"gem_name *.*"')
=> ["gem_name *.*"] # Aha!
因此解决方案可能简单如下:
When I run `"gem_name *.*"`
如果这不起作用,那么你几乎没有运气。我建议你手动扩展文件名,因为你不是真的在这里测试shell扩展 - 我们知道它有效:你正在测试多个参数。
因此你应该这样做:
When I run `gem_name your_file1 your_file2 your_file3`