Class: Spec::Runner::Context

Inherits:
Object
  • Object
show all
Includes:
ControllerContext
Defined in:
lib/rspec_on_rails.rb,
lib/fixture_loading.rb

Constant Summary collapse

@@already_loaded_fixtures =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ControllerContext

included

Instance Attribute Details

#loaded_fixturesObject

Returns the value of attribute loaded_fixtures.



18
19
20
# File 'lib/fixture_loading.rb', line 18

def loaded_fixtures
  @loaded_fixtures
end

#setup_blockObject

Returns the value of attribute setup_block.



18
19
20
# File 'lib/fixture_loading.rb', line 18

def setup_block
  @setup_block
end

#teardown_blockObject

Returns the value of attribute teardown_block.



18
19
20
# File 'lib/fixture_loading.rb', line 18

def teardown_block
  @teardown_block
end

Class Method Details

.fixtures(*table_names) ⇒ Object



34
35
36
37
38
39
# File 'lib/fixture_loading.rb', line 34

def self.fixtures(*table_names)
  table_names = table_names.flatten.map { |n| n.to_s }
  self.fixture_table_names |= table_names
  require_fixture_classes(table_names)
  setup_fixture_accessors(table_names)
end

.helper(name, &block) ⇒ Object



59
60
61
# File 'lib/rspec_on_rails.rb', line 59

def self.helper(name, &block)
  Spec::Runner::ExecutionContext.send :define_method, name.to_sym, &block
end

.require_fixture_classes(table_names = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fixture_loading.rb', line 45

def self.require_fixture_classes(table_names=nil)
  (table_names || fixture_table_names).each do |table_name| 
    file_name = table_name.to_s
    file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
    begin
      require file_name
    rescue LoadError
      # Let's hope the developer has included it himself
    end
  end
end

.set_fixture_class(class_names = {}) ⇒ Object



30
31
32
# File 'lib/fixture_loading.rb', line 30

def self.set_fixture_class(class_names = {})
  self.fixture_class_names = self.fixture_class_names.merge(class_names)
end

.setup_fixture_accessors(table_names = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/fixture_loading.rb', line 57

def self.setup_fixture_accessors(table_names=nil)

  (table_names || fixture_table_names).each do |table_name|
    table_name = table_name.to_s.tr('.','_')

    # define_method(table_name) 
    # when defining the methods into Spec::Runner::ExecutionContext, you need to make sure
    # it gets all the data it needs passed through somehow
    # this is done in the lambda's in Spec::Runner::Context#run
    Spec::Runner::ExecutionContext.send(:define_method, table_name) do |fixture, *optionals|

      force_reload = optionals.shift
      @fixture_cache[table_name] ||= Hash.new
      @fixture_cache[table_name][fixture] = nil if force_reload

      if @spec.loaded_fixtures[table_name][fixture.to_s]
        @fixture_cache[table_name][fixture] ||= @spec.loaded_fixtures[table_name][fixture.to_s].find
      else
        raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
      end
    end
  end
end

.uses_transaction(*methods) ⇒ Object



81
82
83
84
# File 'lib/fixture_loading.rb', line 81

def self.uses_transaction(*methods)
  @uses_transaction ||= []
  @uses_transaction.concat methods.map { |m| m.to_s }
end

.uses_transaction?(method) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/fixture_loading.rb', line 86

def self.uses_transaction?(method)
  @uses_transaction && @uses_transaction.include?(method.to_s)
end

Instance Method Details

#fixtures(*table_names) ⇒ Object



41
42
43
# File 'lib/fixture_loading.rb', line 41

def fixtures(*table_names)
  self.class.fixtures(*table_names)
end

#helper(name, &block) ⇒ Object



55
56
57
# File 'lib/rspec_on_rails.rb', line 55

def helper(name, &block)
  self.class.helper(name, &block)
end

#run(reporter, dry_run = false) ⇒ Object

entry point into rspec Keep it sync’ed!



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rspec_on_rails.rb', line 26

def run(reporter,dry_run=false)
  ctx = self

  reporter.add_context(@name)

  @specifications.each do |specification|

    specification.run( reporter,
      lambda do
        @fixture_cache = Hash.new
        ctx.setup_with_fixtures
        setup_with_controller(ctx.controller_name)

        specification.loaded_fixtures = ctx.loaded_fixtures

        self.instance_exec(&ctx.setup_block) unless ctx.setup_block.nil?
      end,
      lambda do
        self.instance_exec(&ctx.teardown_block) unless ctx.teardown_block.nil?

        teardown_with_controller
        ctx.teardown_with_fixtures
      end,
      dry_run
    )

  end
end

#setup_with_fixturesObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/fixture_loading.rb', line 97

def setup_with_fixtures
  if pre_loaded_fixtures && use_transactional_fixtures?
    raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures' 
  end

  # @fixture_cache = Hash.new

  # Load fixtures once and begin transaction.
  if use_transactional_fixtures?
    if @@already_loaded_fixtures[self.class]
      @loaded_fixtures = @@already_loaded_fixtures[self.class]
    else
      load_fixtures
      @@already_loaded_fixtures[self.class] = @loaded_fixtures
    end
    ActiveRecord::Base.lock_mutex
    ActiveRecord::Base.connection.begin_db_transaction

  # Load fixtures for every test.
  else
    @@already_loaded_fixtures[self.class] = nil
    load_fixtures
  end

  # Instantiate fixtures for every test if requested.
  instantiate_fixtures if use_instantiated_fixtures
end

#teardown_with_fixturesObject



125
126
127
128
129
130
131
132
# File 'lib/fixture_loading.rb', line 125

def teardown_with_fixtures
  # Rollback changes.
  if use_transactional_fixtures?
    ActiveRecord::Base.connection.rollback_db_transaction
    ActiveRecord::Base.unlock_mutex
  end
  ActiveRecord::Base.verify_active_connections!
end

#use_transactional_fixtures?Boolean

instance

Returns:

  • (Boolean)


91
92
93
94
95
# File 'lib/fixture_loading.rb', line 91

def use_transactional_fixtures?
  use_transactional_fixtures 
  #&&
  #!self.class.uses_transaction?(method_name)
end