daigaku 0.0.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 (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +5 -0
  5. data/README.md +62 -0
  6. data/Rakefile +2 -0
  7. data/bin/daigaku +12 -0
  8. data/daigaku.gemspec +37 -0
  9. data/lib/daigaku.rb +27 -0
  10. data/lib/daigaku/chapter.rb +23 -0
  11. data/lib/daigaku/configuration.rb +86 -0
  12. data/lib/daigaku/course.rb +23 -0
  13. data/lib/daigaku/database.rb +64 -0
  14. data/lib/daigaku/exceptions.rb +19 -0
  15. data/lib/daigaku/generator.rb +53 -0
  16. data/lib/daigaku/loadable.rb +23 -0
  17. data/lib/daigaku/loading/chapters.rb +9 -0
  18. data/lib/daigaku/loading/courses.rb +9 -0
  19. data/lib/daigaku/loading/units.rb +9 -0
  20. data/lib/daigaku/reference_solution.rb +10 -0
  21. data/lib/daigaku/solution.rb +42 -0
  22. data/lib/daigaku/task.rb +10 -0
  23. data/lib/daigaku/terminal.rb +11 -0
  24. data/lib/daigaku/terminal/cli.rb +59 -0
  25. data/lib/daigaku/terminal/courses.rb +114 -0
  26. data/lib/daigaku/terminal/output.rb +72 -0
  27. data/lib/daigaku/terminal/setup.rb +115 -0
  28. data/lib/daigaku/terminal/solutions.rb +46 -0
  29. data/lib/daigaku/terminal/texts/about.txt +19 -0
  30. data/lib/daigaku/terminal/texts/courses_empty.txt +3 -0
  31. data/lib/daigaku/terminal/texts/hint_course_download.txt +13 -0
  32. data/lib/daigaku/terminal/texts/welcome.txt +12 -0
  33. data/lib/daigaku/terminal/welcome.rb +98 -0
  34. data/lib/daigaku/test.rb +46 -0
  35. data/lib/daigaku/test_result.rb +69 -0
  36. data/lib/daigaku/unit.rb +28 -0
  37. data/lib/daigaku/version.rb +3 -0
  38. data/lib/daigaku/views.rb +59 -0
  39. data/lib/daigaku/views/chapters_menu.rb +91 -0
  40. data/lib/daigaku/views/courses_menu.rb +87 -0
  41. data/lib/daigaku/views/main_menu.rb +37 -0
  42. data/lib/daigaku/views/splash.rb +57 -0
  43. data/lib/daigaku/views/task_view.rb +206 -0
  44. data/lib/daigaku/views/top_bar.rb +48 -0
  45. data/lib/daigaku/views/units_menu.rb +92 -0
  46. data/lib/daigaku/window.rb +160 -0
  47. data/spec/daigaku/chapter_spec.rb +76 -0
  48. data/spec/daigaku/configuration_spec.rb +161 -0
  49. data/spec/daigaku/course_spec.rb +75 -0
  50. data/spec/daigaku/database_spec.rb +79 -0
  51. data/spec/daigaku/generator_spec.rb +82 -0
  52. data/spec/daigaku/loading/chapters_spec.rb +16 -0
  53. data/spec/daigaku/loading/courses_spec.rb +16 -0
  54. data/spec/daigaku/loading/units_spec.rb +21 -0
  55. data/spec/daigaku/reference_solution_spec.rb +23 -0
  56. data/spec/daigaku/solution_spec.rb +79 -0
  57. data/spec/daigaku/task_spec.rb +23 -0
  58. data/spec/daigaku/terminal/cli_spec.rb +51 -0
  59. data/spec/daigaku/terminal/courses_spec.rb +60 -0
  60. data/spec/daigaku/terminal/output_spec.rb +123 -0
  61. data/spec/daigaku/terminal/setup_spec.rb +10 -0
  62. data/spec/daigaku/terminal/solutions_spec.rb +8 -0
  63. data/spec/daigaku/terminal/welcome_spec.rb +12 -0
  64. data/spec/daigaku/terminal_spec.rb +14 -0
  65. data/spec/daigaku/test_example_spec.rb +54 -0
  66. data/spec/daigaku/test_result_spec.rb +81 -0
  67. data/spec/daigaku/test_spec.rb +48 -0
  68. data/spec/daigaku/unit_spec.rb +85 -0
  69. data/spec/daigaku/views/chapters_menu_spec.rb +8 -0
  70. data/spec/daigaku/views/courses_menu_spec.rb +8 -0
  71. data/spec/daigaku/views/task_view_spec.rb +7 -0
  72. data/spec/daigaku/views/units_menu_spec.rb +8 -0
  73. data/spec/daigaku/views_spec.rb +23 -0
  74. data/spec/daigaku_spec.rb +57 -0
  75. data/spec/path_helpers_spec.rb +60 -0
  76. data/spec/resource_helpers_spec.rb +33 -0
  77. data/spec/spec_helper.rb +28 -0
  78. data/spec/support/macros/content_helpers.rb +129 -0
  79. data/spec/support/macros/mock_helpers.rb +20 -0
  80. data/spec/support/macros/path_helpers.rb +133 -0
  81. data/spec/support/macros/resource_helpers.rb +119 -0
  82. data/spec/support/macros/test_helpers.rb +6 -0
  83. metadata +361 -0
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Terminal::Output do
4
+
5
+ subject do
6
+ require 'thor'
7
+ class Test < Thor
8
+ include Daigaku::Terminal::Output
9
+ end
10
+
11
+ Test.new
12
+ end
13
+
14
+ before do
15
+ allow($stdout).to receive(:puts) { |string| string }
16
+ allow($stdout).to receive(:print) { |string| string }
17
+ end
18
+
19
+ [
20
+ :say,
21
+ :empty_line,
22
+ :get,
23
+ :say_info,
24
+ :say_warning,
25
+ :get_command
26
+ ].each do |method|
27
+ it "has the private method #{method}" do
28
+ expect(subject.private_methods.include?(method)).to be_truthy
29
+ end
30
+ end
31
+
32
+ describe "::say" do
33
+ it "prints the prescribed output to the $stdout" do
34
+ line = "line"
35
+ expect($stdout).to receive(:puts).with("\t#{line}")
36
+ subject.send(:say, line)
37
+ end
38
+
39
+ it "adds the line start in case of multiline inputs" do
40
+ lines = "first line\nsecond line\nthird line\n"
41
+ out_lines = lines.split("\n").map {|l| "\t#{l}" }.join("\n")
42
+ expect($stdout).to receive(:puts).with(out_lines)
43
+ subject.send(:say, lines)
44
+ end
45
+ end
46
+
47
+ describe "::empty_line" do
48
+ it "prints an empty line to the $stdout" do
49
+ expect($stdout).to receive(:puts).with('')
50
+ subject.send(:empty_line)
51
+ end
52
+ end
53
+
54
+ describe "::get" do
55
+ it "prints a string to $stdout to get a line on $stdin" do
56
+ printed = 'printed'
57
+ received = 'received'
58
+
59
+ allow($stdin).to receive(:gets) { received }
60
+ expect($stdout).to receive(:print).with("\n\t#{printed} ")
61
+ expect($stdin).to receive(:gets)
62
+ subject.send(:get, printed)
63
+ end
64
+ end
65
+
66
+ describe "::say_info" do
67
+ it "prints the prescribed output to the $stdout" do
68
+ line = "line"
69
+ expect($stdout).to receive(:puts).exactly(4).times.with("")
70
+ expect($stdout).to receive(:puts).with("\t" + " ℹ #{line}".light_blue)
71
+ expect($stdout).to receive(:puts).twice.times.with("\t" + ('-' * 70).light_blue)
72
+ subject.send(:say_info, line)
73
+ end
74
+ end
75
+
76
+ describe "::say_warning" do
77
+ it "prints the prescribed output to the $stdout" do
78
+ line = "line"
79
+ expect($stdout).to receive(:puts).exactly(4).times.with("")
80
+ expect($stdout).to receive(:puts).with("\t" + "⚠ #{line}".light_red)
81
+ expect($stdout).to receive(:puts).twice.times.with("\t" + ('-' * 70).light_red)
82
+ subject.send(:say_warning, line)
83
+ end
84
+ end
85
+
86
+ describe "::get_command" do
87
+
88
+ before do
89
+ @correct_command = 'correct command'
90
+ @description = 'description'
91
+ allow($stdin).to receive(:gets).and_return(@correct_command)
92
+ allow(Kernel).to receive(:system) { '' }
93
+ end
94
+
95
+ it "prints a description" do
96
+ expect($stdout).to receive(:puts).once.with("\t#{@description}")
97
+ subject.send(:get_command, @correct_command, @description)
98
+ end
99
+
100
+ it "gets a command from the $stdin" do
101
+ expect($stdin).to receive(:gets)
102
+ subject.send(:get_command, @correct_command, @description)
103
+ end
104
+
105
+ context "with the right command typed in:" do
106
+ it "gets a specified command from the user" do
107
+ subject.send(:get_command, @correct_command, @description)
108
+ end
109
+ end
110
+
111
+ context "with a wrong command typed in:" do
112
+ it "writed a hint" do
113
+ wrong_command = 'wrong command'
114
+ error = "This was something else. Try \"#{@correct_command}\"."
115
+ allow($stdin).to receive(:gets).and_return(wrong_command, @correct_command)
116
+
117
+ expect($stdout).to receive(:puts).once.with("\t#{error}")
118
+ subject.send(:get_command, @correct_command, @description)
119
+ end
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Terminal::Setup do
4
+
5
+ it { is_expected.to be_a Thor }
6
+ it { is_expected.to respond_to :list }
7
+ it { is_expected.to respond_to :set }
8
+ it { is_expected.to respond_to :init }
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Terminal::Solutions do
4
+
5
+ it { is_expected.to be_a Thor }
6
+ it { is_expected.to respond_to :open }
7
+
8
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Terminal::Welcome do
4
+
5
+ [:run, :about].each do |method|
6
+ it "has the singleton method ::#{method}" do
7
+ singleton_methods = Daigaku::Terminal::Welcome.singleton_methods
8
+ expect(singleton_methods.include?(method)).to be_truthy
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Terminal do
4
+
5
+ it { is_expected.to respond_to :text }
6
+
7
+ describe "::load_text" do
8
+ it "loads a text from a file in the cli/texts" do
9
+ text = Daigaku::Terminal.text(:welcome)
10
+ expect(text).to be_a String
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::TestExample do
4
+
5
+ it { is_expected.to respond_to :description }
6
+ it { is_expected.to respond_to :status }
7
+ it { is_expected.to respond_to :message }
8
+
9
+ context "when passed:" do
10
+ let(:description) { test_passed_json_parsed[:examples].first[:description] }
11
+ let(:status) { test_passed_json_parsed[:examples].first[:status] }
12
+
13
+ subject { Daigaku::TestExample.new(description: description, status: status) }
14
+
15
+ it "has the prescribed description" do
16
+ expect(subject.description).to eq description
17
+ end
18
+
19
+ it "has the prescribed status" do
20
+ expect(subject.status).to eq status
21
+ end
22
+
23
+ it "has the prescribed message" do
24
+ expect(subject.message).to eq example_passed_message
25
+ end
26
+ end
27
+
28
+ context "when failed:" do
29
+ let(:description) { test_failed_json_parsed[:examples].first[:description] }
30
+ let(:status) { test_failed_json_parsed[:examples].first[:status] }
31
+ let(:message) { test_failed_json_parsed[:examples].first[:exception][:message] }
32
+
33
+ subject do
34
+ Daigaku::TestExample.new(
35
+ description: description,
36
+ status: status,
37
+ message: message
38
+ )
39
+ end
40
+
41
+ it "has the prescribed description" do
42
+ expect(subject.description).to eq description
43
+ end
44
+
45
+ it "has the prescribed status" do
46
+ expect(subject.status).to eq status
47
+ end
48
+
49
+ it "has the prescribed message" do
50
+ expect(subject.message).to eq message
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::TestResult do
4
+
5
+ subject { Daigaku::TestResult.new(test_passed_json) }
6
+
7
+ it { is_expected.to respond_to :example_count }
8
+ it { is_expected.to respond_to :failure_count }
9
+ it { is_expected.to respond_to :examples }
10
+ it { is_expected.to respond_to :passed? }
11
+ it { is_expected.to respond_to :summary }
12
+
13
+ context "with passed input:" do
14
+
15
+ subject { Daigaku::TestResult.new(test_passed_json) }
16
+
17
+ it "is marked passed" do
18
+ expect(subject.passed?).to be_truthy
19
+ end
20
+
21
+ it "has a default summary" do
22
+ expect(subject.summary).to eq test_passed_summary
23
+ end
24
+ end
25
+
26
+ context "with failed input:" do
27
+
28
+ subject { Daigaku::TestResult.new(test_failed_json) }
29
+
30
+ it "is not marked passed" do
31
+ expect(subject.passed?).to be_falsey
32
+ end
33
+
34
+ it "has the prescribed example count" do
35
+ example_count = test_failed_json_parsed[:summary][:example_count]
36
+ expect(subject.example_count).to eq example_count
37
+ end
38
+
39
+ it "has the prescribed failure count" do
40
+ failure_count = test_failed_json_parsed[:summary][:failure_count]
41
+ expect(subject.failure_count).to eq failure_count
42
+ end
43
+
44
+ describe "#examples" do
45
+ it "returns the prescribed number of examples" do
46
+ examples_count = test_failed_json_parsed[:examples].count
47
+ expect(subject.examples.count).to eq examples_count
48
+ end
49
+
50
+ it "returns examples of type Daigaku::TestExample" do
51
+ subject.examples.each do |example|
52
+ expect(example).to be_a Daigaku::TestExample
53
+ end
54
+ end
55
+
56
+ it "return examples with the prescribed info" do
57
+ subject.examples.each_with_index do |example, index|
58
+ description = test_failed_json_parsed[:examples][index][:full_description]
59
+ status = test_failed_json_parsed[:examples][index][:status]
60
+ exception = test_failed_json_parsed[:examples][index][:exception]
61
+ message = exception ? exception[:message] : example_passed_message
62
+
63
+ expect(example.description).to eq description
64
+ expect(example.status).to eq status
65
+ expect(example.message).to eq message
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "#summary" do
71
+ it "returns a string having all example infos" do
72
+ subject.examples.each do |example|
73
+ expect(subject.summary).to include example.description
74
+ expect(subject.summary).to include example.message
75
+ expect(subject.summary).to include example.status
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Test do
4
+
5
+ it { is_expected.to respond_to :path }
6
+ it { is_expected.to respond_to :run }
7
+
8
+ before(:all) do
9
+ prepare_solutions
10
+ Daigaku.config.solutions_path = solutions_basepath
11
+ end
12
+
13
+ let(:unit_path) { all_unit_dirs.first }
14
+ let(:test_path) { all_test_file_paths.first }
15
+
16
+ subject { Daigaku::Test.new(unit_path) }
17
+
18
+ it "has the appropriate path" do
19
+ expect(subject.path).to eq test_path
20
+ end
21
+
22
+ describe "#run" do
23
+ before do
24
+ course_name = course_dir_names.first
25
+ chapter_name = chapter_dir_names.first
26
+ unit_name = unit_dir_names.first
27
+ @code = available_solution(course_name, chapter_name, unit_name).code
28
+ end
29
+
30
+ it "returns a Daigaku::TestResult" do
31
+ expect(subject.run(@code)).to be_a Daigaku::TestResult
32
+ end
33
+
34
+ context "when passing" do
35
+ it "returns a passing result" do
36
+ expect(subject.run(@code).passed?).to be_truthy
37
+ end
38
+ end
39
+
40
+ context "when failing" do
41
+ it "returns a failing result" do
42
+ code = "print 'BYE WORLD'"
43
+ expect(subject.run(code).passed?).to be_falsey
44
+ end
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daigaku::Unit do
4
+
5
+ it { is_expected.to respond_to :title }
6
+ it { is_expected.to respond_to :task }
7
+ it { is_expected.to respond_to :solution }
8
+ it { is_expected.to respond_to :reference_solution }
9
+ it { is_expected.to respond_to :mastered? }
10
+
11
+ let(:course_name) { course_dir_names.first }
12
+ let(:chapter_name) { chapter_dir_names.first }
13
+ let(:unit_name) { unit_dir_names.first }
14
+
15
+ subject { Daigaku::Unit.new(unit_dirs(course_name).first[0]) }
16
+
17
+ it "has the prescribed title" do
18
+ expect(subject.title).to eq unit_titles.first
19
+ end
20
+
21
+ describe "#task" do
22
+ it "returns an object of type Daigaku::Task" do
23
+ expect(subject.task).to be_a Daigaku::Task
24
+ end
25
+
26
+ it "returns the unit's appropriate task" do
27
+ task = available_task(course_name, chapter_name, unit_name).first
28
+ expect(subject.task.markdown).to eq task.markdown
29
+ end
30
+
31
+ it "lazy-loads the task" do
32
+ expect(subject.instance_variable_get(:@task)).to be_nil
33
+ subject.task
34
+ expect(subject.instance_variable_get(:@task)).not_to be_nil
35
+ end
36
+ end
37
+
38
+ describe "#reference_solution" do
39
+ it "returns an object of type Daigaku::ReferenceSolution" do
40
+ expect(subject.reference_solution).to be_a Daigaku::ReferenceSolution
41
+ end
42
+
43
+ it "returns the units appropriate predefined reference solution" do
44
+ reference_solution = available_reference_solution(course_name,
45
+ chapter_name,
46
+ unit_name).first
47
+ expect(subject.reference_solution.code).to eq reference_solution.code
48
+ end
49
+
50
+ it "lazy-loads the reference solution" do
51
+ expect(subject.instance_variable_get(:@reference_solution)).to be_nil
52
+ subject.reference_solution
53
+ expect(subject.instance_variable_get(:@reference_solution)).not_to be_nil
54
+ end
55
+ end
56
+
57
+ describe "#solution" do
58
+ it "returns an object of type Daigaku::Solution" do
59
+ expect(subject.solution).to be_a Daigaku::Solution
60
+ end
61
+
62
+ it "returns the units appropriate solution provided by the user" do
63
+ expect(subject.solution.code).to eq available_solution(course_name,
64
+ chapter_name,
65
+ unit_name).code
66
+ end
67
+
68
+ it "lazy-loads the reference solution" do
69
+ expect(subject.instance_variable_get(:@solution)).to be_nil
70
+ subject.solution
71
+ expect(subject.instance_variable_get(:@solution)).not_to be_nil
72
+ end
73
+ end
74
+
75
+ describe "#mastered?" do
76
+ it "returns false by default" do
77
+ expect(subject.mastered?).to be_falsey
78
+ end
79
+
80
+ it "returns true if the solution has been verified" do
81
+ allow_any_instance_of(Daigaku::Solution).to receive(:verified?) { true }
82
+ expect(subject.mastered?).to be_truthy
83
+ end
84
+ end
85
+ end