0

私は単純なコマンドラインの宝石を書いています。

実際の作業を行うライブラリは rspec で開発されており、これまでのところ動作しています。

コマンド ライン部分を Aruba/Cucumber でテストしようとしていますが、奇妙な動作に遭遇しました。

これをテストするために、バイナリ ファイルを にputs ARGV、テスト ファイルをtmp/aruba

実行するbundle exec gem_name tmp/aruba/*.*と、シェル展開ファイル名のリストが表示されます。

今、私の機能ファイルは次のとおりです。

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"

最後のステップは明らかに失敗しますが、期待されるものと実際の出力との違いを示しています。シェル展開されたファイル名のリストを見るのではなく、私が得るのは"*.*"

そのため、実際に期待どおりに動作するアプリを作成する立場に置かれていますが、テストに合格することはできません。「 . 」を取り、そこからファイルのリストを生成することもできますが、アプリをテストで動作させるためだけに追加の本番コードを書いています。これは正しい方法ではないと思います。そして、シェルの拡張が行われていないためです。

私のプロフィールを見ると、Ruby は私のメイン バッグではないことがわかります。これについて見逃している可能性のあるリソースがあれば、遠慮なく指摘してください。どのように回避するのですか?

4

1 に答える 1

2

Arubaのソースを少し調べてみたところ、このWhen I runステップは次のようなコード ブロックで終わることがわかりました。

def run!(&block)
  @process = ChildProcess.build(*shellwords(@cmd))
  ...
  begin
    @process.start
    ...

さらに掘り下げると、次のようにChildProcessなります

def launch_process
  ...
  begin
    exec(*@args)
    ...

そしてそこに問題があります。exec引数リストが複数の配列要素に分割されている場合、シェル展開は行われません。

exec に単一の引数が与えられた場合、その引数は、実行される前にシェル展開の対象となる行と見なされます。複数の引数が指定された場合、2 番目以降の引数はシェル展開なしでコマンドにパラメーターとして渡されます。

ただし、少し遊んでみるとshellwords、次のことがわかります。

Shellwords.shellwords('gem_name *.*')
=> ["gem_name", "*.*"]                   # No good
Shellwords.shellwords('"gem_name *.*"')
=> ["gem_name *.*"]                      # Aha!

したがって、解決策次のように簡単です。

When I run `"gem_name *.*"`

それがうまくいかない場合は、かなり運が悪いです。ここではシェル展開を実際にテストしていないため、ファイル名を手動で展開することをお勧めします-動作することはわかっています:複数の引数をテストしています。

したがって、代わりに次のことを行う必要があります。

When I run `gem_name your_file1 your_file2 your_file3`
于 2012-12-29T05:06:39.523 に答える