pdd 0.9 → 0.10

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.
@@ -2,7 +2,7 @@ Feature: Applies Post-Parsing Rules
2
2
  As a source code writer I want to be sure that
3
3
  certain post-parsing rules are applied
4
4
 
5
- Scenario: Throwing exception on invalid estimate
5
+ Scenario: Throwing exception on big estimates
6
6
  Given I have a "Sample.java" file with content:
7
7
  """
8
8
  @todo #13:180m This puzzle has too big estimate
@@ -11,7 +11,7 @@ Feature: Applies Post-Parsing Rules
11
11
  Then Exit code is not zero
12
12
  Then Stdout contains "bigger than 90 minutes"
13
13
 
14
- Scenario: Throwing exception on invalid estimate
14
+ Scenario: Throwing exception on small estimates
15
15
  Given I have a "Sample.java" file with content:
16
16
  """
17
17
  @todo #13:15min This puzzle has too small estimate
@@ -20,3 +20,12 @@ Feature: Applies Post-Parsing Rules
20
20
  Then Exit code is not zero
21
21
  Then Stdout contains "lower than 30 minutes"
22
22
 
23
+ Scenario: Throwing exception on duplicates
24
+ Given I have a "Sample.java" file with content:
25
+ """
26
+ @todo #13:15min The text
27
+ @todo #13:15min The text
28
+ """
29
+ When I run bin/pdd with ""
30
+ Then Exit code is not zero
31
+ Then Stdout contains "there are 2 duplicate"
@@ -15,4 +15,4 @@ Feature: Avoiding Duplicate Puzzles
15
15
  }
16
16
  }
17
17
  """
18
- When I run pdd it fails with "Duplicate key-sequence"
18
+ When I run pdd it fails with "errors, see log above"
data/features/cli.feature CHANGED
@@ -39,6 +39,7 @@ Feature: Command Line Processing
39
39
  """
40
40
  When I run bin/pdd with "> out.xml"
41
41
  Then Exit code is zero
42
+ And Stdout is empty
42
43
  And XML file "out.xml" matches "/puzzles[count(puzzle)=1]"
43
44
 
44
45
  Scenario: Excluding unnecessary files
@@ -72,7 +72,7 @@ end
72
72
 
73
73
  When(/^I run bin\/pdd with "([^"]*)"$/) do |arg|
74
74
  home = File.join(File.dirname(__FILE__), '../..')
75
- @stdout = `ruby -I#{home}/lib #{home}/bin/pdd #{arg} 2>&1`
75
+ @stdout = `ruby -I#{home}/lib #{home}/bin/pdd #{arg}`
76
76
  @exitstatus = $CHILD_STATUS.exitstatus
77
77
  end
78
78
 
@@ -82,6 +82,10 @@ Then(/^Stdout contains "([^"]*)"$/) do |txt|
82
82
  end
83
83
  end
84
84
 
85
+ Then(/^Stdout is empty$/) do
86
+ fail "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
87
+ end
88
+
85
89
  Then(/^XML file "([^"]+)" matches "([^"]+)"$/) do |file, xpath|
86
90
  fail "File #{file} doesn't exit" unless File.exist?(file)
87
91
  xml = Nokogiri::XML.parse(File.read(file))
@@ -23,5 +23,3 @@
23
23
 
24
24
  require 'simplecov'
25
25
  require 'pdd'
26
-
27
- PDD.log = Logger.new(STDOUT)
data/lib/pdd.rb CHANGED
@@ -25,6 +25,7 @@ require 'pdd/sources'
25
25
  require 'pdd/version'
26
26
  require 'pdd/rule/estimates'
27
27
  require 'pdd/rule/text'
28
+ require 'pdd/rule/duplicates'
28
29
  require 'nokogiri'
29
30
  require 'logger'
30
31
  require 'time'
@@ -45,22 +46,24 @@ module PDD
45
46
  RULES = {
46
47
  'min-estimate' => PDD::Rule::Estimate::Min,
47
48
  'max-estimate' => PDD::Rule::Estimate::Max,
48
- 'min-words' => PDD::Rule::Text::MinWords
49
+ 'min-words' => PDD::Rule::Text::MinWords,
50
+ 'max-duplicates' => PDD::Rule::MaxDuplicates
49
51
  }
50
52
 
51
53
  # Get logger.
52
54
  def self.log
53
- unless @log
54
- @log = Logger.new(STDOUT)
55
- @log.formatter = proc { |severity, _, _, msg|
56
- puts "#{severity}: #{msg.dump}"
55
+ unless @logger
56
+ @logger = Logger.new(STDOUT)
57
+ @logger.formatter = proc { |severity, _, _, msg|
58
+ "#{severity}: #{msg.dump}\n"
57
59
  }
60
+ @logger.level = Logger::ERROR
58
61
  end
59
- @log
62
+ @logger
60
63
  end
61
64
 
62
65
  class << self
63
- attr_writer :log
66
+ attr_writer :logger
64
67
  end
65
68
 
66
69
  # Code base abstraction
@@ -69,7 +72,7 @@ module PDD
69
72
  # +opts+:: Options
70
73
  def initialize(opts)
71
74
  @opts = opts
72
- PDD.log = Logger.new(File::NULL) unless @opts.verbose?
75
+ PDD.log.level = Logger::INFO if @opts.verbose?
73
76
  PDD.log.info "my version is #{PDD::VERSION}"
74
77
  end
75
78
 
@@ -82,8 +85,8 @@ module PDD
82
85
  sources = sources.exclude(p)
83
86
  PDD.log.info "excluding #{p}"
84
87
  end unless @opts[:exclude].nil?
85
- rules(
86
- sanitize(
88
+ sanitize(
89
+ rules(
87
90
  Nokogiri::XML::Builder.new do |xml|
88
91
  xml << "<?xml-stylesheet type='text/xsl' href='#{xsl}'?>"
89
92
  xml.puzzles(attrs) do
@@ -132,17 +135,16 @@ module PDD
132
135
  def rules(xml)
133
136
  doc = Nokogiri::XML(xml)
134
137
  total = 0
135
- @opts[:rule].map do |r|
138
+ (@opts[:rule] || []).push('max-duplicates:1').map do |r|
136
139
  name, value = r.split(':')
137
140
  rule = RULES[name]
138
141
  fail "rule '#{name}' doesn't exist" if rule.nil?
139
142
  rule.new(doc, value.to_i).errors.each do |e|
140
- puts e
141
143
  PDD.log.error e
142
144
  total += 1
143
145
  end
144
- end unless @opts[:rule].nil?
145
- fail "#{total} errors, see log above" unless total == 0
146
+ end
147
+ fail PDD::Error, "#{total} errors, see log above" unless total == 0
146
148
  xml
147
149
  end
148
150
 
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (c) 2014 TechnoPark Corp.
4
+ # Copyright (c) 2014 Yegor Bugayenko
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the 'Software'), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ module PDD
25
+ module Rule
26
+ # Rule for max duplicates.
27
+ class MaxDuplicates
28
+ # Ctor.
29
+ # +xml+:: XML with puzzles
30
+ def initialize(xml, max)
31
+ @xml = xml
32
+ @max = max
33
+ end
34
+
35
+ def errors
36
+ @xml.xpath('//puzzle')
37
+ .group_by { |p| p.xpath('body/text()').to_s }
38
+ .map do |_, puzzles|
39
+ next nil if puzzles.count <= @max
40
+ "there are #{puzzles.count} duplicate(s) of the same puzzle: " +
41
+ puzzles.map do |p|
42
+ "#{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"
43
+ end.join(', ') +
44
+ ", while maximum #{@max} duplicate is allowed"
45
+ end.compact
46
+ end
47
+ end
48
+ end
49
+ end
data/lib/pdd/version.rb CHANGED
@@ -26,5 +26,5 @@
26
26
  # Copyright:: Copyright (c) 2014 Yegor Bugayenko
27
27
  # License:: MIT
28
28
  module PDD
29
- VERSION = '0.9'
29
+ VERSION = '0.10'
30
30
  end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (c) 2014 TechnoPark Corp.
4
+ # Copyright (c) 2014 Yegor Bugayenko
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the 'Software'), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ require 'minitest/autorun'
25
+ require 'nokogiri'
26
+ require 'pdd/rule/duplicates'
27
+
28
+ # PDD::Rule::MaxDuplicates class test.
29
+ # Author:: Yegor Bugayenko (yegor@teamed.io)
30
+ # Copyright:: Copyright (c) 2014 Yegor Bugayenko
31
+ # License:: MIT
32
+ class TestMaxDuplicates < Minitest::Test
33
+ def test_max_duplicates
34
+ rule = PDD::Rule::MaxDuplicates.new(
35
+ Nokogiri::XML::Document.parse(
36
+ '<puzzles><puzzle><body>test</body></puzzle>
37
+ <puzzle><body>test</body></puzzle></puzzles>'
38
+ ), 1
39
+ )
40
+ assert !rule.errors.empty?, 'why it is empty?'
41
+ end
42
+
43
+ def test_max_duplicates_without_errors
44
+ rule = PDD::Rule::MaxDuplicates.new(
45
+ Nokogiri::XML::Document.parse(
46
+ '<puzzles><puzzle><body>hello</body></puzzle></puzzles>'
47
+ ), 1
48
+ )
49
+ assert rule.errors.empty?, 'it has to be empty!'
50
+ end
51
+ end
data/test/test_pdd.rb CHANGED
@@ -37,7 +37,7 @@ class TestPDD < Minitest::Test
37
37
  opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'max-estimate:15'])
38
38
  File.write(File.join(dir, 'a.txt'), '@todo #55 hello!')
39
39
  matches(
40
- Nokogiri::XML::Document.parse(PDD::Base.new(opts).xml),
40
+ Nokogiri::XML(PDD::Base.new(opts).xml),
41
41
  [
42
42
  '/processing-instruction("xml-stylesheet")[contains(.,".xsl")]',
43
43
  '/puzzles/@version',
@@ -53,7 +53,7 @@ class TestPDD < Minitest::Test
53
53
  Dir.mktmpdir 'test' do |dir|
54
54
  opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'min-estimate:30'])
55
55
  File.write(File.join(dir, 'a.txt'), '@todo #90 hello!')
56
- assert_raises RuntimeError do
56
+ assert_raises PDD::Error do
57
57
  PDD::Base.new(opts).xml
58
58
  end
59
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdd
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.9'
4
+ version: '0.10'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-04 00:00:00.000000000 Z
12
+ date: 2014-12-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -222,6 +222,7 @@ files:
222
222
  - features/unicode.feature
223
223
  - lib/pdd.rb
224
224
  - lib/pdd/puzzle.rb
225
+ - lib/pdd/rule/duplicates.rb
225
226
  - lib/pdd/rule/estimates.rb
226
227
  - lib/pdd/rule/text.rb
227
228
  - lib/pdd/source.rb
@@ -229,6 +230,7 @@ files:
229
230
  - lib/pdd/version.rb
230
231
  - pdd.gemspec
231
232
  - test/test__helper.rb
233
+ - test/test_duplicates.rb
232
234
  - test/test_estimates.rb
233
235
  - test/test_pdd.rb
234
236
  - test/test_source.rb
@@ -272,6 +274,7 @@ test_files:
272
274
  - features/support/env.rb
273
275
  - features/unicode.feature
274
276
  - test/test__helper.rb
277
+ - test/test_duplicates.rb
275
278
  - test/test_estimates.rb
276
279
  - test/test_pdd.rb
277
280
  - test/test_source.rb