daigaku 0.2.0 → 1.0.0

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 (88) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +7 -4
  3. data/CODE_OF_CONDUCT.md +77 -0
  4. data/README.md +11 -11
  5. data/bin/daigaku +6 -2
  6. data/daigaku.gemspec +22 -26
  7. data/lib/daigaku.rb +0 -1
  8. data/lib/daigaku/chapter.rb +3 -4
  9. data/lib/daigaku/coloring.rb +22 -27
  10. data/lib/daigaku/configuration.rb +25 -28
  11. data/lib/daigaku/congratulator.rb +17 -5
  12. data/lib/daigaku/course.rb +9 -8
  13. data/lib/daigaku/exceptions.rb +0 -2
  14. data/lib/daigaku/generator.rb +13 -15
  15. data/lib/daigaku/github_client.rb +5 -5
  16. data/lib/daigaku/loadable.rb +23 -14
  17. data/lib/daigaku/loading/chapters.rb +0 -2
  18. data/lib/daigaku/loading/courses.rb +0 -2
  19. data/lib/daigaku/loading/units.rb +0 -2
  20. data/lib/daigaku/markdown.rb +1 -0
  21. data/lib/daigaku/markdown/printer.rb +89 -0
  22. data/lib/daigaku/markdown/ruby_doc.rb +15 -15
  23. data/lib/daigaku/solution.rb +23 -15
  24. data/lib/daigaku/storeable.rb +11 -12
  25. data/lib/daigaku/task.rb +1 -1
  26. data/lib/daigaku/terminal.rb +3 -4
  27. data/lib/daigaku/terminal/cli.rb +8 -8
  28. data/lib/daigaku/terminal/courses.rb +22 -19
  29. data/lib/daigaku/terminal/output.rb +46 -53
  30. data/lib/daigaku/terminal/setup.rb +13 -18
  31. data/lib/daigaku/terminal/solutions.rb +27 -32
  32. data/lib/daigaku/terminal/welcome.rb +9 -11
  33. data/lib/daigaku/test.rb +7 -10
  34. data/lib/daigaku/test_result.rb +54 -21
  35. data/lib/daigaku/unit.rb +2 -4
  36. data/lib/daigaku/version.rb +1 -1
  37. data/lib/daigaku/views.rb +29 -33
  38. data/lib/daigaku/views/chapters_menu.rb +16 -20
  39. data/lib/daigaku/views/courses_menu.rb +12 -15
  40. data/lib/daigaku/views/main_menu.rb +23 -23
  41. data/lib/daigaku/views/menu.rb +14 -18
  42. data/lib/daigaku/views/splash.rb +11 -13
  43. data/lib/daigaku/views/subscriber.rb +38 -0
  44. data/lib/daigaku/views/task_view.rb +97 -80
  45. data/lib/daigaku/views/top_bar.rb +4 -10
  46. data/lib/daigaku/views/units_menu.rb +16 -21
  47. data/lib/daigaku/window.rb +12 -70
  48. data/spec/daigaku/chapter_spec.rb +23 -18
  49. data/spec/daigaku/coloring_spec.rb +0 -1
  50. data/spec/daigaku/configuration_spec.rb +54 -50
  51. data/spec/daigaku/congratulator_spec.rb +11 -8
  52. data/spec/daigaku/course_spec.rb +75 -52
  53. data/spec/daigaku/generator_spec.rb +24 -25
  54. data/spec/daigaku/github_client_spec.rb +17 -18
  55. data/spec/daigaku/loading/chapters_spec.rb +2 -3
  56. data/spec/daigaku/loading/courses_spec.rb +2 -3
  57. data/spec/daigaku/loading/units_spec.rb +4 -5
  58. data/spec/daigaku/markdown/ruby_doc_spec.rb +12 -6
  59. data/spec/daigaku/reference_solution_spec.rb +8 -10
  60. data/spec/daigaku/solution_spec.rb +21 -22
  61. data/spec/daigaku/storeable_spec.rb +12 -10
  62. data/spec/daigaku/task_spec.rb +3 -4
  63. data/spec/daigaku/terminal/cli_spec.rb +29 -21
  64. data/spec/daigaku/terminal/courses_spec.rb +104 -99
  65. data/spec/daigaku/terminal/output_spec.rb +44 -39
  66. data/spec/daigaku/terminal/setup_spec.rb +1 -3
  67. data/spec/daigaku/terminal/solutions_spec.rb +0 -2
  68. data/spec/daigaku/terminal/welcome_spec.rb +0 -2
  69. data/spec/daigaku/terminal_spec.rb +5 -7
  70. data/spec/daigaku/test_example_spec.rb +16 -14
  71. data/spec/daigaku/test_result_spec.rb +21 -25
  72. data/spec/daigaku/test_spec.rb +11 -12
  73. data/spec/daigaku/unit_spec.rb +24 -27
  74. data/spec/daigaku/views/chapters_menu_spec.rb +0 -1
  75. data/spec/daigaku/views/courses_menu_spec.rb +0 -1
  76. data/spec/daigaku/views/menu_spec.rb +1 -2
  77. data/spec/daigaku/views/task_view_spec.rb +0 -2
  78. data/spec/daigaku/views/units_menu_spec.rb +0 -1
  79. data/spec/daigaku/views_spec.rb +0 -1
  80. data/spec/daigaku_spec.rb +9 -12
  81. data/spec/path_helpers_spec.rb +11 -12
  82. data/spec/resource_helpers_spec.rb +11 -12
  83. data/spec/spec_helper.rb +3 -4
  84. data/spec/support/macros/content_helpers.rb +16 -17
  85. data/spec/support/macros/mock_helpers.rb +6 -6
  86. data/spec/support/macros/path_helpers.rb +15 -15
  87. data/spec/support/macros/resource_helpers.rb +34 -35
  88. metadata +32 -44
@@ -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
@@ -1,21 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Loading::Units do
4
-
5
- let(:course_name) { course_dir_names.first }
4
+ let(:course_name) { course_dir_names.first }
6
5
  let(:chapter_path) { chapter_dirs(course_name).first }
7
6
  let(:chapter_name) { File.basename(chapter_path) }
8
7
 
9
8
  let(:subjects) { Daigaku::Loading::Units.load(chapter_path) }
10
9
 
11
- it "has the prescribed number of units" do
10
+ it 'has the prescribed number of units' do
12
11
  units_count = available_units(course_name, chapter_name).count
13
12
  expect(subjects.count).to eq units_count
14
13
  end
15
14
 
16
- it "loads the available units" do
15
+ it 'loads the available units' do
17
16
  subjects.each_with_index do |unit, index|
18
17
  expect(unit.title).to eq unit_titles[index]
19
18
  end
20
19
  end
21
- end
20
+ end
@@ -1,18 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Markdown::RubyDoc do
4
-
5
- [:parse].each do |class_method|
6
- it "responds to #{class_method}" do
7
- expect(Daigaku::Markdown::RubyDoc).to respond_to class_method
8
- end
4
+ it 'responds to .parse' do
5
+ expect(Daigaku::Markdown::RubyDoc).to respond_to :parse
9
6
  end
10
7
 
11
8
  def parse(text)
12
9
  Daigaku::Markdown::RubyDoc.parse(text)
13
10
  end
14
11
 
15
- describe '::parse' do
12
+ describe '.parse' do
16
13
  context 'for a text containing a core doc markup' do
17
14
  let(:base_url) { "http://ruby-doc.org/core-#{RUBY_VERSION}" }
18
15
 
@@ -56,6 +53,15 @@ describe Daigaku::Markdown::RubyDoc do
56
53
  expect(parse(markdown)).to eq "#{base_url}/Enumerator/Lazy.html#method-i-flat_map"
57
54
  end
58
55
 
56
+ it 'returns the right link for an instance method not starting with word characters' do
57
+ markdown = '(ruby-doc core: Array#<<)'
58
+ expect(parse(markdown)).to eq "#{base_url}/Array.html#method-i-3C-3C"
59
+ end
60
+
61
+ it 'returns the right link for an instance method with regex characters' do
62
+ markdown = '(ruby-doc core: Array#any?)'
63
+ expect(parse(markdown)).to eq "#{base_url}/Array.html#method-i-any-3F"
64
+ end
59
65
  end
60
66
 
61
67
  context 'for a text containing a stdlib doc markup' do
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::ReferenceSolution do
4
-
5
4
  it { is_expected.to respond_to :code }
6
5
  it { is_expected.to respond_to :path }
7
6
  it { is_expected.to respond_to :code_lines }
@@ -13,27 +12,26 @@ describe Daigaku::ReferenceSolution do
13
12
 
14
13
  subject { Daigaku::ReferenceSolution.new(unit_path) }
15
14
 
16
- it "has the prescribed path" do
15
+ it 'has the prescribed path' do
17
16
  path = File.join(unit_path, reference_solution_name)
18
17
  expect(subject.path).to eq path
19
18
  end
20
19
 
21
- describe "#code" do
22
- it "has the prescribed code" do
20
+ describe '#code' do
21
+ it 'has the prescribed code' do
23
22
  expect(subject.code).to eq solution_content
24
23
  end
25
24
 
26
- it "returns an empty string if the code is not available" do
25
+ it 'returns an empty string if the code is not available' do
27
26
  subject.instance_variable_set(:@code, nil)
28
- expect(subject.code).to eq ""
27
+ expect(subject.code).to eq ''
29
28
  end
30
29
  end
31
30
 
32
-
33
- describe "#code_lines" do
34
- it "returns the code split into lines" do
31
+ describe '#code_lines' do
32
+ it 'returns the code split into lines' do
35
33
  lines = ['muffin = "sweet"', 'hamburger = "mjummy"']
36
- allow(subject).to receive(:code) { lines.join("\n") }
34
+ allow(subject).to receive(:code).and_return(lines.join("\n"))
37
35
 
38
36
  expect(subject.code_lines).to eq lines
39
37
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Solution do
4
-
5
4
  it { is_expected.to respond_to :code }
6
5
  it { is_expected.to respond_to :path }
7
6
  it { is_expected.to respond_to :verify! }
@@ -14,39 +13,39 @@ describe Daigaku::Solution do
14
13
  end
15
14
 
16
15
  let(:solution_path) { all_solution_file_paths.first }
17
- let(:unit_path) { all_unit_dirs.first }
16
+ let(:unit_path) { all_unit_dirs.first }
18
17
 
19
18
  subject { Daigaku::Solution.new(unit_path) }
20
19
 
21
- it "has the prescribed solution path from the given unit path" do
20
+ it 'has the prescribed solution path from the given unit path' do
22
21
  expect(subject.path).to eq solution_path
23
22
  end
24
23
 
25
- it "has the prescribed code" do
24
+ it 'has the prescribed code' do
26
25
  expect(subject.code).to eq solution_content
27
26
  end
28
27
 
29
- it "loads the verified state from the store on creation" do
28
+ it 'loads the verified state from the store on creation' do
30
29
  Daigaku::Solution.new(unit_path).verify!
31
30
  solution = Daigaku::Solution.new(unit_path)
32
31
 
33
32
  expect(solution).to be_verified
34
33
  end
35
34
 
36
- describe "#store_key" do
37
- it "returns the appropriate key string for the solution" do
38
- key = "verified/course_a/chapter_a/unit_a"
35
+ describe '#store_key' do
36
+ it 'returns the appropriate key string for the solution' do
37
+ key = 'verified/course_a/chapter_a/unit_a'
39
38
  expect(subject.store_key).to eq key
40
39
  end
41
40
  end
42
41
 
43
- context "Verification" do
44
- describe "#verify!" do
45
- it "returns a TestResult" do
42
+ context 'Verification' do
43
+ describe '#verify!' do
44
+ it 'returns a TestResult' do
46
45
  expect(subject.verify!).to be_a Daigaku::TestResult
47
46
  end
48
47
 
49
- it "sets @verified true if Test passed" do
48
+ it 'sets @verified true if Test passed' do
50
49
  QuickStore.store.set(subject.store_key, false)
51
50
  solution = Daigaku::Solution.new(unit_path)
52
51
 
@@ -55,32 +54,32 @@ describe Daigaku::Solution do
55
54
  expect(solution.instance_variable_get(:@verified)).to be_truthy
56
55
  end
57
56
 
58
- it "sets the solution's state in the store to verified if passed" do
57
+ it 'sets the solutions state in the store to verified if passed' do
59
58
  subject.verify!
60
59
  mastered = QuickStore.store.get(subject.store_key)
61
60
 
62
61
  expect(mastered).to be_truthy
63
62
  end
64
63
 
65
- it "sets the solution's state in the store to unverified unless passed" do
66
- subject.instance_variable_set(:@code, 'puts "I ❤ Daigaku!"')
64
+ it 'sets the solutions state in the store to unverified unless passed' do
65
+ allow(File).to receive(:read).and_return('puts "I ❤ Daigaku!"')
66
+ QuickStore.store.set(subject.store_key, true)
67
+
67
68
  subject.verify!
68
69
  mastered = QuickStore.store.get(subject.store_key)
69
-
70
70
  expect(mastered).to be_falsey
71
71
  end
72
72
  end
73
73
 
74
- describe "#verified?" do
75
- it "is false by default" do
76
- expect(subject.verified?).to be_falsey
74
+ describe '#verified?' do
75
+ it 'is false by default' do
76
+ expect(subject.verified?).to be false
77
77
  end
78
78
 
79
- it "returns true if #verify! passed" do
79
+ it 'returns true if #verify! passed' do
80
80
  subject.verify!
81
- expect(subject.verified?).to be_truthy
81
+ expect(subject.verified?).to be true
82
82
  end
83
83
  end
84
84
  end
85
-
86
85
  end
@@ -1,35 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Storeable do
4
-
5
- it "responds to ::key" do
4
+ it 'responds to .key' do
6
5
  expect(Daigaku::Storeable).to respond_to :key
7
6
  end
8
7
 
9
- describe '::key' do
10
- it "creates a store key from the given string" do
8
+ describe '.key' do
9
+ it 'creates a store key from the given string' do
11
10
  key = Daigaku::Storeable.key('1-_Raw content-Title')
12
11
  expect(key).to eq 'raw_content_title'
13
12
  end
14
13
 
15
- it "creates a cleaned up store key from a given path string" do
14
+ it 'creates a cleaned up store key from a given path string' do
16
15
  key = Daigaku::Storeable.key('path/to/the/1-_Raw content string')
17
16
  expect(key).to eq 'path/to/the/raw_content_string'
18
17
  end
19
18
 
20
- it "creates a prefixed key when a prefix option is given" do
19
+ it 'creates a prefixed key when a prefix option is given' do
21
20
  key = Daigaku::Storeable.key('1-_Raw content-Title', prefix: 'courses')
22
21
  expect(key).to eq 'courses/raw_content_title'
23
22
  end
24
23
 
25
- it "creates a suffixed key if a suffix option is given" do
24
+ it 'creates a suffixed key if a suffix option is given' do
26
25
  key = Daigaku::Storeable.key('1-_Raw content-Title', suffix: '1-author')
27
26
  expect(key).to eq 'raw_content_title/author'
28
27
  end
29
28
 
30
- it "creates a multi suffixed key if a suffixes option is given" do
31
- key = Daigaku::Storeable.key('1-_Raw content-Title', suffixes: ['meta', '1-author'] )
29
+ it 'creates a multi suffixed key if a suffixes option is given' do
30
+ suffixes = ['meta', '1-author']
31
+ title = '1-_Raw content-Title'
32
+ key = Daigaku::Storeable.key(title, suffixes: suffixes)
33
+
32
34
  expect(key).to eq 'raw_content_title/meta/author'
33
35
  end
34
36
  end
35
- end
37
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Task do
4
-
5
4
  it { is_expected.to respond_to :markdown }
6
5
  it { is_expected.to respond_to :path }
7
6
 
@@ -12,12 +11,12 @@ describe Daigaku::Task do
12
11
 
13
12
  subject { Daigaku::Task.new(unit_path) }
14
13
 
15
- it "has the prescribed path" do
14
+ it 'has the prescribed path' do
16
15
  path = File.join(unit_path, task_name)
17
16
  expect(subject.path).to eq path
18
17
  end
19
18
 
20
- it "has the prescribed markdown" do
19
+ it 'has the prescribed markdown' do
21
20
  expect(subject.markdown).to eq task_file_content
22
21
  end
23
- end
22
+ end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Terminal::CLI do
4
+ before { suppress_print_out }
4
5
 
5
6
  it { is_expected.to be_a Thor }
6
7
  it { is_expected.to respond_to :about }
@@ -11,40 +12,47 @@ describe Daigaku::Terminal::CLI do
11
12
  it { is_expected.to respond_to :solutions }
12
13
  it { is_expected.to respond_to :setup }
13
14
 
14
- describe "#learn" do
15
- it "starts the daigaku terminal app if there are courses" do
16
- allow(Daigaku::Loading::Courses).to receive(:load) { [1] }
17
- allow(Daigaku).to receive(:start) { true }
18
- expect(Daigaku).to receive(:start)
15
+ describe '#learn' do
16
+ before { allow(Daigaku).to receive(:start).and_return(true) }
19
17
 
20
- subject.learn
18
+ context 'if there are courses' do
19
+ before do
20
+ allow(Daigaku::Loading::Courses).to receive(:load).and_return([1])
21
+ end
22
+
23
+ it 'starts the daigaku terminal app' do
24
+ expect(Daigaku).to receive(:start)
25
+ subject.learn
26
+ end
21
27
  end
22
28
 
23
- it "does not start the daigaku terminal app if there are no courses" do
24
- suppress_print_out
25
- allow(Daigaku::Loading::Courses).to receive(:load) { [] }
26
- allow(Daigaku).to receive(:start) { true }
27
- expect(Daigaku).not_to receive(:start)
29
+ context 'if there are no courses' do
30
+ before do
31
+ allow(Daigaku::Loading::Courses).to receive(:load).and_return([])
32
+ end
28
33
 
29
- subject.learn
34
+ it 'does not start the daigaku terminal app' do
35
+ expect(Daigaku).not_to receive(:start)
36
+ subject.learn
37
+ end
30
38
  end
31
39
  end
32
40
 
33
- describe "#welcome" do
34
- it "runs the welcome routine" do
35
- allow(Daigaku::Terminal::Welcome).to receive(:run) { true }
41
+ describe '#welcome' do
42
+ it 'runs the welcome routine' do
43
+ allow(Daigaku::Terminal::Welcome).to receive(:run).and_return(true)
36
44
  expect(Daigaku::Terminal::Welcome).to receive(:run).once
37
-
38
45
  subject.welcome
39
46
  end
40
47
  end
41
48
 
42
- describe "#scaffold" do
43
- it "runs the scaffolding" do
44
- allow($stdout).to receive(:puts) {}
45
- allow_any_instance_of(Daigaku::Generator).to receive(:scaffold) { true }
46
- expect_any_instance_of(Daigaku::Generator).to receive(:scaffold).once
49
+ describe '#scaffold' do
50
+ it 'runs the scaffolding' do
51
+ allow_any_instance_of(Daigaku::Generator)
52
+ .to receive(:scaffold)
53
+ .and_return(true)
47
54
 
55
+ expect_any_instance_of(Daigaku::Generator).to receive(:scaffold).once
48
56
  subject.scaffold
49
57
  end
50
58
  end
@@ -1,102 +1,104 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Daigaku::Terminal::Courses do
4
-
5
4
  before { suppress_print_out }
6
5
 
7
6
  it { is_expected.to be_a Thor }
8
7
 
9
- describe "commands" do
10
- [:list, :download].each do |method|
11
- it { is_expected.to respond_to method }
12
- end
8
+ describe 'commands' do
9
+ it { is_expected.to respond_to :list }
10
+ it { is_expected.to respond_to :download }
13
11
  end
14
12
 
15
- describe "#download" do
13
+ describe '#download' do
16
14
  before do
17
15
  Daigaku.config.courses_path = local_courses_path
18
16
 
19
- @zip_file_name = "repo.zip"
20
- @file_content = prepare_download(@zip_file_name)
21
- @url = "https://example.com/#{@zip_file_name}"
17
+ @zip_file_name = 'repo.zip'
18
+ @file_content = prepare_download(@zip_file_name)
19
+ @url = "https://example.com/#{@zip_file_name}"
22
20
 
23
21
  stub_request(:get, @url)
24
- .with(headers: {
25
- 'Accept' => '*/*',
26
- 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
27
- 'User-Agent' => 'Ruby'
28
- })
29
- .to_return(status: 200, body: @file_content, headers: {})
30
-
31
- stub_request(:get, "https://api.github.com/repos/daigaku-ruby/Get_started_with_Ruby")
22
+ .with(
23
+ headers: {
24
+ 'Accept' => '*/*',
25
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
26
+ 'User-Agent' => 'Ruby'
27
+ }
28
+ ).to_return(status: 200, body: @file_content, headers: {})
29
+
30
+ stub_request(:get, 'https://api.github.com/repos/daigaku-ruby/Get_started_with_Ruby')
32
31
  .with(headers: { 'Accept' => '*/*', 'User-Agent' => 'Ruby' })
33
- .to_return(status: 200, body: "{}", headers: {})
32
+ .to_return(status: 200, body: '{}', headers: {})
34
33
  end
35
34
 
36
35
  after { cleanup_download(@zip_file_name) }
37
36
 
38
- it "downloads the file from a given url" do
39
- expect{ subject.download(@url) }.not_to raise_error
37
+ it 'downloads the file from a given url' do
38
+ expect { subject.download(@url) }.not_to raise_error
40
39
  end
41
40
 
42
- it "uses Courses.unzip to unzip the course" do
41
+ it 'uses Courses.unzip to unzip the course' do
43
42
  expect(Daigaku::Course).to receive(:unzip).once
44
43
  subject.download(@url)
45
44
  end
46
45
 
47
- it "creates a new courses folder in the daigaku courses directory" do
46
+ it 'creates a new courses folder in the daigaku courses directory' do
48
47
  target_path = File.join(Daigaku.config.courses_path, File.basename(course_dirs.first))
49
48
  dirs = Dir[File.join(Daigaku.config.courses_path, '**')]
50
49
  expect(dirs.include?(target_path)).to be_truthy
51
50
  end
52
51
 
53
- it "raises an error if param is no url" do
52
+ it 'raises an error if param is no url' do
54
53
  expect(subject).to receive(:say_warning)
55
54
  subject.download('no-url')
56
55
  end
57
56
 
58
- it "raises an error if param is no url to a zip file" do
57
+ it 'raises an error if param is no url to a zip file' do
59
58
  expect(subject).to receive(:say_warning)
60
59
  subject.download('http://exmaple.com/something-else')
61
60
  end
62
61
 
63
- describe "stores download data:" do
62
+ describe 'stores download data:' do
64
63
  before do
65
- @github_url = "https://github.com/user/course_a/archive/master.zip"
64
+ @github_url = 'https://github.com/user/course_a/archive/master.zip'
66
65
 
67
66
  stub_request(:get, @github_url)
68
- .with(headers: {
69
- 'Accept' => '*/*',
70
- 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
71
- 'User-Agent' => 'Ruby'
72
- })
73
- .to_return(status: 200, body: @file_content, headers: {})
74
-
75
- stub_request(:get, "https://api.github.com/repos/course_a/repo")
67
+ .with(
68
+ headers: {
69
+ 'Accept' => '*/*',
70
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
71
+ 'User-Agent' => 'Ruby'
72
+ }
73
+ ).to_return(status: 200, body: @file_content, headers: {})
74
+
75
+ stub_request(:get, 'https://api.github.com/repos/course_a/repo')
76
76
  .with(headers: { 'Accept' => '*/*', 'User-Agent' => 'Ruby' })
77
- .to_return(status: 200, body: "{}", headers: {})
77
+ .to_return(status: 200, body: '{}', headers: {})
78
78
  end
79
79
 
80
- it "stores the course's author for courses from Github" do
80
+ it 'stores the courses author for courses from Github' do
81
81
  subject.download(@github_url)
82
82
  store_key = 'courses/course_a/author'
83
83
  expect(QuickStore.store.get(store_key)).to eq 'user'
84
84
  end
85
85
 
86
- it "stores the course's repo for courses from Github" do
86
+ it 'stores the courses repo for courses from Github' do
87
87
  subject.download(@github_url)
88
88
  store_key = 'courses/course_a/github'
89
89
  expect(QuickStore.store.get(store_key)).to eq 'user/course_a'
90
90
  end
91
91
 
92
- it "stores the downloading timestamp" do
92
+ it 'stores the downloading timestamp' do
93
93
  time = Time.now
94
- allow(Time).to receive(:now) { time }
94
+ allow(Time).to receive(:now).and_return(time)
95
95
  subject.download(@url)
96
- expect(QuickStore.store.get('courses/course_a/updated_at')).to eq time.to_s
96
+
97
+ updated_at = QuickStore.store.get('courses/course_a/updated_at')
98
+ expect(updated_at).to eq time.to_s
97
99
  end
98
100
 
99
- it "stores the course's download url" do
101
+ it 'stores the courses download url' do
100
102
  subject.download(@url)
101
103
  expect(QuickStore.store.get('courses/course_a/url')).to eq @url
102
104
  end
@@ -107,44 +109,46 @@ describe Daigaku::Terminal::Courses do
107
109
  before do
108
110
  Daigaku.config.courses_path = local_courses_path
109
111
 
110
- @zip_file_name = "repo.zip"
111
- @file_content = prepare_download(@zip_file_name)
112
- @url = "https://example.com/#{@zip_file_name}"
112
+ @zip_file_name = 'repo.zip'
113
+ @file_content = prepare_download(@zip_file_name)
114
+ @url = "https://example.com/#{@zip_file_name}"
113
115
 
114
116
  stub_request(:get, @url)
115
- .with(headers: {
116
- 'Accept' => '*/*',
117
- 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
118
- 'User-Agent' => 'Ruby'
119
- })
120
- .to_return(status: 200, body: @file_content, headers: {})
121
-
122
- stub_request(:get, "https://api.github.com/repos/daigaku-ruby/Get_started_with_Ruby")
117
+ .with(
118
+ headers: {
119
+ 'Accept' => '*/*',
120
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
121
+ 'User-Agent' => 'Ruby'
122
+ }
123
+ ).to_return(status: 200, body: @file_content, headers: {})
124
+
125
+ stub_request(:get, 'https://api.github.com/repos/daigaku-ruby/Get_started_with_Ruby')
123
126
  .with(headers: { 'Accept' => '*/*', 'User-Agent' => 'Ruby' })
124
- .to_return(status: 200, body: "{}", headers: {})
127
+ .to_return(status: 200, body: '{}', headers: {})
125
128
 
126
- allow(subject).to receive(:download) { true }
127
- allow(Daigaku::GithubClient).to receive(:updated?) { |attr| true }
129
+ allow(subject).to receive(:download).and_return(true)
130
+ allow(Daigaku::GithubClient).to receive(:updated?).and_return(true)
128
131
  end
129
132
 
130
133
  after { cleanup_download(@zip_file_name) }
131
134
 
132
- it "updates a course that is not from Github on each call" do
135
+ it 'updates a course that is not from Github on each call' do
133
136
  url = 'https://example.com/repo.zip'
134
137
  expect(subject).to receive(:download).with(url, 'updated').once
135
138
  subject.update('Course_A')
136
139
  end
137
140
 
138
- it "updates a course from Github if there are new contents" do
139
- url = "https://github.com/user/repo/archive/master.zip"
141
+ it 'updates a course from Github if there are new contents' do
142
+ url = 'https://github.com/user/repo/archive/master.zip'
140
143
 
141
144
  stub_request(:get, url)
142
- .with(headers: {
143
- 'Accept' => '*/*',
144
- 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
145
- 'User-Agent' => 'Ruby'
146
- })
147
- .to_return(status: 200, body: @file_content, headers: {})
145
+ .with(
146
+ headers: {
147
+ 'Accept' => '*/*',
148
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
149
+ 'User-Agent' => 'Ruby'
150
+ }
151
+ ).to_return(status: 200, body: @file_content, headers: {})
148
152
 
149
153
  QuickStore.store.set('courses/course_a/url', url)
150
154
 
@@ -152,17 +156,18 @@ describe Daigaku::Terminal::Courses do
152
156
  subject.update('Course_A')
153
157
  end
154
158
 
155
- it "does not update a course from Github if there are no new contents" do
156
- allow(Daigaku::GithubClient).to receive(:updated?) { false }
157
- url = "https://github.com/user/repo/archive/master.zip"
159
+ it 'does not update a course from Github if there are no new contents' do
160
+ allow(Daigaku::GithubClient).to receive(:updated?).and_return(false)
161
+ url = 'https://github.com/user/repo/archive/master.zip'
158
162
 
159
163
  stub_request(:get, url)
160
- .with(headers: {
161
- 'Accept' => '*/*',
162
- 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
163
- 'User-Agent' => 'Ruby'
164
- })
165
- .to_return(status: 200, body: @file_content, headers: {})
164
+ .with(
165
+ headers: {
166
+ 'Accept' => '*/*',
167
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
168
+ 'User-Agent' => 'Ruby'
169
+ }
170
+ ).to_return(status: 200, body: @file_content, headers: {})
166
171
 
167
172
  QuickStore.store.set('courses/course_a/url', url)
168
173
  QuickStore.store.set('courses/course_a/github', 'user/repo')
@@ -171,7 +176,7 @@ describe Daigaku::Terminal::Courses do
171
176
  subject.update('Course_A')
172
177
  end
173
178
 
174
- it "updates all courses if --all option is given" do
179
+ it 'updates all courses if --all option is given' do
175
180
  file_content = prepare_download(@zip_file_name, multiple_courses: true)
176
181
 
177
182
  stub_request(:get, @url)
@@ -183,7 +188,7 @@ describe Daigaku::Terminal::Courses do
183
188
  }
184
189
  ).to_return(status: 200, body: file_content, headers: {})
185
190
 
186
- allow(subject).to receive(:options) { { all: true } }
191
+ allow(subject).to receive(:options).and_return(all: true)
187
192
  allow(subject).to receive(:download).exactly(course_dirs.count).times
188
193
 
189
194
  subject.update
@@ -198,49 +203,49 @@ describe Daigaku::Terminal::Courses do
198
203
  allow(subject).to receive(:get).and_return('yes')
199
204
  end
200
205
 
201
- describe "confirmation" do
202
- it "is nessecary to delete all courses" do
203
- allow(subject).to receive(:options) { { all: true } }
206
+ describe 'confirmation' do
207
+ it 'is nessecary to delete all courses' do
208
+ allow(subject).to receive(:options).and_return(all: true)
204
209
  expect(subject).to receive(:get_confirm)
205
210
  subject.delete
206
211
  end
207
212
 
208
- it "is nessecary to delete a certain course" do
213
+ it 'is nessecary to delete a certain course' do
209
214
  expect(subject).to receive(:get_confirm)
210
215
  subject.delete(course_dir_names.first)
211
216
  end
212
217
  end
213
218
 
214
- context "when confirmed:" do
215
- it "deletes the given course" do
219
+ context 'when confirmed:' do
220
+ it 'deletes the given course' do
216
221
  expect(Dir.exist?(@course_path)).to be_truthy
217
222
  subject.delete(course_dir_names.first)
218
223
  expect(Dir.exist?(@course_path)).to be_falsey
219
224
  end
220
225
 
221
- it "deletes all courses with option --all" do
222
- allow(subject).to receive(:options) { { all: true } }
226
+ it 'deletes all courses with option --all' do
227
+ allow(subject).to receive(:options).and_return(all: true)
223
228
  expect(Dir.exist?(@course_path)).to be_truthy
224
229
  subject.delete
225
230
 
226
231
  course_dirs.each do |dir|
227
- expect(Dir.exist?(dir)).to be_falsey
232
+ expect(Dir.exist?(dir)).to be false
228
233
  end
229
234
  end
230
235
  end
231
236
 
232
- context "when not confirmed:" do
237
+ context 'when not confirmed:' do
233
238
  before { allow(subject).to receive(:get).and_return('no') }
234
239
 
235
- it "does not delete the given course" do
240
+ it 'does not delete the given course' do
236
241
  expect(Dir.exist?(@course_path)).to be_truthy
237
242
  subject.delete(course_dir_names.first)
238
243
  expect(Dir.exist?(@course_path)).to be_truthy
239
244
  end
240
245
 
241
- it "does not delete all courses" do
242
- allow(subject).to receive(:options) { { all: true } }
243
- expect(Dir.exist?(@course_path)).to be_truthy
246
+ it 'does not delete all courses' do
247
+ allow(subject).to receive(:options).and_return(all: true)
248
+ expect(Dir.exist?(@course_path)).to be true
244
249
  subject.delete
245
250
 
246
251
  course_dirs.each do |dir|
@@ -249,29 +254,30 @@ describe Daigaku::Terminal::Courses do
249
254
  end
250
255
  end
251
256
 
252
- describe "status information" do
253
- it "is printed when a certain course was deleted" do
257
+ describe 'status information' do
258
+ it 'is printed when a certain course was deleted' do
254
259
  expect(subject).to receive(:say_info)
255
260
  subject.delete(course_dir_names.first)
256
261
  end
257
262
 
258
- it "is printed when all courses were deleted" do
259
- allow(subject).to receive(:options) { { all: true } }
263
+ it 'is printed when all courses were deleted' do
264
+ allow(subject).to receive(:options).and_return(all: true)
260
265
  expect(subject).to receive(:say_info)
261
266
  subject.delete
262
267
  end
263
268
  end
264
269
 
265
- describe "QuickStore data" do
266
- it "is deleted for a certain course" do
270
+ describe 'QuickStore data' do
271
+ it 'is deleted for a certain course' do
267
272
  key = Daigaku::Storeable.key(course_dir_names.first, prefix: 'courses')
268
273
  QuickStore.store.set(key, 'some value')
269
274
  subject.delete(course_dir_names.first)
275
+
270
276
  expect(QuickStore.store.get(key)).to be_nil
271
277
  end
272
278
 
273
- it "is deleted for all courses when option --all is set" do
274
- allow(subject).to receive(:options) { { all: true } }
279
+ it 'is deleted for all courses when option --all is set' do
280
+ allow(subject).to receive(:options).and_return(all: true)
275
281
 
276
282
  keys = course_dir_names.map do |course_name|
277
283
  Daigaku::Storeable.key(course_name, prefix: 'courses')
@@ -283,10 +289,9 @@ describe Daigaku::Terminal::Courses do
283
289
 
284
290
  subject.delete
285
291
 
286
- course_dir_names.each_with_index do |course_name, index|
292
+ course_dir_names.each_with_index do |_, index|
287
293
  expect(QuickStore.store.get(keys[index])).to be_nil
288
294
  end
289
-
290
295
  end
291
296
  end
292
297
  end