Как использовать Dir.mktmpdir с блоком в хуке с rspec? - PullRequest
0 голосов
/ 02 августа 2011

Я хочу создать tmpdir в хуке before-each и использовать его путь в примере rspec. Я хочу использовать блочную форму Dir.mktmpdir, чтобы удалить dir в конце примера.

Проблемы:

  • Я не могу позволить блоку выйти из ловушки before, или директория удалена, прежде чем мой пример сможет работать.
  • Я не могу обернуть блок вокруг моего примера. Я пытался использовать вокруг крюк, но это не разделяет переменные экземпляра с примерами ( doc подтверждает это поведение).

В настоящее время я использую продолжения (Fibers было бы лучше, если бы я был на 1.9), чтобы выпрыгнуть из блока, а затем вернуться назад, чтобы mktmpdir смог очиститься.

Есть ли более простой способ сделать это, не перемещая mktmpdir внутри каждого примера? Это правда, что я могу удалить dir в вспомогательном хуке, но я также ищу общее решение проблемы такого типа - я не всегда знаю, какой код очистки должен выполняться при выходе из блока.

К вашему сведению, мой код продолжения, инкапсулированный в класс:

class SuspendableBlock
  def initialize
  end

  def run(&block)
    raise LocalJumpError unless block_given?
    callcc {|@run_cc|
      yield
      @resume_cc.call if @resume_cc
    }
    nil
  end

  # saves the suspend point & causes run to return immediately
  def suspend
    raise "run must be called first" unless @run_cc
    callcc {|@suspend_cc|
      @run_cc.call(@suspend_cc)
    }
    nil
  end

  # jumps back to after the suspend point to finish the block.
  # after the block exits, return immediately from resume.
  def resume
    raise "suspend must be called first" unless @suspend_cc
    callcc {|@resume_cc|
      @suspend_cc.call(@resume_cc)
    }
    nil
  end
end

Использование:

before :each do
  @sb = SuspendableBlock.new
  @sb.run do
    Dir.mktmpdir do |dir|
      @tmpdir_path = Pathname.new(dir)
      @sb.suspend
    end
  end
end

after :each do
  @sb.resume
end

it "should use a tmp dir" do
  p @tmpdir_path
end

1 Ответ

1 голос
/ 10 октября 2011

Из того, что я прочитал (никогда не проверял), продолжения действительно неэффективны.

Хотя я не могу помочь вам в продолжениях, вы можете использовать Thread для имитации волокон: https://github.com/tmm1/fiber18.

Одна библиотека, которая уже выполняет это em-spec (https://github.com/tmm1/em-spec),, при этом каждый тест запускается в волокне, вы можете изменить его в соответствии с вашими потребностями.

...