2017-04-01 11 views
1

私は現在、Making your own gemのドキュメントの例に従ってレイアウトされている単純なRuby Gemを作成しています。Ruby Gemでrspecテストのパスが必要

私のディレクトリ構造:

. 
├── Gemfile 
├── Gemfile.lock 
├── lib 
│   ├── go_run 
│   │   ├── parser.rb 
│   │   └── runner.rb 
│   └── go_run.rb 
└── spec 
    ├── go_run_spec.rb 
    ├── parser_spec.rb 
    └── runner_spec.rb 

私はもともとただRunnerlib/go_run/runner.rbRunnerクラスと呼ばれるが、今、文書化の例のように私はGoRun::Runnerの下でそれを名前空間しています。コードは機能します。問題は現在、bundle exec rspec spec/parser_spec.rbを実行していないことです。それはで失敗します。

/home/smurf/dev/ruby/go_run/lib/go_run/parser.rb:3:in `<top (required)>': uninitialized constant GoRun (NameError) 

そのファイルの3行目は次のとおりです。

class GoRun::Parser 

私はrequirerequire 'go_run/parser'を使用してspec/parser_spec.rbにライブラリコードをINGのです。

require_relative '../lib/go_run/parser'と一緒に試してみましたが、同じエラーが発生しました。

誰かが私が間違っていることを知っていますか?

アップデート:私はこのブランチの完全なコードをアップロードしていますhttps://github.com/henrytk/go_run/tree/stackoverflow-43155117

答えて

1

問題がlib/go_run/parser.rbではなく、テスト自体から発信されます。 RubyがGoRun::Parserの定義を見つけたら、定数ルックアップテーブルでGoRunを探しますが、そこには存在しないので、プログラムはエラーで終了します。 go_run/parser.rbGoRunが定義される前が必要とされるので、エントリポイントとしてlib/go_run.rbを使用しても、動作しません

注意。

GoRunとしてと入力してください。プロジェクトレベルの名前空間とエントリポイントclassがあります。

  1. GoRun名前空間のために純粋に使用され、トップレベルmoduleを行います


    は、あなたがこのような状況を解決するために検討すべきである慣用句がいくつかあります。現在のロジックに存在するロジックをclassに移動します(例:go_run/cli.rb)。 go_run.rbファイルは、プロジェクトのクラスを必要とする一種のマニフェストファイルとして保管されます。

  2. ネストされたmodule - とclassの構文を使用してください。外部モジュールが定義されていない場合、これが定義されます。

  3. require 'go_run'を使用してプロジェクトをブートストラップするファイルspec_helper.rbを使用して、テストを実行する前にすべてが正しくロードされていることを確認してください。

+0

ありがとう@Drenmi。私は 'GoRun :: Parser'の名前空間に名前をつけたいだけでした。なぜなら、それがドキュメンテーションのやり方だからです。どうしてそうしたのか分かりますか?それを 'パーサー 'として放置することの害は何でしょうか? – HenryTK

+0

あなたの宝石は、他の図書館とユーザーコードの両方と一緒に暮らすことを考慮する必要があります。彼らや他の宝石(RuboCopなど)がParser gemに依存していると、名前の競合が発生します。 :-) – Drenmi

+0

優れています。私のGemは、ライブラリとしてではなく、実行可能な 'run'のためだけに使用されることを意図しているので、' gem install'だけで実際に 'go_run 'を' require'する必要はありません。ご協力ありがとうございました。 – HenryTK

関連する問題