Pickaxe 0.3.2 → 0.4.1

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