Pickaxe 0.4.4 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ require "active_support/all"
5
5
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
6
6
 
7
7
  module Pickaxe
8
- VERSION = "0.4.4"
8
+ VERSION = "0.5.1"
9
9
 
10
10
  class PickaxeError < StandardError
11
11
  attr_reader :status_code
@@ -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 (default 'txt')") do |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
 
@@ -1,5 +1,6 @@
1
1
  module Pickaxe
2
- # Extracted from https://github.com/wycats/thor/blob/master/lib/thor/shell/color.rb
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"
@@ -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] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
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
 
@@ -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', File::WRONLY|File::TRUNC|File::CREAT))
26
- @logger.formatter = lambda { |severity, time, progname, msg| msg.to_s + "\n" }
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
- while @current_index < @questions.length + (Main.options[:full_test] ? 1 : 0) do
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
- puts "#{@current_index+1} / #{@questions.length}\t\tFrom: #{@question.file}\t\tTime spent: #{spent?}"
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.strip.split(/\s+/).collect(&:strip)
106
- puts @question.check?(@answers[@question]) unless Main.options[:full_test]
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%%)", value/@questions_length * 100).color(color)
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
@@ -1,6 +1,7 @@
1
1
  module Pickaxe
2
2
  module Shell
3
- # Extracted from https://github.com/wycats/thor/blob/master/lib/thor/shell/basic.rb
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
@@ -1,12 +1,54 @@
1
1
  module Pickaxe
2
2
 
3
- class PathError < PickaxeError; status_code(1) ; end
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 TestSyntaxError < PickaxeError; status_code(2) ; end
6
- class MissingAnswers < TestSyntaxError; status_code(2) ; end
7
- class BadAnswer < TestSyntaxError; status_code(3) ; end
8
- class BadQuestion < TestSyntaxError; status_code(4) ; end
9
- class NoCorrectAnswer < TestSyntaxError; status_code(3) ; end
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
- raise PathError, "file or directory '#{file_or_directory}' does not exist" unless File.exist?(file_or_directory)
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] || "txt"}")
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).enum_with_index.collect do |line, index|
54
- TestLine.new(line, index)
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, "#{file}: line #{answers.first.index}: no content (check blank lines nearby)" if content.blank?
122
- raise BadQuestion, "#{file}: line #{content.first.index}: '#{content.first.truncate(20)}' does not look like question" unless m = RE.match(content.first)
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, "#{file}: line #{line.index}: '#{line.truncate(20)}' starts with weird characters" unless Answer::LINE_RE.match(line)
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
- Question.new(file, m[1], content, answers.collect {|answer| Answer.parse(file, answer) }).tap do |q|
138
- raise NoCorrectAnswer, (error_template % "has no correct answer") if q.correct_answers.blank?
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 Main.options[:force_show_answers] or (not indices.blank? and not Main.options[:full_test]) then
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*(\?\?)?\s*\(?(\w+)\)\s*(.+)$/u
179
- LINE_RE = /^\s*(\w+)/u
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(" "), m[3].strip, !m[1].nil?)
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: 7
4
+ hash: 9
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 4
10
- version: 0.4.4
8
+ - 5
9
+ - 1
10
+ version: 0.5.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dawid Fatyga