trecs 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/Gemfile.lock +13 -1
- data/bin/trecs_message +4 -0
- data/lib/trecs/player.rb +128 -0
- data/lib/trecs/recorder.rb +59 -0
- data/lib/trecs/recording_strategies/custom_strategy.rb +5 -0
- data/lib/trecs/recording_strategies/hash_strategy.rb +17 -0
- data/lib/{recording_strategies/incremental_recording_strategy.rb → trecs/recording_strategies/incremental_strategy.rb} +4 -3
- data/lib/trecs/recording_strategies/raw_file_strategy.rb +54 -0
- data/lib/{recording_strategies → trecs/recording_strategies}/ttyrec_recording_strategy.rb +0 -0
- data/lib/{screens → trecs/screens}/terminal_screen.rb +0 -0
- data/lib/trecs/version.rb +1 -1
- data/lib/trecs/writers/in_memory_writer.rb +17 -0
- data/lib/{recorders/zip_file_recorder.rb → trecs/writers/zip_file_writer.rb} +9 -7
- data/lib/trecs.rb +3 -0
- data/{spec → old_specs}/player_spec.rb +0 -0
- data/{spec → old_specs/recorders}/zip_file_recorder_spec.rb +11 -5
- data/{spec → old_specs}/timestamps_spec.rb +0 -0
- data/{spec → old_specs}/trecs_message_spec.rb +0 -0
- data/{spec → old_specs}/trecs_spec.rb +0 -0
- data/pkg/trecs-0.0.3.gem +0 -0
- data/spec/spec_helper.rb +90 -20
- data/spec/trecs/player_spec.rb +76 -0
- data/spec/trecs/recorder_spec.rb +227 -0
- data/spec/trecs/recording_strategies/incremental_strategy_spec.rb +43 -0
- data/spec/trecs/recording_strategies/raw_file_strategy_spec.rb +66 -0
- data/spec/trecs/writers/in_memory_writer_spec.rb +45 -0
- data/trecs.gemspec +4 -1
- metadata +78 -41
- data/lib/player.rb +0 -76
- data/lib/recorder.rb +0 -74
- data/lib/recording_strategies/raw_file_recording_strategy.rb +0 -42
- data/spec/recorder_spec.rb +0 -249
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OTk1Njk3M2RhYzJhZTFhODg5ZTBhM2IzMmZhYzI5YjcyNjY1NDQ4YQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6b9b65056214045e29a8c560870c4e53b4bc04b7
|
4
|
+
data.tar.gz: f8ed9275619e0d6afc1ab51f4580dbced02be455
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YzE0NjAwZWYyZDQxODRlMmZjYzdmMzFhZmY5NWJkNTBiYjE3NzMyNmU5Nzky
|
11
|
-
YmI3YTUxYmYwYTVkMWIyNWQ3ODYwYTM4MDZhMTM0OWYzMDcwODM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NTQzY2U1NmM2Yjc3YjkyODdjOGU3NmQxYzY2NDE4MzFkODk5ODY4YTk2YzRl
|
14
|
-
MjA0YWM0M2ZmYTQ0OGM2ZTg3MGU0N2NlZTA5NTg4NmQ0ZTA2YzI3OGYwN2I0
|
15
|
-
Mjc4ZDQ4MGFkNzU2ZWI4ZjlkZDU3N2NhZTE5YTQ0Y2RkOTEyOTk=
|
6
|
+
metadata.gz: 19da3e8a8954ded968fc30564efc5f6f0aebe8f331cca3cb75932a1cb45820d508432d026a090fa94d07dd15a027359e01b330db2a019c101b40bb3e68033b0b
|
7
|
+
data.tar.gz: da0ef87b85613a53b6f0345a2f1e2e3438739fcc28e37c4a0df6ecbd30fb71f371a80d030387f2df349ec0b92df90ce4bf90e3ed7595d2e187ecbb54a1633704
|
data/Gemfile.lock
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
trecs (0.0.
|
4
|
+
trecs (0.0.4)
|
5
5
|
rubyzip (~> 1.1.4)
|
6
6
|
trollop (~> 2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
coderay (1.1.0)
|
11
12
|
diff-lcs (1.2.5)
|
12
13
|
given_core (3.5.4)
|
13
14
|
sorcerer (>= 0.3.7)
|
15
|
+
method_source (0.8.2)
|
16
|
+
pry (0.9.12.6)
|
17
|
+
coderay (~> 1.0)
|
18
|
+
method_source (~> 0.8)
|
19
|
+
slop (~> 3.4)
|
20
|
+
pry-nav (0.2.3)
|
21
|
+
pry (~> 0.9.10)
|
14
22
|
rake (10.3.2)
|
15
23
|
rspec (2.99.0)
|
16
24
|
rspec-core (~> 2.99.0)
|
@@ -24,14 +32,18 @@ GEM
|
|
24
32
|
rspec (>= 2.12)
|
25
33
|
rspec-mocks (2.99.0)
|
26
34
|
rubyzip (1.1.4)
|
35
|
+
slop (3.5.0)
|
27
36
|
sorcerer (1.0.2)
|
28
37
|
trollop (2.0)
|
29
38
|
|
30
39
|
PLATFORMS
|
40
|
+
java
|
31
41
|
ruby
|
32
42
|
|
33
43
|
DEPENDENCIES
|
34
44
|
bundler (~> 1.6)
|
45
|
+
pry
|
46
|
+
pry-nav
|
35
47
|
rake
|
36
48
|
rspec (~> 2.12)
|
37
49
|
rspec-given (~> 3.5.4)
|
data/bin/trecs_message
CHANGED
@@ -13,6 +13,10 @@ options = Trollop::options do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
if options[:file_name]
|
16
|
+
|
17
|
+
recorder = Recorder.new(
|
18
|
+
persistence_strategy: ZipFileRecorder.new(file_name: file_name),
|
19
|
+
recording_strategy: IncrementalRecordingStrategy.new(message: message)
|
16
20
|
recorder = TRecs::MessageRecorder.new(options)
|
17
21
|
recorder.record
|
18
22
|
else
|
data/lib/trecs/player.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require "screens/terminal_screen"
|
2
|
+
|
3
|
+
module TRecs
|
4
|
+
class Player
|
5
|
+
attr_reader :reader
|
6
|
+
attr_reader :screen
|
7
|
+
attr_reader :ticker
|
8
|
+
attr_reader :step
|
9
|
+
attr_reader :current_time
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
time = options.fetch(:time) { nil }
|
13
|
+
@reader = options.fetch(:reader)
|
14
|
+
@reader.player = self
|
15
|
+
|
16
|
+
@ticker = options.fetch(:ticker)
|
17
|
+
@ticker.player = self
|
18
|
+
|
19
|
+
@screen = options.fetch(:screen) { TerminalScreen.new }
|
20
|
+
|
21
|
+
@testing = options.fetch(:testing) { false }
|
22
|
+
|
23
|
+
@current_time = time
|
24
|
+
@step = options.fetch(:step) { 100 }
|
25
|
+
end
|
26
|
+
|
27
|
+
def play
|
28
|
+
reader.setup
|
29
|
+
ticker.start
|
30
|
+
end
|
31
|
+
|
32
|
+
def tick(time=current_time)
|
33
|
+
content = reader.frame_at(time)
|
34
|
+
if content != @prev_content
|
35
|
+
screen.clear
|
36
|
+
screen.puts(content)
|
37
|
+
@prev_content = content
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def timestamps
|
42
|
+
reader.timestamps
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
attr_writer :current_time
|
47
|
+
attr_reader :testing
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# require "timestamps"
|
54
|
+
# require "screens/terminal_screen"
|
55
|
+
|
56
|
+
# module TRecs
|
57
|
+
# class Player
|
58
|
+
# attr_reader :screen
|
59
|
+
|
60
|
+
# def initialize(options={})
|
61
|
+
# time = options.fetch(:time) { nil }
|
62
|
+
# @current_time = time
|
63
|
+
# @step = options.fetch(:step) { 100 }
|
64
|
+
# @screen = options.fetch(:screen) { TerminalScreen.new }
|
65
|
+
# @testing = options.fetch(:testing) { false }
|
66
|
+
# @ticks = time ? Array(time.to_i) : ticks
|
67
|
+
# end
|
68
|
+
|
69
|
+
# def play
|
70
|
+
# ticks.each do |time|
|
71
|
+
# play_frame(time)
|
72
|
+
# sleep(sleep_time) unless testing
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
|
76
|
+
# def tick(time=current_time)
|
77
|
+
# self.current_time = time
|
78
|
+
# get_frame(time)
|
79
|
+
# end
|
80
|
+
|
81
|
+
# def timestamps
|
82
|
+
# @timestamps ||= get_timestamps.sort
|
83
|
+
# end
|
84
|
+
|
85
|
+
# def generate_ticks
|
86
|
+
# ticks = [0]
|
87
|
+
# curr = 0
|
88
|
+
# while(curr < timestamps.last.to_i)
|
89
|
+
# curr += step
|
90
|
+
# ticks << curr
|
91
|
+
# end
|
92
|
+
# ticks
|
93
|
+
# end
|
94
|
+
|
95
|
+
# def ticks
|
96
|
+
# @ticks ||= generate_ticks
|
97
|
+
# end
|
98
|
+
|
99
|
+
# def play_frame(time)
|
100
|
+
# screen.clear
|
101
|
+
# screen.puts tick(time_at(time))
|
102
|
+
# end
|
103
|
+
|
104
|
+
# def time_at(time)
|
105
|
+
# Timestamps.new(timestamps).time_at(time)
|
106
|
+
# end
|
107
|
+
|
108
|
+
# private
|
109
|
+
# attr_accessor :current_time
|
110
|
+
# attr_reader :step
|
111
|
+
# attr_reader :testing
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
# def get_timestamps
|
116
|
+
# []
|
117
|
+
# end
|
118
|
+
|
119
|
+
# def get_frame(time)
|
120
|
+
# ""
|
121
|
+
# end
|
122
|
+
|
123
|
+
# def sleep_time
|
124
|
+
# # TODO: Fix this to use the current time
|
125
|
+
# @sleep_time ||= (step/1000.0)*0.8
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
# end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module TRecs
|
2
|
+
class Recorder
|
3
|
+
attr_reader :writer
|
4
|
+
attr_reader :strategy
|
5
|
+
attr_reader :step
|
6
|
+
attr_reader :recording
|
7
|
+
attr_reader :current_time
|
8
|
+
attr_reader :current_content
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@writer = options.fetch(:writer)
|
13
|
+
@writer.recorder = self
|
14
|
+
|
15
|
+
@strategy = options.fetch(:strategy)
|
16
|
+
@strategy.recorder = self
|
17
|
+
|
18
|
+
@step = options.fetch(:step) { 100 }
|
19
|
+
@recording = false
|
20
|
+
@current_time = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def record
|
24
|
+
self.current_time = nil
|
25
|
+
self.recording = true
|
26
|
+
writer.setup
|
27
|
+
strategy.perform
|
28
|
+
writer.render
|
29
|
+
self.recording = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_frame(options={})
|
33
|
+
time = options.fetch(:time) { next_timestamp }
|
34
|
+
content = options.fetch(:content)
|
35
|
+
@current_time = time
|
36
|
+
@current_content = content
|
37
|
+
|
38
|
+
if @previous_content != content
|
39
|
+
writer.create_frame(time: current_time, content: current_content)
|
40
|
+
@previous_content = content
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def next_timestamp
|
45
|
+
@current_time = -step unless @current_time
|
46
|
+
@current_time += step
|
47
|
+
end
|
48
|
+
|
49
|
+
def stop
|
50
|
+
strategy.stop
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
attr_writer :recording
|
55
|
+
attr_writer :current_time
|
56
|
+
attr_writer :current_content
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class HashStrategy
|
2
|
+
attr_accessor :recorder
|
3
|
+
attr_accessor :frames
|
4
|
+
|
5
|
+
def initialize(frames)
|
6
|
+
@frames = frames || Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform
|
10
|
+
@frames.each do |time, content|
|
11
|
+
recorder.current_frame(time: time, content: content)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
end
|
17
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require "recording_strategy"
|
2
2
|
module TRecs
|
3
|
-
class
|
3
|
+
class IncrementalStrategy
|
4
|
+
attr_reader :message
|
5
|
+
attr_accessor :recorder
|
6
|
+
|
4
7
|
def initialize(options={})
|
5
8
|
@message = options.fetch(:message)
|
6
|
-
super(options)
|
7
9
|
end
|
8
10
|
|
9
11
|
def perform
|
@@ -16,7 +18,6 @@ module TRecs
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
private
|
19
|
-
attr_reader :message
|
20
21
|
|
21
22
|
def timestamp_for(message)
|
22
23
|
(message.size - 1) * recorder.step
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "recording_strategy"
|
2
|
+
module TRecs
|
3
|
+
class RawFileStrategy
|
4
|
+
attr_accessor :recorder
|
5
|
+
attr_reader :file
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
file = options.fetch(:file)
|
9
|
+
@file = File.open(file)
|
10
|
+
|
11
|
+
@clock = options.fetch(:clock) { Time }
|
12
|
+
@testing = options.fetch(:testing) { false }
|
13
|
+
#
|
14
|
+
#@height = options.fetch(:height) { 24 }
|
15
|
+
#@width = options.fetch(:width) { 80 }
|
16
|
+
#
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
@recording = true
|
21
|
+
start_time = clock.now
|
22
|
+
|
23
|
+
while @recording
|
24
|
+
time = timestamp(clock.now - start_time)
|
25
|
+
content = File.read(@file)
|
26
|
+
recorder.current_frame(time: time, content: content)
|
27
|
+
custom_sleep(recorder.step)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def custom_sleep(millis)
|
32
|
+
if testing
|
33
|
+
clock.sleep(millis)
|
34
|
+
else
|
35
|
+
@sleep_time ||= (millis/1000.0)
|
36
|
+
sleep(@sleep_time)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
@recording = false
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
attr_reader :clock
|
46
|
+
attr_reader :testing
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
def timestamp(time)
|
51
|
+
(time * 1000).to_i
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
File without changes
|
File without changes
|
data/lib/trecs/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
class InMemoryWriter
|
2
|
+
attr_accessor :recorder
|
3
|
+
attr_reader :frames
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@frames = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_frame(options={})
|
10
|
+
time = options.fetch(:time)
|
11
|
+
content = options.fetch(:content)
|
12
|
+
@frames[time] = content
|
13
|
+
end
|
14
|
+
|
15
|
+
def render
|
16
|
+
end
|
17
|
+
end
|
@@ -2,18 +2,16 @@ require "zip"
|
|
2
2
|
require "recorder"
|
3
3
|
|
4
4
|
module TRecs
|
5
|
-
class ZipFileRecorder
|
5
|
+
class ZipFileRecorder
|
6
|
+
attr_accessor :recorder
|
7
|
+
|
6
8
|
include FileUtils
|
7
9
|
def initialize(options={})
|
8
|
-
super(options)
|
9
10
|
@file_name = options.fetch(:file_name)
|
10
11
|
delete_file
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
-
attr_reader :file_name
|
15
|
-
attr_reader :frames
|
16
|
-
|
14
|
+
|
17
15
|
# this
|
18
16
|
def setup
|
19
17
|
@frames = {}
|
@@ -30,10 +28,14 @@ module TRecs
|
|
30
28
|
end
|
31
29
|
end
|
32
30
|
|
31
|
+
|
33
32
|
def create_frame
|
34
|
-
frames[current_time] = current_content
|
33
|
+
frames[recorder.current_time] = recorder.current_content
|
35
34
|
end
|
36
35
|
|
36
|
+
private
|
37
|
+
attr_reader :frames
|
38
|
+
|
37
39
|
def delete_file
|
38
40
|
rm file_name if File.exists? file_name
|
39
41
|
end
|
data/lib/trecs.rb
ADDED
File without changes
|
@@ -7,11 +7,12 @@ require "players/zip_file_player"
|
|
7
7
|
module TRecs
|
8
8
|
describe ZipFileRecorder do
|
9
9
|
class DummyRecordingStrategy
|
10
|
-
|
10
|
+
attr_accessor :recorder
|
11
11
|
|
12
12
|
def initialize(options={})
|
13
|
-
|
13
|
+
#@recorder = options.fetch(:recorder)
|
14
14
|
end
|
15
|
+
|
15
16
|
def perform
|
16
17
|
recorder.current_frame(time: 0, content: "zero")
|
17
18
|
recorder.current_frame(time: 1, content: "one")
|
@@ -27,12 +28,15 @@ module TRecs
|
|
27
28
|
end
|
28
29
|
|
29
30
|
it "expects a file name" do
|
30
|
-
expect {
|
31
|
+
expect {
|
32
|
+
Recorder.new( persistence_strategy: ZipFileRecorder.new, recording_strategy: DummyRecordingStrategy.new) }.to raise_error
|
31
33
|
end
|
32
34
|
|
33
35
|
it "generates a .trecs compressed file" do
|
34
36
|
file_name = "tmp/i_should_exist.trecs"
|
35
|
-
recorder
|
37
|
+
recorder = Recorder.new(
|
38
|
+
persistence_strategy: ZipFileRecorder.new(file_name: file_name),
|
39
|
+
recording_strategy: DummyRecordingStrategy.new)
|
36
40
|
|
37
41
|
recorder.record
|
38
42
|
|
@@ -42,7 +46,9 @@ module TRecs
|
|
42
46
|
|
43
47
|
it "has the correct frames" do
|
44
48
|
file_name = "tmp/zero_one_two.trecs"
|
45
|
-
recorder
|
49
|
+
recorder = Recorder.new(
|
50
|
+
persistence_strategy: ZipFileRecorder.new(file_name: file_name),
|
51
|
+
recording_strategy: DummyRecordingStrategy.new)
|
46
52
|
|
47
53
|
recorder.record
|
48
54
|
|
File without changes
|
File without changes
|
File without changes
|
data/pkg/trecs-0.0.3.gem
ADDED
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -1,32 +1,102 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
1
|
+
require File.expand_path("../../lib/trecs", __FILE__)
|
2
|
+
|
3
|
+
require "rspec/given"
|
4
|
+
require "ostruct"
|
5
|
+
|
7
6
|
RSpec.configure do |config|
|
8
7
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
8
|
config.run_all_when_everything_filtered = true
|
10
9
|
config.filter_run :focus
|
11
|
-
|
12
|
-
# Run specs in random order to surface order dependencies. If you find an
|
13
|
-
# order dependency and want to debug it, you can fix the order by providing
|
14
|
-
# the seed, which is printed after each run.
|
15
|
-
# --seed 1234
|
16
10
|
config.order = 'random'
|
17
11
|
end
|
18
12
|
|
19
|
-
|
13
|
+
class Spy
|
14
|
+
attr_reader :calls
|
15
|
+
|
16
|
+
@calls = {}
|
17
|
+
@index = 0
|
18
|
+
|
19
|
+
def initialize(name)
|
20
|
+
@calls = {}
|
21
|
+
@index = 0
|
22
|
+
@name = name
|
23
|
+
@skips = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.clear
|
27
|
+
@calls = {}
|
28
|
+
@index = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method, *args)
|
32
|
+
unless @skips.include? method
|
33
|
+
@index = @index + 1
|
34
|
+
self.class.inc_index
|
35
|
+
|
36
|
+
@calls[@index] = add_call(method, args)
|
37
|
+
self.class.add_call(@name, method, args)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def ignore(*methods)
|
42
|
+
methods.each do |method|
|
43
|
+
@skips << method
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
alias :skip :ignore
|
48
|
+
|
49
|
+
def self.inc_index
|
50
|
+
@index = @index + 1
|
51
|
+
end
|
20
52
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
53
|
+
def add_call(method, args)
|
54
|
+
@calls[@index] = [method, args]
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.add_call(name, method, args)
|
58
|
+
@calls[@index] = [name, method, args]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.calls
|
62
|
+
@calls
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
class CustomTicker
|
68
|
+
attr_accessor :player
|
69
|
+
def initialize(*ticks)
|
70
|
+
@ticks = ticks
|
71
|
+
end
|
72
|
+
def start
|
73
|
+
@ticks.each do |time|
|
74
|
+
player.tick(time)
|
75
|
+
end
|
76
|
+
end
|
24
77
|
end
|
25
78
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
79
|
+
class CustomReader
|
80
|
+
attr_accessor :player
|
81
|
+
def initialize(frames={})
|
82
|
+
@frames = frames
|
83
|
+
end
|
84
|
+
def frame_at(n)
|
85
|
+
@frames[n]
|
86
|
+
end
|
87
|
+
def setup
|
31
88
|
end
|
32
89
|
end
|
90
|
+
|
91
|
+
# def create_dir(dir_path)
|
92
|
+
# mkdir_p dir_path unless File.exist?(dir_path)
|
93
|
+
# dir_path
|
94
|
+
# end
|
95
|
+
|
96
|
+
# def file_name(string=nil)
|
97
|
+
# if string
|
98
|
+
# @file_name = "#{project_dir}/#{string}.trecs"
|
99
|
+
# else
|
100
|
+
# @file_name
|
101
|
+
# end
|
102
|
+
# end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "player"
|
4
|
+
|
5
|
+
module TRecs
|
6
|
+
describe Player do
|
7
|
+
context "initialization" do
|
8
|
+
Given(:reader) { OpenStruct.new }
|
9
|
+
Given(:ticker) { OpenStruct.new }
|
10
|
+
Given(:screen) { Object.new }
|
11
|
+
|
12
|
+
When(:player) {
|
13
|
+
Player.new(
|
14
|
+
reader: reader,
|
15
|
+
ticker: ticker,
|
16
|
+
screen: screen,
|
17
|
+
)
|
18
|
+
}
|
19
|
+
|
20
|
+
Then { player.reader == reader }
|
21
|
+
Then { reader.player == player}
|
22
|
+
|
23
|
+
Then { player.ticker == ticker }
|
24
|
+
Then { ticker.player == player}
|
25
|
+
|
26
|
+
Then { player.step == 100}
|
27
|
+
Then { player.screen == screen}
|
28
|
+
end
|
29
|
+
|
30
|
+
context "Playing" do
|
31
|
+
Given { Spy.clear }
|
32
|
+
Given(:reader) { Spy.new("reader").ignore(:player=) }
|
33
|
+
Given(:ticker) { Spy.new("ticker").ignore(:player=) }
|
34
|
+
Given(:player) {
|
35
|
+
Player.new(reader: reader, ticker: ticker)
|
36
|
+
}
|
37
|
+
|
38
|
+
When { player.play }
|
39
|
+
|
40
|
+
Then { Spy.calls[1] == ["reader", :setup, []] }
|
41
|
+
Then { Spy.calls[2] == ["ticker", :start, []] }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "Playing some frames" do
|
45
|
+
Given { Spy.clear }
|
46
|
+
Given(:screen) { Spy.new("screen") }
|
47
|
+
Given(:player) {
|
48
|
+
Player.new(reader: reader, ticker: ticker, screen: screen)
|
49
|
+
}
|
50
|
+
|
51
|
+
When { player.play }
|
52
|
+
|
53
|
+
context "no repetitions" do
|
54
|
+
Given(:reader) { CustomReader.new(0 => "a", 100 => "b") }
|
55
|
+
Given(:ticker) { CustomTicker.new(0, 100) }
|
56
|
+
|
57
|
+
Then { screen.calls[1] == [:clear, []] }
|
58
|
+
Then { screen.calls[2] == [:puts, ["a"]] }
|
59
|
+
Then { screen.calls[3] == [:clear, []] }
|
60
|
+
Then { screen.calls[4] == [:puts, ["b"]] }
|
61
|
+
Then { screen.calls.size == 4 }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with repetitions" do
|
65
|
+
Given(:reader) { CustomReader.new(0 => "a", 100 => "b", 200 => "b") }
|
66
|
+
Given(:ticker) { CustomTicker.new(0, 100, 200) }
|
67
|
+
|
68
|
+
Then { screen.calls[1] == [:clear, []] }
|
69
|
+
Then { screen.calls[2] == [:puts, ["a"]] }
|
70
|
+
Then { screen.calls[3] == [:clear, []] }
|
71
|
+
Then { screen.calls[4] == [:puts, ["b"]] }
|
72
|
+
Then { screen.calls.size == 4 }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|