Class: Onceler::Recorder

Inherits:
Object
  • Object
show all
Defined in:
lib/onceler/recorder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group_class) ⇒ Recorder

Returns a new instance of Recorder.



17
18
19
20
21
22
# File 'lib/onceler/recorder.rb', line 17

def initialize(group_class)
  @group_class = group_class
  @recordings = []
  @named_recordings = []
  @arounds = []
end

Instance Attribute Details

#tapeObject

Returns the value of attribute tape.



15
16
17
# File 'lib/onceler/recorder.rb', line 15

def tape
  @tape
end

Instance Method Details

#<<(block) ⇒ Object



28
29
30
# File 'lib/onceler/recorder.rb', line 28

def <<(block)
  @recordings << Recording.new(block)
end

#[](name) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/onceler/recorder.rb', line 37

def [](name)
  if @retvals&.key?(name)
    @retvals[name]
  elsif parent
    parent[name]
  end
end

#[]=(name, block) ⇒ Object



32
33
34
35
# File 'lib/onceler/recorder.rb', line 32

def []=(name, block)
  @named_recordings << name
  @recordings << NamedRecording.new(block, name)
end

#add_around(block) ⇒ Object



45
46
47
# File 'lib/onceler/recorder.rb', line 45

def add_around(block)
  @arounds.unshift(block)
end

#aroundsObject



49
50
51
# File 'lib/onceler/recorder.rb', line 49

def arounds
  (parent ? parent.arounds : []) + @arounds
end

#hooksObject



94
95
96
97
98
99
# File 'lib/onceler/recorder.rb', line 94

def hooks
  @hooks ||= {
    before: { record: [], reset: [] },
    after: { record: [], reset: [] }
  }
end

#parentObject



90
91
92
# File 'lib/onceler/recorder.rb', line 90

def parent
  @group_class.parent_onceler
end

#parent_tapeObject



24
25
26
# File 'lib/onceler/recorder.rb', line 24

def parent_tape
  parent.tape || parent.parent_tape if parent
end

#record!Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/onceler/recorder.rb', line 53

def record!
  Onceler.recording = true
  @tape = @group_class.new
  @tape.send(:setup_fixtures)
  @tape.send :extend, Recordable
  @tape.copy_from(parent_tape) if parent_tape

  run_before_hooks(:record, @tape)
  # we don't know the order named recordings will be called (or if
  # they'll call each other), so prep everything first
  @recordings.each do |recording|
    recording.prepare_medium!(@tape)
  end

  # wrap the before in a lambda
  stack = lambda do
    @recordings.each do |recording|
      recording.record_onto!(@tape)
    end
  end
  # and then stack each around block on top
  arounds.inject(stack) do |old_stack, hook|
    -> { @tape.instance_exec(old_stack, &hook) }
  end.call

  run_after_hooks(:record, @tape)
  @data = @tape.__data
ensure
  Onceler.recording = false
end

#replay_into!(instance) ⇒ Object



123
124
125
126
127
128
# File 'lib/onceler/recorder.rb', line 123

def replay_into!(instance)
  @ivars, @retvals = Marshal.load(@data)
  @ivars.each do |key, value|
    instance.instance_variable_set(key, value)
  end
end

#reset!Object



84
85
86
87
88
# File 'lib/onceler/recorder.rb', line 84

def reset!
  run_before_hooks(:reset)
  @tape&.teardown_fixtures
  run_after_hooks(:reset)
end

#run_after_hooks(scope, context = nil) ⇒ Object



112
113
114
115
116
117
118
119
120
121
# File 'lib/onceler/recorder.rb', line 112

def run_after_hooks(scope, context = nil)
  hooks[:after][scope].each do |hook|
    context ? context.instance_eval(&hook) : hook.call
  end
  if parent
    parent.run_after_hooks(scope, context)
  else
    Onceler.configuration.run_hooks(:after, scope, context)
  end
end

#run_before_hooks(scope, context = nil) ⇒ Object



101
102
103
104
105
106
107
108
109
110
# File 'lib/onceler/recorder.rb', line 101

def run_before_hooks(scope, context = nil)
  if parent
    parent.run_before_hooks(scope, context)
  else
    Onceler.configuration.run_hooks(:before, scope, context)
  end
  hooks[:before][scope].each do |hook|
    context ? context.instance_eval(&hook) : hook.call
  end
end