TL;DR
File.expand_path(File.join(Rails.root, "./my_config/hogehoge")) => "/Users/yoan/dev/src/github.com/myoan/rails_test/my_config/hogehoge"
とずっと書いていましたが、
File.expand_path("./my_config/hogehoge", Rails.root) => "/Users/yoan/dev/src/github.com/myoan/rails_test/my_config/hogehoge"
と書くほうがシンプルでした
挙動を調べる
リファレンスによると、
expand_path(path, default_dir = '.') -> String[permalink][rdoc] (中略) [PARAM] path: パスを表す文字列を指定します。 [PARAM] default_dir: path が相対パスであれば default_dir を基準に展開されます。
と書かれています。
相対パスなので第一引数のパスに対する比較対象が必要で、第二引数がその対象になります。 そして、第二引数が省略された場合は今いるパスが対象になります。
したがって、
File.expand_path("../hoge")
は今いるパス
から"../hoge"
移動した絶対パスを返すFile.expand_path("../hoge", "/tmp")
は/tmp
から"../hoge"
移動した絶対パスを返す- つまり
/hoge
- つまり
File.expand_path("./my_config/hogehoge", Rails.root)
はRails.root
から"./my_config/hogehoge"
移動した絶対パスを返す- つまり
Rails.root/my_config/hogehoge
- つまり
そもそもの問題
modelにはそのまま相対パスを、rspecにはRails.rootとjoinした形で書いていました
### rb def my_path mkdir_if_not_exist(File.expand_path("../my_config/hogehoge")) File.expand_path("../my_config/hogehoge") end ### spec describe do it { is_expected(my_path).to eq File.expand_path(File.join(Rails.root, '../my_config/hogehoge'))" } end
テストではディレクトリを作ってほしくないためFakeFSを導入したところエラーが出たところが始まりでした
expected: "/Users/yoan/dev/src/github.com/rails-test/my_config/hogehoge" got: "/my_conofig/hogehoge"
FakeFS.expand_pathを調べたところ
def self.expand_path(file_name, dir_string = FileSystem.current_dir.to_s) RealFile.expand_path(file_name, RealFile.expand_path(dir_string, Dir.pwd)) end
となっており、第二引数に"/"
が渡されていました
つまりルートディレクトリからの絶対パスを返していたため、got
の結果が帰ってきたというわけでした。