daigaku 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -3
  3. data/README.md +1 -1
  4. data/daigaku.gemspec +23 -26
  5. data/lib/daigaku.rb +0 -1
  6. data/lib/daigaku/chapter.rb +3 -4
  7. data/lib/daigaku/coloring.rb +13 -13
  8. data/lib/daigaku/configuration.rb +25 -28
  9. data/lib/daigaku/congratulator.rb +17 -5
  10. data/lib/daigaku/course.rb +9 -8
  11. data/lib/daigaku/exceptions.rb +0 -2
  12. data/lib/daigaku/generator.rb +13 -13
  13. data/lib/daigaku/github_client.rb +4 -4
  14. data/lib/daigaku/loadable.rb +11 -15
  15. data/lib/daigaku/loading/chapters.rb +0 -2
  16. data/lib/daigaku/loading/courses.rb +0 -2
  17. data/lib/daigaku/loading/units.rb +0 -2
  18. data/lib/daigaku/markdown.rb +1 -0
  19. data/lib/daigaku/markdown/printer.rb +89 -0
  20. data/lib/daigaku/markdown/ruby_doc.rb +6 -8
  21. data/lib/daigaku/solution.rb +18 -15
  22. data/lib/daigaku/storeable.rb +11 -12
  23. data/lib/daigaku/task.rb +1 -1
  24. data/lib/daigaku/terminal.rb +3 -4
  25. data/lib/daigaku/terminal/cli.rb +6 -8
  26. data/lib/daigaku/terminal/courses.rb +19 -16
  27. data/lib/daigaku/terminal/output.rb +0 -2
  28. data/lib/daigaku/terminal/setup.rb +13 -18
  29. data/lib/daigaku/terminal/solutions.rb +27 -32
  30. data/lib/daigaku/terminal/welcome.rb +9 -11
  31. data/lib/daigaku/test.rb +7 -10
  32. data/lib/daigaku/test_result.rb +13 -16
  33. data/lib/daigaku/unit.rb +1 -3
  34. data/lib/daigaku/version.rb +1 -1
  35. data/lib/daigaku/views.rb +4 -3
  36. data/lib/daigaku/views/chapters_menu.rb +16 -20
  37. data/lib/daigaku/views/courses_menu.rb +12 -15
  38. data/lib/daigaku/views/main_menu.rb +23 -23
  39. data/lib/daigaku/views/menu.rb +9 -13
  40. data/lib/daigaku/views/splash.rb +11 -13
  41. data/lib/daigaku/views/subscriber.rb +38 -0
  42. data/lib/daigaku/views/task_view.rb +80 -78
  43. data/lib/daigaku/views/top_bar.rb +4 -10
  44. data/lib/daigaku/views/units_menu.rb +16 -21
  45. data/lib/daigaku/window.rb +12 -70
  46. data/spec/daigaku/chapter_spec.rb +23 -18
  47. data/spec/daigaku/coloring_spec.rb +0 -1
  48. data/spec/daigaku/configuration_spec.rb +54 -50
  49. data/spec/daigaku/congratulator_spec.rb +11 -8
  50. data/spec/daigaku/course_spec.rb +70 -51
  51. data/spec/daigaku/generator_spec.rb +24 -25
  52. data/spec/daigaku/github_client_spec.rb +17 -18
  53. data/spec/daigaku/loading/chapters_spec.rb +2 -3
  54. data/spec/daigaku/loading/courses_spec.rb +2 -3
  55. data/spec/daigaku/loading/units_spec.rb +4 -5
  56. data/spec/daigaku/markdown/ruby_doc_spec.rb +3 -6
  57. data/spec/daigaku/reference_solution_spec.rb +8 -10
  58. data/spec/daigaku/solution_spec.rb +18 -20
  59. data/spec/daigaku/storeable_spec.rb +12 -10
  60. data/spec/daigaku/task_spec.rb +3 -4
  61. data/spec/daigaku/terminal/cli_spec.rb +29 -21
  62. data/spec/daigaku/terminal/courses_spec.rb +104 -99
  63. data/spec/daigaku/terminal/output_spec.rb +44 -39
  64. data/spec/daigaku/terminal/setup_spec.rb +1 -3
  65. data/spec/daigaku/terminal/solutions_spec.rb +0 -2
  66. data/spec/daigaku/terminal/welcome_spec.rb +0 -2
  67. data/spec/daigaku/terminal_spec.rb +5 -7
  68. data/spec/daigaku/test_example_spec.rb +16 -14
  69. data/spec/daigaku/test_result_spec.rb +21 -25
  70. data/spec/daigaku/test_spec.rb +11 -12
  71. data/spec/daigaku/unit_spec.rb +24 -27
  72. data/spec/daigaku/views/chapters_menu_spec.rb +0 -1
  73. data/spec/daigaku/views/courses_menu_spec.rb +0 -1
  74. data/spec/daigaku/views/menu_spec.rb +1 -2
  75. data/spec/daigaku/views/task_view_spec.rb +0 -2
  76. data/spec/daigaku/views/units_menu_spec.rb +0 -1
  77. data/spec/daigaku/views_spec.rb +0 -1
  78. data/spec/daigaku_spec.rb +9 -12
  79. data/spec/path_helpers_spec.rb +11 -12
  80. data/spec/resource_helpers_spec.rb +11 -12
  81. data/spec/spec_helper.rb +3 -4
  82. data/spec/support/macros/content_helpers.rb +16 -17
  83. data/spec/support/macros/mock_helpers.rb +6 -6
  84. data/spec/support/macros/path_helpers.rb +15 -15
  85. data/spec/support/macros/resource_helpers.rb +34 -35
  86. metadata +12 -10
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Course do
4
-
5
4
  it { is_expected.to respond_to :title }
6
5
  it { is_expected.to respond_to :chapters }
7
6
  it { is_expected.to respond_to :path }
@@ -22,73 +21,82 @@ describe Daigaku::Course do
22
21
 
23
22
  subject { Daigaku::Course.new(course_path) }
24
23
 
25
- it "responds to ::unzip" do
24
+ it 'responds to .unzip' do
26
25
  expect(Daigaku::Course).to respond_to :unzip
27
26
  end
28
27
 
29
- it "has the prescribed title" do
28
+ it 'has the prescribed title' do
30
29
  expect(subject.title).to eq course_titles.first
31
30
  end
32
31
 
33
- it "has the prescribed path" do
32
+ it 'has the prescribed path' do
34
33
  expect(subject.path).to eq course_path
35
34
  end
36
35
 
37
- it "is not started by default" do
38
- expect(subject.started?).to be_falsey
36
+ it 'is not started by default' do
37
+ expect(subject.started?).to be false
39
38
  end
40
39
 
41
- it "is not mastered by default" do
42
- expect(subject.mastered?).to be_falsey
40
+ it 'is not mastered by default' do
41
+ expect(subject.mastered?).to be false
43
42
  end
44
43
 
45
- describe "#chapters" do
46
- it "loads the prescribed number of chapters" do
44
+ describe '#chapters' do
45
+ it 'loads the prescribed number of chapters' do
47
46
  expect(subject.chapters.count).to eq available_chapters(course_path).count
48
47
  end
49
48
 
50
- it "lazy-loads the chapters" do
49
+ it 'lazy-loads the chapters' do
51
50
  expect(subject.instance_variable_get(:@chapters)).to be_nil
52
51
  subject.chapters
53
52
  expect(subject.instance_variable_get(:@chapters)).not_to be_nil
54
53
  end
55
54
  end
56
55
 
57
- describe "#started?" do
58
- it "returns true if at least one chapter has been started" do
59
- allow(subject.chapters.first).to receive(:started?) { true }
56
+ describe '#started?' do
57
+ it 'returns true if at least one chapter has been started' do
58
+ allow(subject.chapters.first).to receive(:started?).and_return(true)
60
59
  expect(subject.started?).to be true
61
60
  end
62
61
 
63
- it "returns false if no chapter has been started" do
64
- allow_any_instance_of(Daigaku::Chapter).to receive(:started?) { false }
62
+ it 'returns false if no chapter has been started' do
63
+ allow_any_instance_of(Daigaku::Chapter)
64
+ .to receive(:started?)
65
+ .and_return(false)
66
+
65
67
  expect(subject.started?).to be false
66
68
  end
67
69
  end
68
70
 
69
- describe "#mastered?" do
70
- it "returns true if all chapters have been mastered" do
71
- allow_any_instance_of(Daigaku::Chapter).to receive(:mastered?) { true }
71
+ describe '#mastered?' do
72
+ it 'returns true if all chapters have been mastered' do
73
+ allow_any_instance_of(Daigaku::Chapter)
74
+ .to receive(:mastered?)
75
+ .and_return(true)
76
+
72
77
  expect(subject.mastered?).to be true
73
78
  end
74
79
 
75
- it "returns false unless all chapters have been mastered" do
76
- allow_any_instance_of(Daigaku::Chapter).to receive(:mastered?) { false }
77
- allow(subject.chapters.first).to receive(:mastered?) { true }
80
+ it 'returns false unless all chapters have been mastered' do
81
+ allow_any_instance_of(Daigaku::Chapter)
82
+ .to receive(:mastered?)
83
+ .and_return(false)
84
+
85
+ allow(subject.chapters.first).to receive(:mastered?).and_return(true)
78
86
  expect(subject.mastered?).to be false
79
87
  end
80
88
  end
81
89
 
82
- describe "#key" do
83
- it "returns the courses store key for the given key name" do
84
- allow(subject).to receive(:title) { '1-Course title' }
85
- key = "courses/course_title/some_key"
90
+ describe '#key' do
91
+ it 'returns the courses store key for the given key name' do
92
+ allow(subject).to receive(:title).and_return('1-Course title')
93
+ key = 'courses/course_title/some_key'
86
94
  expect(subject.key('1-some Key')).to eq key
87
95
  end
88
96
  end
89
97
 
90
- describe "#author" do
91
- it "returns the author of Github courses form the store" do
98
+ describe '#author' do
99
+ it 'returns the author of Github courses form the store' do
92
100
  author = 'author'
93
101
  QuickStore.store.set(subject.key(:author), author)
94
102
 
@@ -97,77 +105,83 @@ describe Daigaku::Course do
97
105
  end
98
106
  end
99
107
 
100
- describe "::unzip" do
108
+ describe '.unzip' do
101
109
  before do
102
110
  Daigaku.config.courses_path = local_courses_path
103
- @zip_file_name = "unzip/repo.zip"
111
+
112
+ @zip_file_name = 'unzip/repo.zip'
104
113
  @zip_file_path = File.join(courses_basepath, @zip_file_name)
105
- @file_content = prepare_download(@zip_file_name)
114
+ @file_content = prepare_download(@zip_file_name)
106
115
  end
107
116
 
108
117
  after do
109
118
  cleanup_download(@zip_file_name)
110
119
  dir = File.dirname(@zip_file_path)
111
- FileUtils.rm_r(dir) if Dir.exist?(dir)
120
+ remove_directory(dir)
112
121
  end
113
122
 
114
123
  def expect_course_dirs_exists_to_be(boolean)
115
124
  unit_dirs(course_dir_names.first).each do |chapter_dirs|
116
125
  chapter_dirs.each do |dir|
117
- path = [dir.split('/')[0..-4], 'unzip', dir.split('/')[-3..-1]].join('/')
126
+ path = [
127
+ dir.split('/')[0..-4],
128
+ 'unzip',
129
+ dir.split('/')[-3..-1]
130
+ ].join('/')
131
+
118
132
  expect(Dir.exist?(path)).to be boolean
119
133
  end
120
134
  end
121
135
  end
122
136
 
123
- it "unzips a course zip file" do
137
+ it 'unzips a course zip file' do
124
138
  expect_course_dirs_exists_to_be false
125
139
  Daigaku::Course.unzip(@zip_file_path)
126
140
  expect_course_dirs_exists_to_be true
127
141
  end
128
142
 
129
- it "returns the unzipped course" do
130
- dir = course_dirs.first
131
- path = File.join(File.dirname(dir), 'unzip', File.basename(dir))
143
+ it 'returns the unzipped course' do
144
+ dir = course_dirs.first
145
+ path = File.join(File.dirname(dir), 'unzip', File.basename(dir))
132
146
  course = Daigaku::Course.new(path)
133
147
 
134
- expect(Daigaku::Course.unzip(@zip_file_path).to_json).to eql course.to_json
148
+ expect(Daigaku::Course.unzip(@zip_file_path).to_json).to eq course.to_json
135
149
  end
136
150
 
137
- it "removes the zip file" do
151
+ it 'removes the zip file' do
138
152
  expect(File.exist?(@zip_file_path)).to be true
139
153
  Daigaku::Course.unzip(@zip_file_path)
140
154
  expect(File.exist?(@zip_file_path)).to be false
141
155
  end
142
156
 
143
- context "with the same course already available:" do
157
+ context 'with the same course already available' do
144
158
  before do
145
159
  dir = course_dirs.first
146
160
  @path = File.join(File.dirname(dir), 'unzip', File.basename(dir))
147
161
  @old_chapter_dir = File.join(@path, 'Old_chapter')
148
162
 
149
- FileUtils.mkdir_p(@old_chapter_dir)
163
+ create_directory(@old_chapter_dir)
150
164
  end
151
165
 
152
- it "overwrites all chapters" do
166
+ it 'overwrites all chapters' do
153
167
  expect(Dir.exist?(@old_chapter_dir)).to be true
154
168
  Daigaku::Course.unzip(@zip_file_path)
155
169
  expect(Dir.exist?(@old_chapter_dir)).to be false
156
170
  end
157
171
 
158
- context "if an errior occurs" do
172
+ context 'if an error occurs' do
159
173
  before do
160
174
  allow_any_instance_of(Zip::File)
161
- .to receive(:extract) { raise Exception.new }
175
+ .to receive(:extract) { raise StandardError.new, 'error' }
162
176
  end
163
177
 
164
- it "restores an old state if an error occurs" do
178
+ it 'restores an old state' do
165
179
  Daigaku::Course.unzip(@zip_file_path)
166
180
  expect(Dir.exist?(@old_chapter_dir)).to be true
167
181
  expect(Dir.exist?("#{@path}_old")).to be false
168
182
  end
169
183
 
170
- it "keeps the zip file if an error occurs" do
184
+ it 'keeps the zip file' do
171
185
  expect(File.exist?(@zip_file_path)).to be true
172
186
  Daigaku::Course.unzip(@zip_file_path)
173
187
  expect(File.exist?(@zip_file_path)).to be true
@@ -175,12 +189,12 @@ describe Daigaku::Course do
175
189
  end
176
190
  end
177
191
 
178
- context "with the github_repo option:" do
192
+ context 'with the github_repo option:' do
179
193
  before { @github_course_dir = prepare_github_course }
180
- after { FileUtils.rm_r(@github_course_dir) }
194
+ after { remove_directory(@github_course_dir) }
181
195
 
182
- it "removes the '-master' from the root directory" do
183
- zip_file_name = "unzip/repo-master.zip"
196
+ it 'removes the "-master" from the root directory' do
197
+ zip_file_name = 'unzip/repo-master.zip'
184
198
  zip_file_path = File.join(courses_basepath, zip_file_name)
185
199
  prepare_github_download(zip_file_name)
186
200
 
@@ -189,7 +203,12 @@ describe Daigaku::Course do
189
203
 
190
204
  unit_dirs("#{course_dir_names.first}-master").each do |chapter_dirs|
191
205
  chapter_dirs.each do |dir|
192
- path = [dir.split('/')[0..-4], 'unzip', dir.split('/')[-3..-1]].join('/')
206
+ path = [
207
+ dir.split('/')[0..-4],
208
+ 'unzip',
209
+ dir.split('/')[-3..-1]
210
+ ].join('/')
211
+
193
212
  expect(Dir.exist?(path)).to be false
194
213
  end
195
214
  end
@@ -1,57 +1,57 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Generator do
4
-
5
- it { is_expected.to respond_to :scaffold }
6
- it { is_expected.to respond_to :prepare }
7
-
8
4
  subject { Daigaku::Generator.new }
9
5
 
10
6
  before do
11
7
  Daigaku.config.instance_variable_set(:@storage_file, local_storage_file)
12
8
  end
13
9
 
14
- describe "#scaffold" do
15
- it "creates blank solution files for all available units" do
10
+ it { is_expected.to respond_to :scaffold }
11
+ it { is_expected.to respond_to :prepare }
12
+
13
+ describe '#scaffold' do
14
+ it 'creates blank solution files for all available units' do
16
15
  subject.scaffold(courses_basepath, solutions_basepath)
17
16
 
18
17
  all_solution_file_paths.each do |file_path|
19
- expect(File.exist?(file_path)).to be_truthy
18
+ expect(File.exist?(file_path)).to be true
20
19
  end
21
20
  end
22
21
  end
23
22
 
24
- describe "#prepare" do
25
- context "with an existing solutions_path" do
23
+ describe '#prepare' do
24
+ context 'with an existing solutions_path' do
26
25
  before do
27
26
  Daigaku.configure do |config|
28
27
  config.solutions_path = solutions_basepath
29
- config.courses_path = local_courses_path
28
+ config.courses_path = local_courses_path
30
29
  end
31
30
 
32
31
  subject.prepare
33
32
  end
34
33
 
35
- it "generates a '<basepath>/.daigaku/daigaku.db.yml' file" do
36
- expect(File.exist?(local_storage_file)).to be_truthy
34
+ it 'generates a "<basepath>/.daigaku/daigaku.db.yml" file' do
35
+ expect(File.exist?(local_storage_file)).to be true
37
36
  end
38
37
 
39
- it "generates a '<basepath>/.daigaku/courses' folder" do
40
- expect(Dir.exist?(local_courses_path)).to be_truthy
38
+ it 'generates a "<basepath>/.daigaku/courses" folder' do
39
+ expect(Dir.exist?(local_courses_path)).to be true
41
40
  end
42
41
 
43
- it "saves the current config info" do
44
- expect(File.exist?(local_storage_file)).to be_truthy
42
+ it 'saves the current config info' do
43
+ expect(File.exist?(local_storage_file)).to be true
45
44
  expect(QuickStore.store.courses_path).to eq local_courses_path
46
45
  expect(QuickStore.store.solutions_path).to eq solutions_basepath
47
46
  end
48
47
  end
49
48
 
50
- context "with a missing solutions_path" do
49
+ context 'with a missing solutions_path' do
51
50
  before do
52
- FileUtils.rm_r(solutions_basepath) if Dir.exist?(solutions_basepath)
53
- base_path = File.dirname(Daigaku.config.courses_path)
54
- @solutions_path = File.join(base_path, 'solutions')
51
+ remove_directory(solutions_basepath)
52
+
53
+ base_path = File.dirname(Daigaku.config.courses_path)
54
+ @solutions_path = File.join(base_path, 'solutions')
55
55
 
56
56
  Daigaku.config.instance_variable_set(:@solutions_path, nil)
57
57
  Daigaku.configure { |config| config.courses_path = local_courses_path }
@@ -59,24 +59,23 @@ describe Daigaku::Generator do
59
59
  subject.prepare
60
60
  end
61
61
 
62
- it "generates a 'solutions' path on the base directory as the courses" do
62
+ it 'generates a "solutions" path on the base directory as the courses' do
63
63
  expect(Dir.exist?(@solutions_path)).to be_truthy
64
64
  end
65
65
 
66
- it "generates a '<basepath>/.daigaku/daigaku.db.yml' file" do
66
+ it 'generates a "<basepath>/.daigaku/daigaku.db.yml" file' do
67
67
  expect(File.exist?(local_storage_file)).to be_truthy
68
68
  end
69
69
 
70
- it "generates a '<basepath>/.daigaku/courses' folder" do
70
+ it 'generates a "<basepath>/.daigaku/courses" folder' do
71
71
  expect(Dir.exist?(local_courses_path)).to be_truthy
72
72
  end
73
73
 
74
- it "saves the current config info" do
74
+ it 'saves the current config info' do
75
75
  expect(File.exist?(local_storage_file)).to be_truthy
76
76
  expect(QuickStore.store.courses_path).to eq local_courses_path
77
77
  expect(QuickStore.store.solutions_path).to eq @solutions_path
78
78
  end
79
79
  end
80
80
  end
81
-
82
81
  end
@@ -1,19 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::GithubClient do
4
-
5
- describe "#master_zip_url" do
6
- it "returns the url to the master zip file for the given github repo" do
7
- url = "https://github.com/a/b/archive/master.zip"
4
+ describe '#master_zip_url' do
5
+ it 'returns the url to the master zip file for the given github repo' do
6
+ url = 'https://github.com/a/b/archive/master.zip'
8
7
  expect(Daigaku::GithubClient.master_zip_url('a/b')).to eq url
9
8
  end
10
9
  end
11
10
 
12
- describe "#updated_at" do
13
- it "fetches the updated_at timestamp from the Github API" do
14
- expected_timestamp = "2015-10-21T12:00:00Z"
11
+ describe '#updated_at' do
12
+ it 'fetches the updated_at timestamp from the Github API' do
13
+ expected_timestamp = '2015-10-21T12:00:00Z'
15
14
  response = { updated_at: expected_timestamp }.to_json
16
- url = "https://api.github.com/repos/a/b"
15
+ url = 'https://api.github.com/repos/a/b'
17
16
 
18
17
  stub_request(:get, url)
19
18
  .with(headers: { 'Accept' => '*/*', 'User-Agent' => 'Ruby' })
@@ -25,29 +24,29 @@ describe Daigaku::GithubClient do
25
24
  end
26
25
  end
27
26
 
28
- describe "#updated?" do
27
+ describe '#updated?' do
29
28
  before do
30
- @received_timestamp = "2015-10-21T12:00:00Z"
29
+ @received_timestamp = '2015-10-21T12:00:00Z'
31
30
  response = { updated_at: @received_timestamp }.to_json
32
- url = "https://api.github.com/repos/a/b"
31
+ url = 'https://api.github.com/repos/a/b'
33
32
 
34
33
  stub_request(:get, url)
35
34
  .with(headers: { 'Accept' => '*/*', 'User-Agent' => 'Ruby' })
36
35
  .to_return(status: 200, body: response, headers: {})
37
36
  end
38
37
 
39
- it "returns true if content was pushed to the Github repo" do
40
- QuickStore.store.set('courses/b/updated_at', "2015-10-21T11:59:59Z")
41
- expect(Daigaku::GithubClient.updated?('a/b')).to be_truthy
38
+ it 'returns true if content was pushed to the Github repo' do
39
+ QuickStore.store.set('courses/b/updated_at', '2015-10-21T11:59:59Z')
40
+ expect(Daigaku::GithubClient.updated?('a/b')).to be true
42
41
  end
43
42
 
44
- it "returns false if no content was pushed to the Github repo" do
43
+ it 'returns false if no content was pushed to the Github repo' do
45
44
  QuickStore.store.set('courses/b/updated_at', @received_timestamp)
46
- expect(Daigaku::GithubClient.updated?('a/b')).to be_falsey
45
+ expect(Daigaku::GithubClient.updated?('a/b')).to be false
47
46
  end
48
47
 
49
- it "returns false if param is nil" do
50
- expect(Daigaku::GithubClient.updated?(nil)).to be_falsey
48
+ it 'returns false if param is nil' do
49
+ expect(Daigaku::GithubClient.updated?(nil)).to be false
51
50
  end
52
51
  end
53
52
  end
@@ -1,14 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Loading::Chapters do
4
-
5
4
  let(:subjects) { Daigaku::Loading::Chapters.load(course_dirs.first) }
6
5
 
7
- it "has the prescribed number of chapters" do
6
+ it 'has the prescribed number of chapters' do
8
7
  expect(subjects.count).to eq available_chapters(course_dirs.first).count
9
8
  end
10
9
 
11
- it "loads the available chapters" do
10
+ it 'loads the available chapters' do
12
11
  subjects.each_with_index do |chapter, index|
13
12
  expect(chapter.title).to eq chapter_titles[index]
14
13
  end
@@ -1,14 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Loading::Courses do
4
-
5
4
  let(:subjects) { Daigaku::Loading::Courses.load(courses_basepath) }
6
5
 
7
- it "has the prescribed number of courses" do
6
+ it 'has the prescribed number of courses' do
8
7
  expect(subjects.count).to eq available_courses.count
9
8
  end
10
9
 
11
- it "loads the available courses" do
10
+ it 'loads the available courses' do
12
11
  subjects.each_with_index do |course, index|
13
12
  expect(course.title).to eq course_titles[index]
14
13
  end