belajar 0.1.1

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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +5 -0
  6. data/README.md +5 -0
  7. data/Rakefile +5 -0
  8. data/belajar.gemspec +38 -0
  9. data/bin/belajar +12 -0
  10. data/lib/belajar.rb +24 -0
  11. data/lib/belajar/chapter.rb +23 -0
  12. data/lib/belajar/configuration.rb +89 -0
  13. data/lib/belajar/congratulator.rb +13 -0
  14. data/lib/belajar/course.rb +80 -0
  15. data/lib/belajar/exceptions.rb +19 -0
  16. data/lib/belajar/generator.rb +60 -0
  17. data/lib/belajar/github_client.rb +30 -0
  18. data/lib/belajar/loadable.rb +23 -0
  19. data/lib/belajar/loading/chapters.rb +9 -0
  20. data/lib/belajar/loading/courses.rb +9 -0
  21. data/lib/belajar/loading/units.rb +9 -0
  22. data/lib/belajar/reference_solution.rb +18 -0
  23. data/lib/belajar/solution.rb +53 -0
  24. data/lib/belajar/storeable.rb +32 -0
  25. data/lib/belajar/task.rb +10 -0
  26. data/lib/belajar/terminal.rb +12 -0
  27. data/lib/belajar/terminal/cli.rb +59 -0
  28. data/lib/belajar/terminal/courses.rb +179 -0
  29. data/lib/belajar/terminal/output.rb +78 -0
  30. data/lib/belajar/terminal/setup.rb +115 -0
  31. data/lib/belajar/terminal/solutions.rb +46 -0
  32. data/lib/belajar/terminal/texts/about.txt +19 -0
  33. data/lib/belajar/terminal/texts/congratulations.txt +12 -0
  34. data/lib/belajar/terminal/texts/courses_empty.txt +3 -0
  35. data/lib/belajar/terminal/texts/hint_course_download.txt +13 -0
  36. data/lib/belajar/terminal/texts/welcome.txt +12 -0
  37. data/lib/belajar/terminal/welcome.rb +98 -0
  38. data/lib/belajar/test.rb +46 -0
  39. data/lib/belajar/test_result.rb +86 -0
  40. data/lib/belajar/unit.rb +28 -0
  41. data/lib/belajar/version.rb +3 -0
  42. data/lib/belajar/views.rb +51 -0
  43. data/lib/belajar/views/chapters_menu.rb +60 -0
  44. data/lib/belajar/views/courses_menu.rb +52 -0
  45. data/lib/belajar/views/main_menu.rb +37 -0
  46. data/lib/belajar/views/menu.rb +89 -0
  47. data/lib/belajar/views/splash.rb +57 -0
  48. data/lib/belajar/views/task_view.rb +236 -0
  49. data/lib/belajar/views/top_bar.rb +40 -0
  50. data/lib/belajar/views/units_menu.rb +61 -0
  51. data/lib/belajar/window.rb +215 -0
  52. data/spec/belajar/chapter_spec.rb +76 -0
  53. data/spec/belajar/configuration_spec.rb +161 -0
  54. data/spec/belajar/congratulator_spec.rb +24 -0
  55. data/spec/belajar/course_spec.rb +201 -0
  56. data/spec/belajar/generator_spec.rb +82 -0
  57. data/spec/belajar/github_client_spec.rb +53 -0
  58. data/spec/belajar/loading/chapters_spec.rb +16 -0
  59. data/spec/belajar/loading/courses_spec.rb +16 -0
  60. data/spec/belajar/loading/units_spec.rb +21 -0
  61. data/spec/belajar/reference_solution_spec.rb +41 -0
  62. data/spec/belajar/solution_spec.rb +86 -0
  63. data/spec/belajar/storeable_spec.rb +35 -0
  64. data/spec/belajar/task_spec.rb +23 -0
  65. data/spec/belajar/terminal/cli_spec.rb +51 -0
  66. data/spec/belajar/terminal/courses_spec.rb +293 -0
  67. data/spec/belajar/terminal/output_spec.rb +151 -0
  68. data/spec/belajar/terminal/setup_spec.rb +10 -0
  69. data/spec/belajar/terminal/solutions_spec.rb +8 -0
  70. data/spec/belajar/terminal/welcome_spec.rb +12 -0
  71. data/spec/belajar/terminal_spec.rb +24 -0
  72. data/spec/belajar/test_example_spec.rb +54 -0
  73. data/spec/belajar/test_result_spec.rb +91 -0
  74. data/spec/belajar/test_spec.rb +48 -0
  75. data/spec/belajar/unit_spec.rb +85 -0
  76. data/spec/belajar/views/chapters_menu_spec.rb +6 -0
  77. data/spec/belajar/views/courses_menu_spec.rb +6 -0
  78. data/spec/belajar/views/menu_spec.rb +19 -0
  79. data/spec/belajar/views/task_view_spec.rb +7 -0
  80. data/spec/belajar/views/units_menu_spec.rb +6 -0
  81. data/spec/belajar/views_spec.rb +21 -0
  82. data/spec/belajar_spec.rb +51 -0
  83. data/spec/path_helpers_spec.rb +60 -0
  84. data/spec/resource_helpers_spec.rb +33 -0
  85. data/spec/spec_helper.rb +28 -0
  86. data/spec/support/macros/content_helpers.rb +129 -0
  87. data/spec/support/macros/mock_helpers.rb +25 -0
  88. data/spec/support/macros/path_helpers.rb +139 -0
  89. data/spec/support/macros/resource_helpers.rb +157 -0
  90. data/spec/support/macros/test_helpers.rb +6 -0
  91. metadata +385 -0
@@ -0,0 +1,40 @@
1
+ module Belajar
2
+ module Views
3
+
4
+ class TopBar
5
+ include Curses
6
+
7
+ HEIGHT = 4
8
+
9
+ attr_reader :height, :width, :panel
10
+
11
+ def initialize(window, text = '')
12
+ @height = HEIGHT
13
+ @width = window.maxx
14
+ @panel = create_panel(window, @width, @height, text)
15
+ end
16
+
17
+ def show
18
+ @panel.refresh
19
+ end
20
+
21
+ private
22
+
23
+ def create_panel(window, width, height, text)
24
+ panel = window.subwin(height, window.maxx, 0, 0)
25
+
26
+ panel.setpos(1, 1)
27
+ panel.print_markdown(text)
28
+ panel.setpos(2, 1)
29
+ panel.clear_line(text: '_')
30
+
31
+ panel
32
+ end
33
+
34
+ def emphasized(panel, text)
35
+ panel.write(text, Window::COLOR_2)
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require 'belajar/views/menu'
2
+
3
+ module Belajar
4
+ module Views
5
+
6
+ class UnitsMenu < Menu
7
+
8
+ private
9
+
10
+ def before_enter(*args)
11
+ @course = args[0]
12
+ @chapter = args[1]
13
+ end
14
+
15
+ def before_reenter(*args)
16
+ @course = args[0]
17
+ @chapter = args[1]
18
+ @unit = args[2]
19
+
20
+ @position = @chapter.units.find_index(@unit)
21
+ end
22
+
23
+ def header_text
24
+ "*#{@course.title}* > *#{@chapter.title}* - available units:"
25
+ end
26
+
27
+ def interact_with(window)
28
+ while char = window.getch
29
+ case char
30
+ when KEY_UP
31
+ @position -= 1
32
+ when KEY_DOWN
33
+ @position += 1
34
+ when 10 # Enter
35
+ broadcast(:enter, @course, @chapter, models[@position])
36
+ return
37
+ when 263 # Backspace
38
+ broadcast(:reenter, @course, @chapter)
39
+ return
40
+ when 27 # ESC
41
+ exit
42
+ end
43
+
44
+ @position = items.length - 1 if @position < 0
45
+ @position = 0 if @position >= items.length
46
+ draw(window, @position)
47
+ end
48
+ end
49
+
50
+ def models
51
+ @chapter.units
52
+ end
53
+
54
+ def items
55
+ models.map(&:title)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,215 @@
1
+ require 'curses'
2
+ require 'cgi'
3
+
4
+ module Belajar
5
+ class Window < Curses::Window
6
+
7
+ COLOR_TEXT = Curses::COLOR_YELLOW unless defined? COLOR_TEXT
8
+ COLOR_TEXT_EMPHASIZE = Curses::COLOR_CYAN unless defined? COLOR_TEXT_EMPHASIZE
9
+ COLOR_HEADING = Curses::COLOR_WHITE unless defined? COLOR_HEADING
10
+ COLOR_RED = Curses::COLOR_BLUE unless defined? COLOR_RED
11
+ COLOR_GREEN = Curses::COLOR_MAGENTA unless defined? COLOR_GREEN
12
+ COLOR_YELLOW = Curses::COLOR_RED unless defined? COLOR_YELLOW
13
+
14
+ BACKGROUND = Curses::COLOR_WHITE unless defined? BACKGROUND
15
+ FONT = Curses::COLOR_BLACK unless defined? FONT
16
+ FONT_HEADING = Curses::COLOR_MAGENTA unless defined? FONT_HEADING
17
+ FONT_EMPHASIZE = Curses::COLOR_BLUE unless defined? FONT_EMPHASIZE
18
+ RED = Curses::COLOR_RED unless defined? RED
19
+ GREEN = Curses::COLOR_GREEN unless defined? GREEN
20
+ YELLOW = Curses::COLOR_YELLOW unless defined? YELLOW
21
+
22
+ def initialize(height = Curses.lines, width = Curses.cols, top = 0, left = 0)
23
+ super(height, width, top, left)
24
+ init_colors
25
+ end
26
+
27
+ def write(text, color = COLOR_TEXT, text_decoration = Curses::A_NORMAL )
28
+ self.attron(Curses.color_pair(color) | text_decoration) { self << text.to_s }
29
+ end
30
+
31
+ def emphasize(text, text_decoration = Curses::A_NORMAL)
32
+ write(text, Window::COLOR_TEXT_EMPHASIZE, text_decoration)
33
+ end
34
+
35
+ def heading(text, text_decoration = Curses::A_UNDERLINE)
36
+ write(text, Window::COLOR_HEADING, text_decoration)
37
+ end
38
+
39
+ def red(text, text_decoration = Curses::A_NORMAL, options = {})
40
+ colored(text, Window::COLOR_RED, text_decoration, options)
41
+ end
42
+
43
+ def yellow(text, text_decoration = Curses::A_NORMAL, options = {})
44
+ colored(text, Window::COLOR_YELLOW, text_decoration, options)
45
+ end
46
+
47
+ def green(text, text_decoration = Curses::A_NORMAL, options = {})
48
+ colored(text, Window::COLOR_GREEN, text_decoration, options)
49
+ end
50
+
51
+ def colored(text, color, text_decoration = Curses::A_NORMAL, options = {})
52
+ if options[:full_line]
53
+ clear_line(
54
+ color: color,
55
+ text_decoration: Curses::A_STANDOUT,
56
+ start_pos: 1,
57
+ end_pos: maxx - 2
58
+ )
59
+
60
+ prefix = ' '
61
+ end
62
+
63
+ write("#{prefix}#{text}", color, text_decoration)
64
+ end
65
+
66
+ # clear_line(options = {})
67
+ # options: [:color, :text_decoration, :start_pos, :end_pos]
68
+ def clear_line(options = {})
69
+ color = options[:color] || COLOR_TEXT
70
+ text_decoration = options[:text_decoration] || Curses::A_NORMAL
71
+ start = options[:start_pos] || 0
72
+ stop = options[:end_pos] || maxx
73
+
74
+ x = curx
75
+ setpos(cury, start)
76
+ write((options[:text] || ' ') * (stop - 1), color, text_decoration)
77
+ setpos(cury, x)
78
+ refresh
79
+ end
80
+
81
+ def print_indicator(object, text = ' ', text_decoration = Curses::A_STANDOUT)
82
+ if object.respond_to?(:mastered?) && object.respond_to?(:started?)
83
+ if object.mastered?
84
+ green(text, text_decoration)
85
+ write ' '
86
+ elsif object.started?
87
+ yellow(text, text_decoration)
88
+ write ' '
89
+ else
90
+ red(text, text_decoration)
91
+ write ' '
92
+ end
93
+ elsif object.respond_to?(:mastered?)
94
+ if object.mastered?
95
+ green(text, text_decoration)
96
+ write ' '
97
+ else
98
+ red(text, text_decoration)
99
+ write ' '
100
+ end
101
+ end
102
+ end
103
+
104
+ def print_markdown(text)
105
+ clear_line
106
+
107
+ h1 = /^\#{1}[^#]+/ # '# heading'
108
+ h2 = /^\#{2}[^#]+/ # '## sub heading'
109
+ bold = /(\*[^*]*\*)/ # '*text*'
110
+ line = /^-{3,}/ # '---' vertical line
111
+ code = /(\`*\`)/ # '`code line`'
112
+ ruby_doc_core = /(\(ruby-doc core:.*\))/ # '(ruby-doc core: Kernel#print)'
113
+ ruby_doc_stdlib = /(\(ruby-doc stdlib:.*\))/ # '(ruby-doc stdlib: CSV#Row::<<)'
114
+
115
+ case text
116
+ when h1
117
+ heading(text.gsub(/^#\s?/, ''))
118
+ when h2
119
+ text_decoration = Curses::A_UNDERLINE | Curses::A_NORMAL
120
+ emphasize(text.gsub(/^##\s?/, ''), text_decoration)
121
+ when (code || bold)
122
+ emphasized = false
123
+ highlighted = false
124
+
125
+ text.chars.each_with_index do |char, index|
126
+ if char == '*' && text[index - 1] != '\\'
127
+ emphasized = !emphasized
128
+ next
129
+ end
130
+
131
+ if char == '`'
132
+ highlighted = !highlighted
133
+ next
134
+ end
135
+
136
+ character = "#{text[index..(index + 1)]}" == '\\*' ? '' : char
137
+
138
+ if highlighted
139
+ red(character)
140
+ elsif emphasized
141
+ emphasize(character)
142
+ else
143
+ write(character)
144
+ end
145
+ end
146
+ when bold
147
+ text.chars.each_with_index do |char, index|
148
+ if char == '*' && text[index - 1] != '\\'
149
+ emphasized = !emphasized
150
+ next
151
+ end
152
+
153
+ character = "#{text[index..(index + 1)]}" == '\\*' ? '' : char
154
+ emphasized ? emphasize(character) : write(character)
155
+ end
156
+ when line
157
+ write('-' * (Curses.cols - 2))
158
+ when ruby_doc_core
159
+ capture = text.match(/\(ruby-doc core:\s?(.*)\)/).captures.first
160
+ write text.gsub(ruby_doc_core, ruby_doc_core_link(capture))
161
+ when ruby_doc_stdlib
162
+ capture = text.match(/\(ruby-doc stdlib:\s?(.*)\)/).captures.first
163
+ write text.gsub(ruby_doc_stdlib, ruby_doc_stdlib_link(capture))
164
+ else
165
+ write(text.gsub(/(\\#)/, '#'))
166
+ end
167
+ end
168
+
169
+ protected
170
+
171
+ def init_colors
172
+ Curses.start_color
173
+ Curses.init_pair(COLOR_TEXT, FONT, BACKGROUND)
174
+ Curses.init_pair(COLOR_TEXT_EMPHASIZE, FONT_EMPHASIZE, BACKGROUND)
175
+ Curses.init_pair(COLOR_HEADING, FONT_HEADING, BACKGROUND)
176
+ Curses.init_pair(COLOR_RED, RED, BACKGROUND)
177
+ Curses.init_pair(COLOR_GREEN, GREEN, BACKGROUND)
178
+ Curses.init_pair(COLOR_YELLOW, YELLOW, BACKGROUND)
179
+ end
180
+
181
+ private
182
+
183
+ def ruby_doc_core_link(text)
184
+ base_url = "http://ruby-doc.org/core-#{RUBY_VERSION}"
185
+ class_part = ruby_doc_class_parts(text).join('/')
186
+ method = ruby_doc_method(text)
187
+
188
+ "#{base_url}/#{class_part}.html#{method}"
189
+ end
190
+
191
+ def ruby_doc_stdlib_link(text)
192
+ base_url = "http://ruby-doc.org/stdlib-#{RUBY_VERSION}"
193
+ class_parts = ruby_doc_class_parts(text)
194
+ libdoc_part = "libdoc/#{class_parts.first.downcase}/rdoc"
195
+ method = ruby_doc_method(text)
196
+
197
+ "#{base_url}/#{libdoc_part}/#{class_parts.join('/')}.html#{method}"
198
+ end
199
+
200
+ def ruby_doc_class_parts(text)
201
+ parts = text.split(/::|#/)
202
+ parts[0..(parts.count > 1 ? -2 : -1)]
203
+ end
204
+
205
+ def ruby_doc_method(text)
206
+ parts = text.split(/::|#/)
207
+
208
+ if parts.count > 1
209
+ method_type = text.match(/#/) ? 'i' : 'c'
210
+ method_name = CGI.escape(parts.last.strip).gsub('%', '-').gsub(/\A-/, '')
211
+ "#method-#{method_type}-#{method_name}"
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Belajar::Chapter do
4
+
5
+ it { is_expected.to respond_to :title }
6
+ it { is_expected.to respond_to :units }
7
+ it { is_expected.to respond_to :path }
8
+
9
+ it { is_expected.to respond_to :mastered? }
10
+ it { is_expected.to respond_to :started? }
11
+
12
+ let(:chapter_path) { chapter_dirs(course_dir_names.first).first }
13
+
14
+ before(:all) do
15
+ prepare_solutions
16
+ Belajar.config.solutions_path = solutions_basepath
17
+ end
18
+
19
+ subject { Belajar::Chapter.new(chapter_path) }
20
+
21
+ it "has the prescribed title" do
22
+ expect(subject.title).to eq chapter_titles.first
23
+ end
24
+
25
+ it "has the prescribed path" do
26
+ expect(subject.path).to eq chapter_path
27
+ end
28
+
29
+ it "is not started by default" do
30
+ expect(subject.started?).to be_falsey
31
+ end
32
+
33
+ it "is not mastered by default" do
34
+ expect(subject.mastered?).to be_falsey
35
+ end
36
+
37
+ describe "#units" do
38
+ it "loads the prescribed number of units" do
39
+ course_name = course_dir_names.first
40
+ chapter_name = File.basename(chapter_path)
41
+ units_count = available_units(course_name, chapter_name).count
42
+ expect(subject.units.count).to eq units_count
43
+ end
44
+
45
+ it "lazy-loads the units" do
46
+ expect(subject.instance_variable_get(:@units)).to be_nil
47
+ subject.units
48
+ expect(subject.instance_variable_get(:@units)).not_to be_nil
49
+ end
50
+ end
51
+
52
+ describe "#started?" do
53
+ it "returns true if at least one unit has been verified" do
54
+ allow(subject.units.first).to receive(:mastered?) { true }
55
+ expect(subject.started?).to be true
56
+ end
57
+
58
+ it "returns false if no unit has been verified" do
59
+ allow_any_instance_of(Belajar::Unit).to receive(:mastered?) { false }
60
+ expect(subject.started?).to be false
61
+ end
62
+ end
63
+
64
+ describe "#mastered?" do
65
+ it "returns true if all units have been verified" do
66
+ subject.units.each { |unit| unit.solution.verify! }
67
+ expect(subject.mastered?).to be true
68
+ end
69
+
70
+ it "returns false unless all units have been verified" do
71
+ allow_any_instance_of(Belajar::Unit).to receive(:mastered?) { false }
72
+ allow(subject.units.first).to receive(:mastered?) { true }
73
+ expect(subject.mastered?).to be false
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ describe Belajar::Configuration do
4
+
5
+ subject { Belajar::Configuration.send(:new) }
6
+
7
+ it { is_expected.to respond_to :solutions_path }
8
+ it { is_expected.to respond_to :solutions_path= }
9
+ it { is_expected.to respond_to :courses_path }
10
+ it { is_expected.to respond_to :courses_path= }
11
+ it { is_expected.to respond_to :storage_file }
12
+ it { is_expected.to respond_to :save }
13
+ it { is_expected.to respond_to :import! }
14
+ it { is_expected.to respond_to :summary }
15
+
16
+ before do
17
+ subject.instance_variable_set(:@storage_file, local_storage_file)
18
+ end
19
+
20
+ describe "#courses_path" do
21
+ it "returns the appropriate initial local courses path" do
22
+ courses_path = File.expand_path('~/.belajar/courses', __FILE__)
23
+ expect(subject.courses_path).to eq courses_path
24
+ end
25
+
26
+ it "returns the appropriate set courses path" do
27
+ subject.courses_path = local_courses_path
28
+ expect(subject.courses_path).to eq local_courses_path
29
+ end
30
+ end
31
+
32
+ describe "#solutions_path=" do
33
+ it "raises an error if the given path is no existent dir" do
34
+ expect { subject.solutions_path = "no/existent/dir" }
35
+ .to raise_error(Belajar::ConfigurationError)
36
+ end
37
+ end
38
+
39
+ describe "#solutions_path" do
40
+ it "raises an error if not set" do
41
+ expect { subject.solutions_path }
42
+ .to raise_error(Belajar::ConfigurationError)
43
+ end
44
+
45
+ it "returns the solutions path if set" do
46
+ subject.solutions_path = test_basepath
47
+ expect { subject.solutions_path }.not_to raise_error
48
+ end
49
+ end
50
+
51
+ describe "#storage_path" do
52
+ it "returns the appropriate path to the storage file" do
53
+ expect(subject.storage_file).to eq local_storage_file
54
+ end
55
+ end
56
+
57
+ describe "#save" do
58
+ it "saves the configured courses path to the belajar store" do
59
+ subject.courses_path = local_courses_path
60
+ subject.save
61
+
62
+ expect(QuickStore.store.courses_path).to eq local_courses_path
63
+ end
64
+
65
+ it "saves the configured solution_path to the belajar store" do
66
+ path = File.join(test_basepath, 'test_solutions')
67
+ FileUtils.makedirs(path)
68
+ subject.solutions_path = path
69
+ subject.save
70
+
71
+ expect(QuickStore.store.solutions_path).to eq path
72
+ end
73
+
74
+ it "does not save the storage file path" do
75
+ subject.save
76
+ expect(QuickStore.store.storage_file).to be_nil
77
+ end
78
+ end
79
+
80
+ describe "#import!" do
81
+ context "with non-existent belajar store entries:" do
82
+ before do
83
+ FileUtils.rm(local_storage_file) if File.exist?(local_storage_file)
84
+ end
85
+
86
+ it "uses the default configuration" do
87
+ QuickStore.store.courses_path = nil
88
+ QuickStore.store.solutions_path = nil
89
+ subject.instance_variable_set(:@courses_path, local_courses_path)
90
+
91
+ loaded_config = subject.import!
92
+
93
+ expect(loaded_config.courses_path).to eq local_courses_path
94
+ expect { loaded_config.solutions_path }
95
+ .to raise_error Belajar::ConfigurationError
96
+ end
97
+ end
98
+
99
+ context "with existing belajar storage file:" do
100
+ it "returns a Belajar::Configuration" do
101
+ expect(subject.import!).to be_a Belajar::Configuration
102
+ end
103
+
104
+ it "loads the belajar store entries into the configuration" do
105
+ wanted_courses_path = "/courses/path"
106
+ wanted_solutions_path = solutions_basepath
107
+ temp_solutions_path = File.join(solutions_basepath, 'temp')
108
+ FileUtils.makedirs(wanted_solutions_path)
109
+ FileUtils.makedirs(temp_solutions_path)
110
+
111
+ # save wanted settings
112
+ subject.courses_path = wanted_courses_path
113
+ subject.solutions_path = wanted_solutions_path
114
+ subject.save
115
+
116
+ # overwrite in memory settings
117
+ subject.courses_path = '/some/other/path/'
118
+ subject.solutions_path = temp_solutions_path
119
+
120
+ # fetch stored settings
121
+ subject.import!
122
+ expect(File.exist?(local_storage_file)).to be_truthy
123
+ expect(subject.courses_path).to eq wanted_courses_path
124
+ expect(subject.solutions_path).to eq wanted_solutions_path
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#summary' do
130
+ before do
131
+ subject.courses_path = "wanted/courses/path"
132
+ subject.solutions_path = solutions_basepath
133
+ @summary = subject.summary
134
+ end
135
+
136
+ it "returns a string" do
137
+ expect(@summary).to be_a String
138
+ end
139
+
140
+ it "returns a string with all properties but @configuration_file" do
141
+ expect(@summary.lines.count).to eq subject.instance_variables.count - 1
142
+ end
143
+
144
+ it "returns a string including the courses path" do
145
+ expect(@summary =~ /courses path/).to be_truthy
146
+ end
147
+
148
+ it "returns a string including the courses path" do
149
+ expect(@summary =~ /solutions path/).to be_truthy
150
+ end
151
+ end
152
+
153
+ describe '#initial_course' do
154
+ it { is_expected.to respond_to :initial_course }
155
+
156
+ it "returns the initial course github repo partial path" do
157
+ expect(subject.initial_course).to eq 'wong-bejo/Get_started_with_Ruby'
158
+ end
159
+ end
160
+
161
+ end