Pickaxe 0.4.4 → 0.5.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.
- data/lib/pickaxe.rb +1 -1
- data/lib/pickaxe/cli.rb +3 -2
- data/lib/pickaxe/color.rb +2 -1
- data/lib/pickaxe/extensions.rb +5 -1
- data/lib/pickaxe/main.rb +14 -7
- data/lib/pickaxe/shell.rb +2 -1
- data/lib/pickaxe/test.rb +71 -23
- metadata +4 -4
data/lib/pickaxe.rb
CHANGED
data/lib/pickaxe/cli.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
|
3
|
-
options = {}
|
3
|
+
options = { :extension => "txt" }
|
4
4
|
OptionParser.new do |opts|
|
5
5
|
opts.banner = <<END_OF_BANNER
|
6
6
|
Usage:
|
@@ -10,7 +10,8 @@ Uses given paths (files or directories) to generate a test from *.txt files.
|
|
10
10
|
END_OF_BANNER
|
11
11
|
|
12
12
|
opts.separator ""
|
13
|
-
opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION
|
13
|
+
opts.on("-e", "--ext [EXTENSION]", "Use files with given EXTENSION " +
|
14
|
+
"(default 'txt')") do |extension|
|
14
15
|
options[:extension] = extension
|
15
16
|
end
|
16
17
|
|
data/lib/pickaxe/color.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Pickaxe
|
2
|
-
# Extracted from
|
2
|
+
# Extracted from
|
3
|
+
# https://github.com/wycats/thor/blob/master/lib/thor/shell/color.rb
|
3
4
|
module Color
|
4
5
|
# Embed in a String to clear all previous ANSI sequences.
|
5
6
|
CLEAR = "\e[0m"
|
data/lib/pickaxe/extensions.rb
CHANGED
@@ -7,7 +7,11 @@ class String
|
|
7
7
|
options.reverse_merge!(:line_width => Pickaxe::Shell.dynamic_width || 80)
|
8
8
|
|
9
9
|
self.split("\n").collect do |line|
|
10
|
-
line.length > options[:line_width]
|
10
|
+
if line.length > options[:line_width]
|
11
|
+
line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip
|
12
|
+
else
|
13
|
+
line
|
14
|
+
end
|
11
15
|
end * "\n"
|
12
16
|
end
|
13
17
|
|
data/lib/pickaxe/main.rb
CHANGED
@@ -22,8 +22,9 @@ END_OF_TEST
|
|
22
22
|
|
23
23
|
puts "! Hit Control-D to end test.\n\n"
|
24
24
|
|
25
|
-
@logger = Logger.new(File.open('answers.log',
|
26
|
-
|
25
|
+
@logger = Logger.new(File.open('answers.log',
|
26
|
+
File::WRONLY|File::TRUNC|File::CREAT))
|
27
|
+
@logger.formatter = lambda { |s, t, p, msg| msg.to_s + "\n" }
|
27
28
|
|
28
29
|
@questions = @test.shuffled_questions
|
29
30
|
@questions_length = @questions.length.to_f
|
@@ -31,11 +32,14 @@ END_OF_TEST
|
|
31
32
|
@started_at = Time.now
|
32
33
|
@current_index = 0
|
33
34
|
|
34
|
-
|
35
|
+
info = Main.options[:full_test] ? 1 : 0
|
36
|
+
while @current_index < @questions.length + info do
|
35
37
|
@question = @questions[@current_index]
|
36
38
|
|
37
39
|
unless @question.nil?
|
38
|
-
|
40
|
+
print "#{@current_index+1} / #{@questions.length}\t\t"
|
41
|
+
puts "From: #{@question.file}\t\tTime spent: #{spent?}"
|
42
|
+
|
39
43
|
puts @question.answered(@answers[@question])
|
40
44
|
else
|
41
45
|
puts END_OF_TEST_MESSAGE
|
@@ -102,8 +106,10 @@ Available commands (whitespace does not matter):
|
|
102
106
|
END_OF_HELP
|
103
107
|
false
|
104
108
|
else
|
105
|
-
@answers[@question] = line.
|
106
|
-
|
109
|
+
@answers[@question] = line.gsub(/\s+/, "").each_char.collect.to_a.uniq
|
110
|
+
unless Main.options[:full_test]
|
111
|
+
puts @question.check?(@answers[@question])
|
112
|
+
end
|
107
113
|
@current_index += 1
|
108
114
|
true
|
109
115
|
end
|
@@ -140,7 +146,8 @@ END_OF_HELP
|
|
140
146
|
protected
|
141
147
|
def stat(name, color)
|
142
148
|
value = @stats[name.to_s.downcase.to_sym]
|
143
|
-
puts format("#{name.to_s.capitalize}: #{value} (%g%%)",
|
149
|
+
puts format("#{name.to_s.capitalize}: #{value} (%g%%)",
|
150
|
+
value/@questions_length * 100).color(color)
|
144
151
|
end
|
145
152
|
end
|
146
153
|
end
|
data/lib/pickaxe/shell.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Pickaxe
|
2
2
|
module Shell
|
3
|
-
# Extracted from
|
3
|
+
# Extracted from
|
4
|
+
# https://github.com/wycats/thor/blob/master/lib/thor/shell/basic.rb
|
4
5
|
def self.dynamic_width
|
5
6
|
(dynamic_width_stty.nonzero? || dynamic_width_tput)
|
6
7
|
end
|
data/lib/pickaxe/test.rb
CHANGED
@@ -1,12 +1,54 @@
|
|
1
1
|
module Pickaxe
|
2
2
|
|
3
|
-
class PathError < PickaxeError
|
3
|
+
class PathError < PickaxeError
|
4
|
+
def initialize(file_or_directory)
|
5
|
+
super("file or directory '#{file_or_directory}' does not exist")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class TestSyntaxError < PickaxeError
|
10
|
+
def initialize(file, line, message)
|
11
|
+
super("#{file}: line #{line}: #{message}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class MissingContent < TestSyntaxError
|
16
|
+
def initialize(file, line)
|
17
|
+
super(file, line, "no content (check blank lines nearby)")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class MissingAnswers < TestSyntaxError
|
22
|
+
def initialize(file, question)
|
23
|
+
super(file, question.index,
|
24
|
+
BadQuestion.message(question, "has no answers"))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class BadAnswer < TestSyntaxError
|
29
|
+
def initialize(file, line)
|
30
|
+
super(file, line.index,
|
31
|
+
"'#{line.truncate(20)}' starts with weird characters")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class BadQuestion < TestSyntaxError
|
36
|
+
def self.message(question, m)
|
37
|
+
"question '#{question.truncate(20)}' #{m}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(file, question)
|
41
|
+
super(file, question.index,
|
42
|
+
"'#{question.truncate(20)}' does not look like question")
|
43
|
+
end
|
44
|
+
end
|
4
45
|
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
46
|
+
class NoCorrectAnswer < TestSyntaxError
|
47
|
+
def initialize(file, question)
|
48
|
+
super(file, question.content.first.index,
|
49
|
+
BadQuestion.message(question.content.first, "has no correct answers"))
|
50
|
+
end
|
51
|
+
end
|
10
52
|
|
11
53
|
class TestLine < String
|
12
54
|
attr_accessor :index
|
@@ -39,19 +81,22 @@ module Pickaxe
|
|
39
81
|
|
40
82
|
def initialize(*files)
|
41
83
|
@files = files.collect do |file_or_directory|
|
42
|
-
|
84
|
+
unless File.exist?(file_or_directory)
|
85
|
+
raise PathError.new(file_or_directory)
|
86
|
+
end
|
87
|
+
|
43
88
|
if File.file?(file_or_directory)
|
44
89
|
file_or_directory
|
45
90
|
else
|
46
|
-
Dir.glob("#{file_or_directory}/*.#{Main.options[:extension]
|
91
|
+
Dir.glob("#{file_or_directory}/*.#{Main.options[:extension]}")
|
47
92
|
end
|
48
93
|
end.flatten.collect { |f| f.squeeze('/') }
|
49
94
|
|
50
95
|
@questions = []
|
51
96
|
@files.each do |file|
|
52
97
|
File.open(file) do |f|
|
53
|
-
lines = f.readlines.collect(&:strip).
|
54
|
-
TestLine.new(
|
98
|
+
lines = f.readlines.collect(&:strip).each_with_index.collect do |l, i|
|
99
|
+
TestLine.new(l, i)
|
55
100
|
end
|
56
101
|
|
57
102
|
lines = lines.reject {|line| line =~ COMMENTS_RE }
|
@@ -117,25 +162,26 @@ module Pickaxe
|
|
117
162
|
until answers.first.nil? or Answer::RE.match(answers.first)
|
118
163
|
content << answers.shift
|
119
164
|
end
|
120
|
-
|
121
|
-
raise MissingAnswers,
|
122
|
-
|
165
|
+
|
166
|
+
raise MissingAnswers.new(file, answers.first.index) if content.blank?
|
167
|
+
unless m = RE.match(content.first)
|
168
|
+
raise BadQuestion.new(file, content.first)
|
169
|
+
end
|
170
|
+
raise MissingAnswers.new(file, content.first) if answers.blank?
|
123
171
|
|
124
|
-
error_template = "#{file}: line #{content.first.index}: question '#{content.first.truncate(20)}' %s"
|
125
|
-
raise MissingAnswers, (error_template % "has no answers") if answers.blank?
|
126
|
-
|
127
172
|
answers = answers.inject([]) do |joined, line|
|
128
173
|
if Answer::RE.match(line)
|
129
174
|
joined << [line]
|
130
175
|
else
|
131
|
-
raise BadAnswer,
|
176
|
+
raise BadAnswer.new(file, line)unless Answer::LINE_RE.match(line)
|
132
177
|
joined.last << line
|
133
178
|
end
|
134
179
|
joined
|
135
180
|
end
|
136
181
|
|
137
|
-
|
138
|
-
|
182
|
+
answers = answers.collect {|answer| Answer.parse(file, answer) }
|
183
|
+
Question.new(file, m[1], content, answers).tap do |q|
|
184
|
+
raise NoCorrectAnswer.new(file, q) if q.correct_answers.blank?
|
139
185
|
end
|
140
186
|
end
|
141
187
|
|
@@ -145,7 +191,8 @@ module Pickaxe
|
|
145
191
|
selected = indices.include?(answer.index)
|
146
192
|
line = (selected ? ">> " : " ") + answer.to_s
|
147
193
|
|
148
|
-
if
|
194
|
+
if(Main.options[:force_show_answers] or
|
195
|
+
(not indices.blank? and not Main.options[:full_test])) then
|
149
196
|
if selected and answer.correctness
|
150
197
|
line.color(:green)
|
151
198
|
elsif not selected and answer.correctness
|
@@ -175,12 +222,13 @@ module Pickaxe
|
|
175
222
|
end
|
176
223
|
|
177
224
|
class Answer < Struct.new(:content, :index, :correctness)
|
178
|
-
RE = /^\s*(>+)?\s*(
|
179
|
-
LINE_RE = /^\s*(
|
225
|
+
RE = /^\s*(>+)?\s*(\?+)?\s*\(?(\w)\)\s*(.+)$/u
|
226
|
+
LINE_RE = /^\s*([[:alpha:]]|\w+)/u
|
180
227
|
|
181
228
|
def self.parse(file, lines)
|
182
229
|
m = RE.match(lines.shift)
|
183
|
-
Answer.new(m[4].strip + " " + lines.collect(&:strip).join(" "),
|
230
|
+
Answer.new(m[4].strip + " " + lines.collect(&:strip).join(" "),
|
231
|
+
m[3].strip, !m[1].nil?)
|
184
232
|
end
|
185
233
|
|
186
234
|
def to_s
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Pickaxe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 1
|
10
|
+
version: 0.5.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dawid Fatyga
|