daigaku 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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