tryruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ require_relative 'spec_helper'
2
+ require 'ripl'
3
+ require_relative '../lib/tryruby/commands'
4
+ require_relative '../lib/tryruby/next_fix'
5
+
6
+ # mocking shell
7
+ module TestShellModule
8
+ class << self; attr_reader :called; end
9
+ @called = {}
10
+
11
+ def next_challenge
12
+ TestShellModule.called[:next_challenge] = true
13
+ end
14
+
15
+ def prev_challenge
16
+ TestShellModule.called[:prev_challenge] = true
17
+ end
18
+
19
+ def help_challenge
20
+ TestShellModule.called[:help_challenge] = true
21
+ end
22
+ end
23
+
24
+ Ripl::Shell.include TestShellModule
25
+ Ripl::Shell.include Tryruby::NextFix
26
+ Ripl::Commands.include Tryruby::Commands
27
+ Ripl.shell.before_loop
28
+
29
+ describe Tryruby::Commands do
30
+ let(:input) { nil }
31
+ before(:each) do
32
+ TestShellModule.called.clear
33
+ Ripl.shell.eval_input(input)
34
+ end
35
+ subject { TestShellModule.called }
36
+ describe '#next' do
37
+ let(:input) { 'next' }
38
+ it { is_expected.to eq next_challenge: true }
39
+ end
40
+
41
+ describe '#back' do
42
+ let(:input) { 'back' }
43
+ it { is_expected.to eq prev_challenge: true }
44
+ end
45
+
46
+ describe '#help' do
47
+ let(:input) { 'help' }
48
+ it { is_expected.to eq help_challenge: true }
49
+ end
50
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/tryruby/level_builder'
3
+
4
+ describe Tryruby::LevelBuilder do
5
+ subject { described_class.new }
6
+
7
+ describe '#challenge' do
8
+ it 'adds challenges' do
9
+ subject.challenge do
10
+ help 'first'
11
+ end
12
+ subject.challenge do
13
+ help 'second'
14
+ end
15
+ level = subject.level
16
+ expect(level[0].help).to eq 'first'
17
+ expect(level[1].help).to eq 'second'
18
+ expect(level.length).to eq 2
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/tryruby/level'
3
+ require_relative '../lib/tryruby/challenge'
4
+
5
+ describe Tryruby::Level do
6
+ let(:a) { Tryruby::Challenge.new('a') }
7
+ let(:b) { Tryruby::Challenge.new('b') }
8
+ subject { described_class.new(a, b) }
9
+
10
+ describe '#[]' do
11
+ it 'returns proper item' do
12
+ expect(subject[0]).to eq a
13
+ expect(subject[1]).to eq b
14
+ end
15
+ end
16
+
17
+ describe '#each' do
18
+ it 'iterates through items' do
19
+ yielded = []
20
+ subject.each { |i| yielded << i }
21
+ expect(yielded).to eq [a, b]
22
+ end
23
+ end
24
+
25
+ describe '#length' do
26
+ it 'returns number of items' do
27
+ expect(subject.length).to eq 2
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/tryruby/next_fix'
3
+
4
+ describe Tryruby::NextFix do
5
+ # mocking module to properly inherit
6
+ module API
7
+ def loop_eval(str)
8
+ str
9
+ end
10
+ end
11
+
12
+ include API
13
+ include described_class
14
+
15
+ it 'converts next to self.next' do
16
+ expect(loop_eval('next')).to eq 'self.next'
17
+ end
18
+
19
+ it 'does not convert "next"' do
20
+ expect(loop_eval('"next"')).to eq '"next"'
21
+ end
22
+ end
@@ -0,0 +1,205 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/tryruby/shell'
3
+ require_relative '../lib/tryruby/challenge'
4
+
5
+ # mocking shell
6
+ class TestShell
7
+ class << self; public :include; end
8
+
9
+ def initialize
10
+ @binding = create_binding
11
+ @result = false
12
+ end
13
+
14
+ # mocking module to properly inherit
15
+ module API
16
+ def before_loop
17
+ end
18
+
19
+ def loop_once
20
+ end
21
+ end
22
+
23
+ def create_binding
24
+ foo = 42
25
+ bar = 24
26
+ binding
27
+ end
28
+
29
+ include API
30
+ end
31
+
32
+ TestShell.include Tryruby::Shell
33
+
34
+ describe Tryruby::Shell do
35
+ called = []
36
+ let(:test) do
37
+ proc do |result, vars, output|
38
+ called << [:test, self, result, vars.dup, output]
39
+ result
40
+ end
41
+ end
42
+ let(:setup) do
43
+ proc do |vars|
44
+ called << [:setup, self, vars.dup]
45
+ vars[:test_var] ||= 0
46
+ vars[:test_var] += 1
47
+ end
48
+ end
49
+ let(:a) { Tryruby::Challenge.new('a', test, setup) }
50
+ let(:b) { Tryruby::Challenge.new('b', nil, setup) }
51
+ let(:c) { Tryruby::Challenge.new('c', test) }
52
+ let(:levels) { [[a, b], [], [c]] }
53
+ let(:shell) { TestShell.new.tap { |sh| sh.levels = levels } }
54
+
55
+ def test_var
56
+ eval('test_var', shell.instance_eval('@binding'))
57
+ end
58
+
59
+ subject { shell.challenge }
60
+
61
+ before(:each) do
62
+ called = []
63
+ shell.before_loop
64
+ end
65
+
66
+ describe '#before_loop' do
67
+ it 'prints help and calls setup' do
68
+ is_expected.to eq a
69
+ expect(called).to eq [[:setup, shell, { foo: 42, bar: 24 }]]
70
+ expect(test_var).to eq 1
71
+ end
72
+ end
73
+
74
+ describe '#next_challenge' do
75
+ let(:test) {}
76
+ it 'prints helps and calls setups' do
77
+ expect do
78
+ shell.next_challenge
79
+ shell.loop_once
80
+ end.to match_stdout('b')
81
+ expect(shell.challenge).to eq b
82
+ expect(test_var).to eq 2
83
+ expect do
84
+ shell.next_challenge
85
+ shell.loop_once
86
+ end.to match_stdout('c')
87
+ expect(shell.challenge).to eq c
88
+ expect(test_var).to eq 2
89
+ expect do
90
+ shell.next_challenge
91
+ shell.loop_once
92
+ end.to throw_symbol(:ripl_exit)
93
+ expect(shell.challenge).to eq nil
94
+ expect(test_var).to eq 2
95
+ expect(called).to eq [
96
+ [:setup, shell, { foo: 42, bar: 24 }],
97
+ [:setup, shell, { foo: 42, bar: 24, test_var: 1 }]
98
+ ]
99
+ end
100
+ end
101
+
102
+ describe '#prev_challenge' do
103
+ let(:test) {}
104
+ it 'prints helps and calls setups' do
105
+ 2.times do
106
+ shell.next_challenge
107
+ shell.loop_once
108
+ end
109
+ expect(shell.challenge).to eq c
110
+ expect(test_var).to eq 2
111
+ expect do
112
+ shell.prev_challenge
113
+ shell.loop_once
114
+ end.to match_stdout('b')
115
+ expect(shell.challenge).to eq b
116
+ expect(test_var).to eq 3
117
+ expect do
118
+ shell.prev_challenge
119
+ shell.loop_once
120
+ end.to match_stdout('a')
121
+ expect(shell.challenge).to eq a
122
+ expect(test_var).to eq 4
123
+ expect do
124
+ shell.prev_challenge
125
+ shell.loop_once
126
+ end.to match_stdout('')
127
+ expect(shell.challenge).to eq a
128
+ expect(test_var).to eq 4
129
+ expect(called).to eq [
130
+ [:setup, shell, { foo: 42, bar: 24 }],
131
+ [:setup, shell, { foo: 42, bar: 24, test_var: 1 }],
132
+ [:setup, shell, { foo: 42, bar: 24, test_var: 2 }],
133
+ [:setup, shell, { foo: 42, bar: 24, test_var: 3 }]
134
+ ]
135
+ end
136
+ end
137
+
138
+ describe '#loop_once' do
139
+ context 'with fulfilled test' do
140
+ let(:test) do
141
+ proc do |result, vars, output|
142
+ called << [:test, self, result, vars, output]
143
+ !result
144
+ end
145
+ end
146
+ it 'goes to next challenge' do
147
+ expect { shell.loop_once }.to match_stdout('Success!')
148
+ expect(called).to eq [
149
+ [:setup, shell, { foo: 42, bar: 24 }],
150
+ [:test, shell, false, { foo: 42, bar: 24, test_var: 1 }, ''],
151
+ [:setup, shell, { foo: 42, bar: 24, test_var: 1 }]
152
+ ]
153
+ expect(shell.challenge).to eq b
154
+ end
155
+ end
156
+ context 'with failed test' do
157
+ it 'does not go to next challenge' do
158
+ expect { shell.loop_once }.to match_stdout('')
159
+ expect(called).to eq [
160
+ [:setup, shell, { foo: 42, bar: 24 }],
161
+ [:test, shell, false, { foo: 42, bar: 24, test_var: 1 }, '']
162
+ ]
163
+ expect(shell.challenge).to eq a
164
+ end
165
+ end
166
+ end
167
+
168
+ describe '#level' do
169
+ it 'returns current level\'s challenges' do
170
+ expect(shell.level).to eq [a, b]
171
+ end
172
+ end
173
+
174
+ describe '#challenge' do
175
+ it 'returns current challenge' do
176
+ is_expected.to eq a
177
+ end
178
+ end
179
+
180
+ describe '#help_challenge' do
181
+ it 'prints help' do
182
+ expect { shell.help_challenge }.to match_stdout('a')
183
+ end
184
+ end
185
+
186
+ context 'without challenge' do
187
+ let(:levels) { [] }
188
+
189
+ describe '#loop_once' do
190
+ it { expect { shell.loop_once }.to throw_symbol(:ripl_exit) }
191
+ end
192
+
193
+ describe '#level' do
194
+ it { expect(shell.level).to eq nil }
195
+ end
196
+
197
+ describe '#challenge' do
198
+ it { is_expected.to eq nil }
199
+ end
200
+
201
+ describe '#help_challenge' do
202
+ it { expect { shell.help_challenge }.to match_stdout('') }
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'stringio'
4
+ $LOAD_PATH << '../lib/tryruby'
5
+
6
+ RSpec.configure do |c|
7
+ c.color = true
8
+ c.formatter = :documentation
9
+ c.tty = true
10
+ end
11
+
12
+ # mtm @ http://stackoverflow.com/questions/6372763/rspec-how-do-i-write-a-test-that-expects-certain-output-but-doesnt-care-about
13
+ RSpec::Matchers.define :match_stdout do |check|
14
+ @capture = nil
15
+
16
+ match do |block|
17
+ begin
18
+ stdout_saved = $stdout
19
+ $stdout = StringIO.new
20
+ block.call
21
+ ensure
22
+ @capture = $stdout
23
+ $stdout = stdout_saved
24
+ end
25
+
26
+ @capture.string.match check
27
+ end
28
+
29
+ failure_message do
30
+ "expected to #{description}"
31
+ end
32
+ failure_message_when_negated do
33
+ "expected not to #{description}"
34
+ end
35
+ description do
36
+ "match [#{check}] on stdout [#{@capture.string}]"
37
+ end
38
+
39
+ def supports_block_expectations?
40
+ true
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/tryruby/tutorial'
3
+
4
+ describe Tryruby::Tutorial do
5
+ subject { described_class.new }
6
+
7
+ describe '#[]' do
8
+ it { expect(subject[0]).to eq nil }
9
+ end
10
+
11
+ describe '#each' do
12
+ it 'returns Enumerator without block' do
13
+ expect(subject.each.class).to be Enumerator
14
+ end
15
+ it 'iterates through levels' do
16
+ yielded = []
17
+ subject.each { |i| yielded << i }
18
+ expect(yielded).to eq []
19
+ end
20
+ end
21
+
22
+ describe '#length' do
23
+ it { expect(subject.length).to eq 0 }
24
+ end
25
+
26
+ describe '#commands' do
27
+ it 'return Commands module' do
28
+ expect(subject.commands).to eq described_class::Commands
29
+ end
30
+ end
31
+
32
+ context 'subclass' do
33
+ # Tutorial subclass
34
+ class TestTutorial < described_class
35
+ # Test commands
36
+ module Commands
37
+ def test
38
+ 'test'
39
+ end
40
+ end
41
+ level do
42
+ end
43
+ end
44
+
45
+ subject { TestTutorial.new }
46
+
47
+ describe '#[]' do
48
+ it { expect(subject[0].class).to eq Tryruby::Level }
49
+ end
50
+
51
+ describe '#each' do
52
+ it 'returns Enumerator without block' do
53
+ expect(subject.each.class).to be Enumerator
54
+ end
55
+ it 'iterates through levels' do
56
+ yielded = []
57
+ subject.each { |i| yielded << i.class }
58
+ expect(yielded).to eq [Tryruby::Level]
59
+ end
60
+ end
61
+
62
+ describe '#length' do
63
+ it { expect(subject.length).to eq 1 }
64
+ end
65
+
66
+ describe '#commands' do
67
+ it 'return Commands module' do
68
+ expect(subject.commands).to eq TestTutorial::Commands
69
+ expect(subject.commands.instance_methods).to eq [:test]
70
+ expect(described_class.new.commands.instance_methods).to eq []
71
+ end
72
+ end
73
+ end
74
+ end