Pickaxe 0.3.2 → 0.4.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/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # A Gemfile for Pickaxe
2
2
  source "http://rubygems.org"
3
3
 
4
- gem 'activesupport', :require => 'active_support/all'
5
- gem 'i18n'
4
+ gem 'activesupport', "3.0.1", :require => 'active_support/all'
5
+ gem 'i18n', "0.4.2"
6
6
 
@@ -8,5 +8,5 @@ PLATFORMS
8
8
  ruby
9
9
 
10
10
  DEPENDENCIES
11
- activesupport
12
- i18n
11
+ activesupport (= 3.0.1)
12
+ i18n (= 0.4.2)
@@ -15,7 +15,6 @@ options = {}
15
15
  OptionParser.new do |opts|
16
16
  opts.banner = <<END_OF_BANNER
17
17
  Usage:
18
- pick path [, path ...]
19
18
  pickaxe path [, path ...]
20
19
 
21
20
  Uses given paths (files or directories) to generate a test from *.txt files.
@@ -38,6 +37,14 @@ END_OF_BANNER
38
37
  options[:full_test] = true
39
38
  end
40
39
 
40
+ opts.on("--strict", "Quit on syntax error in test file") do |v|
41
+ options[:strict] = true
42
+ end
43
+
44
+ opts.on_tail("--syntax-check", "Check syntax only - do not run test") do
45
+ options[:syntax_check] = true
46
+ end
47
+
41
48
  opts.on_tail("--version", "Show version") do
42
49
  puts "pickaxe version #{Pickaxe::VERSION}"
43
50
  exit
@@ -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.3.2"
8
+ VERSION = "0.4.1"
9
9
 
10
10
  class PickaxeError < StandardError
11
11
  attr_reader :status_code
@@ -14,9 +14,10 @@ END_OF_TEST
14
14
  def initialize(paths, options = {})
15
15
  raise NoTests, "no tests to run" if paths.empty?
16
16
 
17
- Main.options = options
18
-
17
+ Main.options = options
19
18
  @test = Test.new(*paths)
19
+ return if options[:syntax_check]
20
+
20
21
  @questions = @test.shuffled_questions
21
22
  @answers = Hash.new([])
22
23
  @started_at = Time.now
@@ -126,7 +127,7 @@ END_OF_HELP
126
127
  protected
127
128
  def stat(name, color)
128
129
  value = @stats[name.to_s.downcase.to_sym]
129
- puts "#{name.to_s.capitalize}: #{value} (#{value/@questions.length.to_f * 100}%%)".color(color)
130
+ puts format("#{name.to_s.capitalize}: #{value} (%g%%)", value/@questions.length.to_f * 100).color(color)
130
131
  end
131
132
  end
132
133
  end
@@ -1,12 +1,23 @@
1
1
  module Pickaxe
2
2
 
3
3
  class PathError < PickaxeError; status_code(1) ; end
4
- class MissingAnswers < PickaxeError; status_code(2) ; end
5
- class BadAnswer < PickaxeError; status_code(3) ; end
4
+
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 NoCorrectAnswer < TestSyntaxError; status_code(3) ; end
9
+
10
+ class TestLine < String
11
+ attr_accessor :index
12
+ def initialize(itself, index)
13
+ super(itself)
14
+ self.index = index + 1
15
+ end
16
+ end
6
17
 
7
18
  #
8
19
  # Test is a file in which questions are separated by a blank line.
9
- # Each question has content (first line), and answers remaining lines.
20
+ # Each question has content (lines until answer), and answers.
10
21
  # Answers are listed one per line which starts with optional >> (means answer
11
22
  # is correct), followed by index in parenthesis (index) and followed by text.
12
23
  #
@@ -33,15 +44,26 @@ module Pickaxe
33
44
  else
34
45
  Dir.glob("#{file_or_directory}/*.#{Main.options[:extension] || "txt"}")
35
46
  end
36
- end.flatten
47
+ end.flatten.collect(&:squeeze)
37
48
 
38
49
  @questions = []
39
50
  @files.each do |file|
40
51
  File.open(file) do |f|
41
- lines = f.readlines.collect(&:strip)
52
+ lines = f.readlines.collect(&:strip).enum_with_index.collect do |line, index|
53
+ TestLine.new(line, index)
54
+ end
55
+
42
56
  lines = lines.reject {|line| line =~ COMMENTS_RE }
43
57
  lines.split("").reject(&:blank?).each do |question|
44
- @questions.push(Question.parse(file, question))
58
+ begin
59
+ @questions.push(Question.parse(file, question))
60
+ rescue TestSyntaxError => e
61
+ if Main.options[:strict]
62
+ raise e
63
+ else
64
+ $stderr.puts(e.message.color(:red))
65
+ end
66
+ end
45
67
  end
46
68
  end
47
69
  end
@@ -88,13 +110,23 @@ module Pickaxe
88
110
 
89
111
  class Question < Struct.new(:file, :content, :answers)
90
112
  def self.parse(file, answers)
91
- content = answers.shift
92
- raise MissingAnswers, "question '#{content.truncate(20)}' has no answers'" if answers.blank?
93
- Question.new(file, content, answers.collect {|answer| Answer.parse(answer) })
113
+ content = []
114
+ until answers.first.nil? or Answer::RE.match(answers.first)
115
+ content << answers.shift
116
+ end
117
+
118
+ raise MissingAnswers, "#{file}: line #{answers.first.index}: no content (check blank lines nearby)" if content.blank?
119
+
120
+ error_template = "#{file}: line #{content.first.index}: question '#{content.first.truncate(20)}' %s"
121
+ raise MissingAnswers, (error_template % "has no answers") if answers.blank?
122
+ Question.new(file, content, answers.collect {|answer| Answer.parse(file, answer) }).tap do |q|
123
+ raise NoCorrectAnswer, (error_template % "has no correct answer") if q.correct_answers.blank?
124
+ end
94
125
  end
95
126
 
96
127
  def answered(indices)
97
- "#{self.content.word_wrap}\n\n" + self.answers.collect do |answer|
128
+ content = self.content.collect(&:word_wrap).join("\n")
129
+ "#{content}\n\n" + self.answers.collect do |answer|
98
130
  selected = indices.include?(answer.index)
99
131
  line = (selected ? ">> " : " ") + answer.to_s
100
132
 
@@ -129,8 +161,8 @@ module Pickaxe
129
161
 
130
162
  class Answer < Struct.new(:content, :index, :correctness)
131
163
  RE = /^\s*(>>)?(\?\?)?\s*\((\w+)\)\s*(.+)$/
132
- def self.parse(line)
133
- raise BadAnswer, "'#{line.truncate(20)}' does not look like answer" if (m = RE.match(line)).nil?
164
+ def self.parse(file, line)
165
+ raise BadAnswer, "#{file}: line #{line.index}: '#{line.truncate(20)}' does not look like answer" if (m = RE.match(line)).nil?
134
166
  Answer.new(m[m.size-1].strip, m[m.size-2].strip, m[1] == ">>")
135
167
  end
136
168
 
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: 23
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 2
10
- version: 0.3.2
8
+ - 4
9
+ - 1
10
+ version: 0.4.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dawid Fatyga
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-20 00:00:00 +01:00
18
+ date: 2010-11-28 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -38,12 +38,14 @@ dependencies:
38
38
  version_requirements: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - ">="
41
+ - - "="
42
42
  - !ruby/object:Gem::Version
43
- hash: 3
43
+ hash: 5
44
44
  segments:
45
+ - 3
45
46
  - 0
46
- version: "0"
47
+ - 1
48
+ version: 3.0.1
47
49
  requirement: *id002
48
50
  name: activesupport
49
51
  prerelease: false
@@ -52,12 +54,14 @@ dependencies:
52
54
  version_requirements: &id003 !ruby/object:Gem::Requirement
53
55
  none: false
54
56
  requirements:
55
- - - ">="
57
+ - - "="
56
58
  - !ruby/object:Gem::Version
57
- hash: 3
59
+ hash: 11
58
60
  segments:
59
61
  - 0
60
- version: "0"
62
+ - 4
63
+ - 2
64
+ version: 0.4.2
61
65
  requirement: *id003
62
66
  name: i18n
63
67
  prerelease: false