pdd 0.20.6 → 0.20.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94bad35283e2d4e40df39ffa9a643c1352a4674cb500123fb0442af9c3af082d
4
- data.tar.gz: a451b9e8a979d64fbcae9e5cb279cc6c25c87ba9d7d1618e740083444a37cc12
3
+ metadata.gz: 8220e74b7aca6e6feddfe8ccad195c1156386ad766ae1dd31311122242c1292c
4
+ data.tar.gz: 97816bbe7fdfdb29d595683dd98b6eb41d6bc1880e269c4dc11eee4a2b02f582
5
5
  SHA512:
6
- metadata.gz: b71f4e3eafa987be5233a8f29ec25b8c72bbb6eebd36cf9f9b23b01b1c09767ea4cd395c9c6f369068d87a41bd638dc6a7e5588ebeb7b21f60d6fd5db9e0e043
7
- data.tar.gz: 075700135e8e66e28c2db6cff9b613d76fdb464529ad164fae32f6c179e840197e2e946622c7ce87419422b3d4029b1c584d59f302a30581febf832b730fadc6
6
+ metadata.gz: c4128efeb2b302351595bbe99978845e8d8d546f11e341c0d0308821e673f6f2aa2730c4d2170751d711892d17942563275641b8dbec04916d9bb7bac8715f2a
7
+ data.tar.gz: 501ddaf76735e9ce50ae3a233c45331d568075979ef3875395e7d361139e008954de9767e14856af7d247adf2a597254b3e89104cc96e5832baa03a278f89a3c
data/.pdd CHANGED
@@ -1,5 +1,6 @@
1
1
  --source=.
2
2
  --verbose
3
+ --skip-errors
3
4
  --exclude .idea/**/*
4
5
  --exclude target/**/*
5
6
  --exclude coverage/**/*
data/.simplecov CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2014-2020 Yegor Bugayenko
3
+ Copyright (c) 2014-2021 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/README.md CHANGED
@@ -4,19 +4,19 @@
4
4
 
5
5
  [![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org)
6
6
  [![Managed by Zerocracy](https://www.0crat.com/badge/C3T46CUJJ.svg)](https://www.0crat.com/p/C3T46CUJJ)
7
- [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/pdd)](http://www.rultor.com/p/yegor256/pdd)
7
+ [![DevOps By Rultor.com](http://www.rultor.com/b/cqfn/pdd)](http://www.rultor.com/p/cqfn/pdd)
8
8
  [![We recommend RubyMine](https://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
9
9
 
10
- [![Build Status](https://travis-ci.org/yegor256/pdd.svg)](https://travis-ci.org/yegor256/pdd)
11
- [![Build status](https://ci.appveyor.com/api/projects/status/b59sdhuu0gcku15b?svg=true)](https://ci.appveyor.com/project/yegor256/pdd)
12
- [![PDD status](http://www.0pdd.com/svg?name=yegor256/pdd)](http://www.0pdd.com/p?name=yegor256/pdd)
13
- [![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/pdd.svg)](https://codecov.io/github/yegor256/pdd?branch=master)
14
- [![Hits-of-Code](https://hitsofcode.com/github/yegor256/pdd)](https://hitsofcode.com/view/github/yegor256/pdd)
15
- [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/pdd/blob/master/LICENSE.txt)
10
+ [![Build Status](https://travis-ci.org/cqfn/pdd.svg)](https://travis-ci.org/cqfn/pdd)
11
+ [![Build status](https://ci.appveyor.com/api/projects/status/b59sdhuu0gcku15b?svg=true)](https://ci.appveyor.com/project/cqfn/pdd)
12
+ [![PDD status](http://www.0pdd.com/svg?name=cqfn/pdd)](http://www.0pdd.com/p?name=cqfn/pdd)
13
+ [![Test Coverage](https://img.shields.io/codecov/c/github/cqfn/pdd.svg)](https://codecov.io/github/cqfn/pdd?branch=master)
14
+ [![Hits-of-Code](https://hitsofcode.com/github/cqfn/pdd)](https://hitsofcode.com/view/github/cqfn/pdd)
15
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/cqfn/pdd/blob/master/LICENSE.txt)
16
16
 
17
17
  [![Gem Version](https://badge.fury.io/rb/pdd.svg)](http://badge.fury.io/rb/pdd)
18
- [![Maintainability](https://api.codeclimate.com/v1/badges/c8e46256fdd8ddc817e5/maintainability)](https://codeclimate.com/github/yegor256/pdd/maintainability)
19
- [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/yegor256/pdd/master/frames)
18
+ [![Maintainability](https://api.codeclimate.com/v1/badges/c8e46256fdd8ddc817e5/maintainability)](https://codeclimate.com/github/cqfn/pdd/maintainability)
19
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/cqfn/pdd/master/frames)
20
20
 
21
21
  Read this article about
22
22
  [_Puzzle Driven Development_](http://www.yegor256.com/2009/03/04/pdd.html).
@@ -60,10 +60,12 @@ to the leading space in every consecutive line):
60
60
  */
61
61
  [related code]
62
62
  ```
63
+
63
64
  \[\] - Replace with apropriate data (see text enclosed in brackets)
64
- <> - Omitable (enclosed data can be left out)
65
+ <> - Omitable (enclosed data can be left out)
65
66
 
66
67
  Example:
68
+
67
69
  ```java
68
70
  /**
69
71
  * @todo #234:15m/DEV This is something to do later
@@ -82,10 +84,13 @@ The specified markers will be included in the issues body
82
84
  along with some predefined text. If your comment is longer
83
85
  than 40 characters, it will be truncated in the title.
84
86
 
85
- It starts with `@todo`, followed by a space and a mandatory puzzle **marker**.
86
- Possible formats of puzzle markers (it doesn't matter what the
87
+ There are 3 supported keywords, one of which must precede the mandatory
88
+ puzzle marker. They are `@todo`, `TODO` and `TODO:`.
89
+
90
+ As an example, it starts with `@todo`, followed by a space and a mandatory
91
+ puzzle **marker**. Possible formats of puzzle markers (it doesn't matter what the
87
92
  line starts with and where it is located,
88
- as long as you have that `@todo` right in front
93
+ as long as you have one of the 3 supported keywords right in front
89
94
  of the mandatory marker):
90
95
 
91
96
  ```
@@ -94,12 +99,14 @@ of the mandatory marker):
94
99
  # @todo #55:45min
95
100
  @todo #67/DES
96
101
  ;; @todo #678:40m/DEV
102
+ // TODO: #1:30min
103
+ (* TODO #42 *)
97
104
  ```
98
105
 
99
106
  Here `DES` and `DEV` are the roles of people who must fix that puzzles;
100
107
  `45min` and `40m` is the amount of time the puzzle should take;
101
- `224`, `TEST-13`, `55`, `67`, and `678` are the IDs of the tickets these
102
- puzzles are coming from.
108
+ `224`, `TEST-13`, `55`, `67`, `678`, `1`, and `42` are the IDs of the tickets
109
+ these puzzles are coming from.
103
110
 
104
111
  Markers are absolutely necessary for all puzzles, because they allow
105
112
  us to build a hierarchical dependency tree of all puzzles, like
@@ -122,18 +129,18 @@ parameter specified after a colon.
122
129
 
123
130
  Here is a list of rules available now:
124
131
 
125
- * `min-estimate:15` blocks all puzzles that don't have an estimate
132
+ - `min-estimate:15` blocks all puzzles that don't have an estimate
126
133
  or their estimates are less than 15 minutes.
127
134
 
128
- * `max-estimate:120` blocks all puzzles with estimates over 120 minutes.
135
+ - `max-estimate:120` blocks all puzzles with estimates over 120 minutes.
129
136
 
130
- * `available-roles:DEV,IMP,DES` specifies a list of roles that
137
+ - `available-roles:DEV,IMP,DES` specifies a list of roles that
131
138
  are allowed in puzzles. Puzzles without explicitly specified
132
139
  roles will be rejected.
133
140
 
134
- * `min-words:5` blocks puzzles with descriptions shorter than five words.
141
+ - `min-words:5` blocks puzzles with descriptions shorter than five words.
135
142
 
136
- * `max-duplicates:1` blocks more than one duplicate of any puzzle.
143
+ - `max-duplicates:1` blocks more than one duplicate of any puzzle.
137
144
  This rule is used by default and you can't configure it at the moment,
138
145
  it must always be set to `1`.
139
146
 
@@ -166,18 +173,18 @@ The XML produced will look approximately like this (here is a
166
173
  [XSD Schema](http://pdd-xsd.teamed.io/0.19.4.xsd) is here.
167
174
  The most interesting parts of each puzzle are:
168
175
 
169
- * `ticket` is a ticket name puzzle marker starts from, in most
170
- cases it will be the number of GitHub issue.
176
+ - `ticket` is a ticket name puzzle marker starts from, in most
177
+ cases it will be the number of GitHub issue.
171
178
 
172
- * `estimate` is the amount of minutes the puzzle is supposed to take.
179
+ - `estimate` is the amount of minutes the puzzle is supposed to take.
173
180
 
174
- * `id` is a unique ID of the puzzle. It is calculated by the
175
- internal algorithm that takes into account only the text of the puzzle.
176
- Thus, if you move the puzzle from one file to another, the ID won't
177
- change. Also, changing the location of a puzzle inside a file
178
- won't change its ID.
181
+ - `id` is a unique ID of the puzzle. It is calculated by the
182
+ internal algorithm that takes into account only the text of the puzzle.
183
+ Thus, if you move the puzzle from one file to another, the ID won't
184
+ change. Also, changing the location of a puzzle inside a file
185
+ won't change its ID.
179
186
 
180
- * `lines` is where the puzzle is found, inside the file.
187
+ - `lines` is where the puzzle is found, inside the file.
181
188
 
182
189
  ## How to contribute
183
190
 
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/assets/puzzles.xsd CHANGED
@@ -2,7 +2,7 @@
2
2
  <!--
3
3
  (The MIT License)
4
4
 
5
- Copyright (c) 2014-2020 Yegor Bugayenko
5
+ Copyright (c) 2014-2021 Yegor Bugayenko
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  of this software and associated documentation files (the 'Software'), to deal
data/assets/puzzles.xsl CHANGED
@@ -2,7 +2,7 @@
2
2
  <!--
3
3
  (The MIT License)
4
4
 
5
- Copyright (c) 2014-2020 Yegor Bugayenko
5
+ Copyright (c) 2014-2021 Yegor Bugayenko
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  of this software and associated documentation files (the 'Software'), to deal
data/bin/pdd CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (c) 2014-2020 Yegor Bugayenko
2
+ # Copyright (c) 2014-2021 Yegor Bugayenko
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the 'Software'), to deal
@@ -21,6 +21,9 @@
21
21
 
22
22
  STDOUT.sync = true
23
23
 
24
+ require 'shellwords'
25
+ require 'English'
26
+ require 'find'
24
27
  require 'slop'
25
28
  require 'nokogiri'
26
29
  require 'rainbow'
@@ -39,6 +42,11 @@ begin
39
42
  end
40
43
  args += ARGV
41
44
 
45
+ dir = Dir.pwd
46
+ @dir = File.absolute_path(dir)
47
+ files = Dir.glob(
48
+ File.join(@dir, '**/*'), File::FNM_DOTMATCH
49
+ ).reject { |f| File.directory?(f) }
42
50
  begin
43
51
  opts = Slop.parse(args, strict: true, help: true) do |o|
44
52
  o.banner = "Usage (#{PDD::VERSION}): pdd [options]"
@@ -46,6 +54,8 @@ begin
46
54
  o.bool '-v', '--verbose', 'Enable verbose mode (a lot of logging)'
47
55
  o.bool '-q', '--quiet', 'Enable quiet mode (almost no logging)'
48
56
  o.bool '--skip-gitignore', 'Don\'t look into .gitignore for excludes'
57
+ o.bool '--skip-errors', 'Suppress error as warning and skip badly
58
+ formatted puzzles'
49
59
  o.bool '-i', '--version', 'Show current version' do
50
60
  puts PDD::VERSION
51
61
  exit
@@ -54,6 +64,8 @@ begin
54
64
  o.string '-f', '--file', 'File to save XML into'
55
65
  o.array '-e', '--exclude', 'Glob pattern to exclude, e.g. "**/*.jpg"',
56
66
  default: []
67
+ o.array '-n', '--include', 'Glob pattern to include, e.g. "**/*.jpg"',
68
+ default: [files]
57
69
  o.string '-t', '--format', 'Format of the report (xml|html)'
58
70
  o.array(
59
71
  '-r', '--rule', 'Rule to apply (can be used many times)',
@@ -67,7 +79,7 @@ begin
67
79
  if opts.help?
68
80
  puts opts
69
81
  puts "This is our README to learn more: \
70
- https://github.com/yegor256/pdd/blob/master/README.md"
82
+ https://github.com/cqfn/pdd/blob/master/README.md"
71
83
  exit
72
84
  end
73
85
 
@@ -76,7 +88,7 @@ https://github.com/yegor256/pdd/blob/master/README.md"
76
88
  end
77
89
 
78
90
  if opts['skip-gitignore']
79
- raise 'For --skip-gitignore see https://github.com/yegor256/pdd/issues/80'
91
+ raise 'For --skip-gitignore see https://github.com/cqfn/pdd/issues/80'
80
92
  end
81
93
 
82
94
  Encoding.default_external = Encoding::UTF_8
@@ -103,9 +115,9 @@ rescue PDD::Error => ex
103
115
  puts "#{Rainbow('ERROR').red}: #{ex.message}
104
116
  If you can't understand the cause of this issue or you don't know \
105
117
  how to fix it, please submit a GitHub issue, we will try to help you: \
106
- https://github.com/yegor256/pdd/issues. This tool is still in its beta \
118
+ https://github.com/cqfn/pdd/issues. This tool is still in its beta \
107
119
  version and we will appreciate your feedback. Here is where you can find \
108
- more documentation: https://github.com/yegor256/pdd/blob/master/README.md."
120
+ more documentation: https://github.com/cqfn/pdd/blob/master/README.md."
109
121
  PDD.log.info 'Exit code is 1'
110
122
  exit(1)
111
123
  rescue StandardError => ex
@@ -21,22 +21,7 @@ Feature: Catches Broken Puzzles
21
21
  }
22
22
  """
23
23
  When I run pdd it fails with "Space expected"
24
- When I run pdd it fails with "puzzle at line #6"
25
-
26
- Scenario: Throwing exception on another broken puzzle
27
- Given I have a "Sample.java" file with content:
28
- """
29
- public class Main {
30
- /**
31
- * @todo #13 This puzzle has an incorrect format
32
- * because its second line starts with too many spaces
33
- */
34
- public void main(String[] args) {
35
- // later
36
- }
37
- }
38
- """
39
- When I run pdd it fails with "Too many leading spaces"
24
+ When I run pdd it fails with "Sample.java:6"
40
25
 
41
26
  Scenario: Throwing exception on yet another broken puzzle
42
27
  Given I have a "Sample.java" file with content:
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/lib/pdd/puzzle.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/lib/pdd/rule/text.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
data/lib/pdd/source.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -26,6 +26,7 @@ require_relative '../pdd'
26
26
  require_relative '../pdd/puzzle'
27
27
 
28
28
  module PDD
29
+ MARKERS = ["\x40todo", 'TODO:?'].freeze
29
30
  # Source.
30
31
  class Source
31
32
  # Ctor.
@@ -36,21 +37,27 @@ module PDD
36
37
  @path = path
37
38
  end
38
39
 
40
+ def match_markers(line)
41
+ MARKERS.map do |mkr|
42
+ %r{(.*(?:^|\s))#{mkr}\s+#([\w\-\.:/]+)\s+(.+)}.match(line)
43
+ end.compact
44
+ end
45
+
39
46
  # Fetch all puzzles.
40
47
  def puzzles
41
- PDD.log.info "Reading #{@path}..."
48
+ PDD.log.info "Reading #{@path} ..."
42
49
  puzzles = []
43
50
  lines = File.readlines(@file, encoding: 'UTF-8')
44
51
  lines.each_with_index do |line, idx|
45
52
  begin
46
53
  check_rules(line)
47
- ["\x40todo", 'TODO:?'].each do |pfx|
48
- %r{(.*(?:^|\s))#{pfx}\s+#([\w\-\.:/]+)\s+(.+)}.match(line) do |m|
49
- puzzles << puzzle(lines.drop(idx + 1), m, idx)
50
- end
54
+ match_markers(line).each do |m|
55
+ puzzles << puzzle(lines.drop(idx + 1), m, idx)
51
56
  end
52
57
  rescue Error, ArgumentError => ex
53
- raise Error, "puzzle at line ##{idx + 1}; #{ex.message}"
58
+ message = "#{@path}:#{idx + 1} #{ex.message}"
59
+ raise Error, message unless PDD.opts && PDD.opts['skip-errors']
60
+ PDD.log.warn message
54
61
  end
55
62
  end
56
63
  puzzles
@@ -60,19 +67,19 @@ module PDD
60
67
 
61
68
  def get_no_leading_space_error(todo)
62
69
  "#{todo} must have a leading space to become \
63
- a puzzle, as this page explains: https://github.com/yegor256/pdd#how-to-format"
70
+ a puzzle, as this page explains: https://github.com/cqfn/pdd#how-to-format"
64
71
  end
65
72
 
66
73
  def get_no_puzzle_marker_error(todo)
67
74
  "#{todo} found, but puzzle can't be parsed, \
68
75
  most probably because #{todo} is not followed by a puzzle marker, \
69
- as this page explains: https://github.com/yegor256/pdd#how-to-format"
76
+ as this page explains: https://github.com/cqfn/pdd#how-to-format"
70
77
  end
71
78
 
72
79
  def get_space_after_hash_error(todo)
73
80
  "#{todo} found, but there is an unexpected space \
74
81
  after the hash sign, it should not be there, \
75
- see https://github.com/yegor256/pdd#how-to-format"
82
+ see https://github.com/cqfn/pdd#how-to-format"
76
83
  end
77
84
 
78
85
  def check_rules(line)
@@ -118,7 +125,7 @@ see https://github.com/yegor256/pdd#how-to-format"
118
125
  match = re.match(text)
119
126
  if match.nil?
120
127
  raise "Invalid puzzle marker \"#{text}\", most probably formatted \
121
- against the rules explained here: https://github.com/yegor256/pdd#how-to-format"
128
+ against the rules explained here: https://github.com/cqfn/pdd#how-to-format"
122
129
  end
123
130
  {
124
131
  ticket: match[1],
@@ -137,20 +144,13 @@ against the rules explained here: https://github.com/yegor256/pdd#how-to-format"
137
144
  # Fetch puzzle tail (all lines after the first one)
138
145
  def tail(lines, prefix, start)
139
146
  lines
140
- .take_while { |t| t.start_with?(prefix) }
147
+ .take_while { |t| match_markers(t).none? && t.start_with?(prefix) }
141
148
  .map { |t| t[prefix.length, t.length] }
142
149
  .take_while { |t| t =~ /^[ a-zA-Z0-9]/ }
143
150
  .each_with_index do |t, i|
144
151
  next if t.start_with?(' ')
145
152
  raise Error, "Space expected at #{start + i + 2}:#{prefix.length}; \
146
153
  make sure all lines in the puzzle body have a single leading space."
147
- end
148
- .each_with_index do |t, i|
149
- next if t !~ /^\s{2,}/
150
- raise Error, "Too many leading spaces \
151
- at #{start + i + 2}:#{prefix.length}; \
152
- make sure all lines that include the puzzle body start \
153
- at position ##{prefix.length + 1}."
154
154
  end
155
155
  .map { |t| t[1, t.length] }
156
156
  end
@@ -188,7 +188,7 @@ at position ##{prefix.length + 1}."
188
188
  end
189
189
 
190
190
  def add_github_login(info)
191
- login = find_github_login(info[:email])
191
+ login = find_github_login(info)
192
192
  info[:author] = "@#{login}" unless login.empty?
193
193
  info
194
194
  end
@@ -203,15 +203,24 @@ at position ##{prefix.length + 1}."
203
203
  JSON.parse res.body
204
204
  end
205
205
 
206
- def find_github_user(email)
207
- base_uri = 'https://api.github.com/search/users'
208
- query = base_uri + "?q=#{email}+in:email&perpage=1"
206
+ def find_github_user(info)
207
+ email, author = info.values_at(:email, :author)
208
+ # if email is not defined, changes have not been committed
209
+ return if email.nil?
210
+ base_uri = 'https://api.github.com/search/users?per_page=1'
211
+ query = base_uri + "&q=#{email}+in:email"
209
212
  json = get_json query
213
+ # find user by name instead since users can make github email private
214
+ unless json['total_count'].positive?
215
+ return if author.nil?
216
+ query = base_uri + "&q=#{author}+in:fullname"
217
+ json = get_json query
218
+ end
210
219
  json['items'].first
211
220
  end
212
221
 
213
- def find_github_login(email)
214
- user = find_github_user email
222
+ def find_github_login(info)
223
+ user = find_github_user info
215
224
  user['login']
216
225
  rescue StandardError
217
226
  ''
data/lib/pdd/sources.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -30,6 +30,7 @@ module PDD
30
30
  def initialize(dir, ptns = [])
31
31
  @dir = File.absolute_path(dir)
32
32
  @exclude = ptns + ['.git/**/*']
33
+ @include = ptns + ['.git/**/*']
33
34
  end
34
35
 
35
36
  # Fetch all sources.
@@ -37,6 +38,14 @@ module PDD
37
38
  files = Dir.glob(
38
39
  File.join(@dir, '**/*'), File::FNM_DOTMATCH
39
40
  ).reject { |f| File.directory?(f) }
41
+ included = 0
42
+ @include.each do |ptn|
43
+ Dir.glob(File.join(@dir, ptn), File::FNM_DOTMATCH) do |f|
44
+ files.keep_if { |i| i != f }
45
+ included += 1
46
+ end
47
+ end
48
+ PDD.log.info "#{files.size} file(s) found, #{included} files included"
40
49
  excluded = 0
41
50
  @exclude.each do |ptn|
42
51
  Dir.glob(File.join(@dir, ptn), File::FNM_DOTMATCH) do |f|
@@ -55,6 +64,10 @@ module PDD
55
64
  Sources.new(@dir, @exclude.push(ptn))
56
65
  end
57
66
 
67
+ def include(ptn)
68
+ Sources.new(@dir, @include.push(ptn))
69
+ end
70
+
58
71
  private
59
72
 
60
73
  # @todo #98:30min Change the implementation of this method
data/lib/pdd/version.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -20,8 +20,8 @@
20
20
 
21
21
  # PDD main module.
22
22
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
23
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module PDD
26
- VERSION = '0.20.6'.freeze
26
+ VERSION = '0.20.7'.freeze
27
27
  end
data/lib/pdd.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -30,7 +30,7 @@ require_relative 'pdd/rule/roles'
30
30
 
31
31
  # PDD main module.
32
32
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
33
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
33
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
34
34
  # License:: MIT
35
35
  module PDD
36
36
  # If it breaks.
@@ -56,17 +56,20 @@ module PDD
56
56
  @logger.formatter = proc { |severity, _, _, msg|
57
57
  if severity == 'ERROR'
58
58
  "#{Rainbow(severity).red}: #{msg}\n"
59
+ elsif severity == 'WARN'
60
+ "#{Rainbow(severity).orange}: #{msg}\n"
59
61
  else
60
62
  "#{msg}\n"
61
63
  end
62
64
  }
63
- @logger.level = Logger::ERROR
65
+ @logger.level = Logger::WARN
64
66
  end
65
67
  @logger
66
68
  end
67
69
 
68
70
  class << self
69
71
  attr_writer :logger
72
+ attr_accessor :opts
70
73
  end
71
74
 
72
75
  # Code base abstraction
@@ -75,6 +78,7 @@ module PDD
75
78
  # +opts+:: Options
76
79
  def initialize(opts)
77
80
  @opts = opts
81
+ PDD.opts = opts
78
82
  PDD.log.level = Logger::INFO if @opts[:verbose]
79
83
  PDD.log.level = Logger::ERROR if @opts[:quiet]
80
84
  PDD.log.info "My version is #{PDD::VERSION}"
@@ -87,6 +91,9 @@ module PDD
87
91
  PDD.log.info "Reading #{dir}"
88
92
  require_relative 'pdd/sources'
89
93
  sources = Sources.new(dir)
94
+ @opts[:include]&.each do |p|
95
+ sources = sources.include(p)
96
+ end
90
97
  @opts[:exclude]&.each do |p|
91
98
  sources = sources.exclude(p)
92
99
  PDD.log.info "Excluding #{p}"
data/pdd.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
38
38
  s.description = 'Collects PDD puzzles from a source code base'
39
39
  s.authors = ['Yegor Bugayenko']
40
40
  s.email = 'yegor256@gmail.com'
41
- s.homepage = 'http://github.com/yegor256/pdd'
41
+ s.homepage = 'http://github.com/cqfn/pdd'
42
42
  s.files = `git ls-files`.split($RS)
43
43
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
44
44
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
data/test/test__helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -29,3 +29,16 @@ end
29
29
 
30
30
  require 'minitest/autorun'
31
31
  require_relative '../lib/pdd'
32
+
33
+ def stub_source_find_github_user(file, path = '')
34
+ source = PDD::Source.new(file, path)
35
+ verbose_source = PDD::VerboseSource.new(file, source)
36
+ fake = proc do |info = {}|
37
+ email, author = info.values_at(:email, :author)
38
+ { 'login' => 'yegor256' } if email == 'yegor256@gmail.com' ||
39
+ author == 'Yegor Bugayenko'
40
+ end
41
+ source.stub :find_github_user, fake do
42
+ yield verbose_source
43
+ end
44
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/duplicates'
24
24
 
25
25
  # PDD::Rule::MaxDuplicates class test.
26
26
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
27
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
28
28
  # License:: MIT
29
29
  class TestMaxDuplicates < Minitest::Test
30
30
  def test_max_duplicates
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/estimates'
24
24
 
25
25
  # PDD::Rule::Estimate module tests.
26
26
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
27
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
28
28
  # License:: MIT
29
29
  class TestEstimates < Minitest::Test
30
30
  def test_min
data/test/test_pdd.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -26,7 +26,7 @@ require_relative '../lib/pdd'
26
26
 
27
27
  # PDD main module test.
28
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
29
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
30
30
  # License:: MIT
31
31
  class TestPDD < Minitest::Test
32
32
  def test_basic
@@ -95,6 +95,7 @@ class TestPDD < Minitest::Test
95
95
  Slop.parse args do |o|
96
96
  o.bool '-v', '--verbose'
97
97
  o.bool '-q', '--quiet'
98
+ o.bool '--skip-errors'
98
99
  o.string '-s', '--source'
99
100
  o.array '-e', '--exclude'
100
101
  o.array '-r', '--rule'
data/test/test_roles.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/roles'
24
24
 
25
25
  # PDD::Rule::Role module tests.
26
26
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
27
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
28
28
  # License:: MIT
29
29
  class TestRoles < Minitest::Test
30
30
  def test_incorrect_role
data/test/test_source.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -25,7 +25,7 @@ require_relative '../lib/pdd/sources'
25
25
 
26
26
  # Source test.
27
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
28
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
29
29
  # License:: MIT
30
30
  class TestSource < Minitest::Test
31
31
  def test_parsing
@@ -42,15 +42,39 @@ class TestSource < Minitest::Test
42
42
  ~~ and it also has to work
43
43
  "
44
44
  )
45
- list = PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
46
- assert_equal 2, list.size
47
- puzzle = list.first
48
- assert_equal '2-3', puzzle.props[:lines]
49
- assert_equal 'привет, how are you doing?', puzzle.props[:body]
50
- assert_equal '44', puzzle.props[:ticket]
51
- assert puzzle.props[:author].nil?
52
- assert puzzle.props[:email].nil?
53
- assert puzzle.props[:time].nil?
45
+ stub_source_find_github_user(file, 'hey') do |source|
46
+ list = source.puzzles
47
+ assert_equal 2, list.size
48
+ puzzle = list.first
49
+ assert_equal '2-3', puzzle.props[:lines]
50
+ assert_equal 'привет, how are you doing?', puzzle.props[:body]
51
+ assert_equal '44', puzzle.props[:ticket]
52
+ assert puzzle.props[:author].nil?
53
+ assert puzzle.props[:email].nil?
54
+ assert puzzle.props[:time].nil?
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_parsing_leading_spaces
60
+ Dir.mktmpdir 'test' do |dir|
61
+ file = File.join(dir, 'a.txt')
62
+ File.write(
63
+ file,
64
+ "
65
+ * \x40todo #56:30min this is a
66
+ * multi-line
67
+ * comment!
68
+ "
69
+ )
70
+ stub_source_find_github_user(file, 'hey') do |source|
71
+ list = source.puzzles
72
+ assert_equal 1, list.size
73
+ puzzle = list.first
74
+ assert_equal '2-4', puzzle.props[:lines]
75
+ assert_equal 'this is a multi-line comment!', puzzle.props[:body]
76
+ assert_equal '56', puzzle.props[:ticket]
77
+ end
54
78
  end
55
79
  end
56
80
 
@@ -65,12 +89,39 @@ class TestSource < Minitest::Test
65
89
  "
66
90
  )
67
91
  error = assert_raises PDD::Error do
68
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
92
+ stub_source_find_github_user(file, 'hey', &:puzzles)
69
93
  end
70
94
  assert !error.message.index('Space expected').nil?
71
95
  end
72
96
  end
73
97
 
98
+ def test_succeed_despite_bad_puzzles
99
+ Dir.mktmpdir 'test' do |dir|
100
+ file = File.join(dir, 'a.txt')
101
+ File.write(
102
+ file,
103
+ "
104
+ * \x40todo #44 this is an incorrectly formatted puzzle,
105
+ * with a second line without a leading space
106
+ Another badly formatted puzzle
107
+ * \x40todo this puzzle misses ticket name/number
108
+ Something else
109
+ * \x40todo #123 This puzzle is correctly formatted
110
+ "
111
+ )
112
+ PDD.opts = { 'skip-errors' => true }
113
+ stub_source_find_github_user(file, 'hey') do |source|
114
+ list = source.puzzles
115
+ PDD.opts = nil
116
+ assert_equal 1, list.size
117
+ puzzle = list.first
118
+ assert_equal '7-7', puzzle.props[:lines]
119
+ assert_equal 'This puzzle is correctly formatted', puzzle.props[:body]
120
+ assert_equal '123', puzzle.props[:ticket]
121
+ end
122
+ end
123
+ end
124
+
74
125
  def test_failing_on_incomplete_puzzle
75
126
  Dir.mktmpdir 't5' do |dir|
76
127
  file = File.join(dir, 'ff.txt')
@@ -81,7 +132,7 @@ class TestSource < Minitest::Test
81
132
  "
82
133
  )
83
134
  error = assert_raises PDD::Error do
84
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'ff')).puzzles
135
+ stub_source_find_github_user(file, 'ff', &:puzzles)
85
136
  end
86
137
  assert !error.to_s.index("\x40todo is not followed by").nil?
87
138
  end
@@ -92,7 +143,7 @@ class TestSource < Minitest::Test
92
143
  file = File.join(dir, 'xx.txt')
93
144
  File.write(file, ' * \x40todo #44 this is a broken unicode: ' + 0x92.chr)
94
145
  assert_raises PDD::Error do
95
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'xx')).puzzles
146
+ stub_source_find_github_user(file, 'xx', &:puzzles)
96
147
  end
97
148
  end
98
149
  end
@@ -107,7 +158,7 @@ class TestSource < Minitest::Test
107
158
  "
108
159
  )
109
160
  error = assert_raises PDD::Error do
110
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
161
+ stub_source_find_github_user(file, 'hey', &:puzzles)
111
162
  end
112
163
  assert !error.message.index('is not followed by a puzzle marker').nil?
113
164
  end
@@ -123,7 +174,7 @@ class TestSource < Minitest::Test
123
174
  "
124
175
  )
125
176
  error = assert_raises PDD::Error do
126
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'x')).puzzles
177
+ stub_source_find_github_user(file, 'x', &:puzzles)
127
178
  end
128
179
  assert !error.message.index("\x40todo must have a leading space").nil?
129
180
  end
@@ -139,7 +190,7 @@ class TestSource < Minitest::Test
139
190
  "
140
191
  )
141
192
  error = assert_raises PDD::Error do
142
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'x')).puzzles
193
+ stub_source_find_github_user(file, 'x', &:puzzles)
143
194
  end
144
195
  assert !error.message.index('an unexpected space').nil?
145
196
  end
@@ -153,20 +204,23 @@ class TestSource < Minitest::Test
153
204
  cd '#{dir}'
154
205
  git init --quiet .
155
206
  git config user.email test@teamed.io
156
- git config user.name test
207
+ git config user.name test_unknown
157
208
  echo '\x40todo #1 this is the puzzle' > a.txt
158
209
  git add a.txt
159
210
  git commit --quiet -am 'first version'
160
211
  ")
161
- list = PDD::Source.new(File.join(dir, 'a.txt'), '').puzzles
162
- assert_equal 1, list.size
163
- puzzle = list.first
164
- assert_equal '1-de87adc8', puzzle.props[:id]
165
- assert_equal '1-1', puzzle.props[:lines]
166
- assert_equal 'this is the puzzle', puzzle.props[:body]
167
- assert_equal 'test', puzzle.props[:author]
168
- assert_equal 'test@teamed.io', puzzle.props[:email]
169
- assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/, puzzle.props[:time])
212
+ stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
213
+ list = source.puzzles
214
+ assert_equal 1, list.size
215
+ puzzle = list.first
216
+ assert_equal '1-de87adc8', puzzle.props[:id]
217
+ assert_equal '1-1', puzzle.props[:lines]
218
+ assert_equal 'this is the puzzle', puzzle.props[:body]
219
+ assert_equal 'test_unknown', puzzle.props[:author]
220
+ assert_equal 'test@teamed.io', puzzle.props[:email]
221
+ assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
222
+ puzzle.props[:time])
223
+ end
170
224
  end
171
225
  end
172
226
 
@@ -183,15 +237,18 @@ class TestSource < Minitest::Test
183
237
  git add a.txt
184
238
  git commit --quiet -am 'first version'
185
239
  ")
186
- list = PDD::Source.new(File.join(dir, 'a.txt'), '').puzzles
187
- assert_equal 1, list.size
188
- puzzle = list.first
189
- assert_equal '1-de87adc8', puzzle.props[:id]
190
- assert_equal '1-1', puzzle.props[:lines]
191
- assert_equal 'this is the puzzle', puzzle.props[:body]
192
- assert_equal 'test', puzzle.props[:author]
193
- assert_nil puzzle.props[:email]
194
- assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/, puzzle.props[:time])
240
+ stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
241
+ list = source.puzzles
242
+ assert_equal 1, list.size
243
+ puzzle = list.first
244
+ assert_equal '1-de87adc8', puzzle.props[:id]
245
+ assert_equal '1-1', puzzle.props[:lines]
246
+ assert_equal 'this is the puzzle', puzzle.props[:body]
247
+ assert_equal 'test', puzzle.props[:author]
248
+ assert_nil puzzle.props[:email]
249
+ assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
250
+ puzzle.props[:time])
251
+ end
195
252
  end
196
253
  end
197
254
 
@@ -207,10 +264,35 @@ class TestSource < Minitest::Test
207
264
  git add a.txt
208
265
  git commit --quiet -am 'first version'
209
266
  ")
210
- list = PDD::Source.new(File.join(dir, 'a.txt'), '').puzzles
211
- assert_equal 1, list.size
212
- puzzle = list.first
213
- assert_equal '@yegor256', puzzle.props[:author]
267
+ stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
268
+ list = source.puzzles
269
+ assert_equal 1, list.size
270
+ puzzle = list.first
271
+ assert_equal '@yegor256', puzzle.props[:author]
272
+ end
273
+ end
274
+ end
275
+
276
+ def test_skips_uncommitted_changes
277
+ skip if Gem.win_platform?
278
+ Dir.mktmpdir 'test' do |dir|
279
+ raise unless system("
280
+ cd '#{dir}'
281
+ git init --quiet .
282
+ git config user.email yegor256@gmail.com
283
+ git config user.name test
284
+ echo 'hi' > a.txt
285
+ git add a.txt
286
+ git commit --quiet -am 'first version'
287
+ echo '\x40todo #1 this is a puzzle uncommitted' > a.txt
288
+ ")
289
+ stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
290
+ list = source.puzzles
291
+ assert_equal 1, list.size
292
+ puzzle = list.first
293
+ assert_nil puzzle.props[:email]
294
+ assert_equal 'Not Committed Yet', puzzle.props[:author]
295
+ end
214
296
  end
215
297
  end
216
298
 
@@ -221,12 +303,14 @@ class TestSource < Minitest::Test
221
303
  file,
222
304
  '<!--/* @todo #123 puzzle info */-->'
223
305
  )
224
- list = PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
225
- assert_equal 1, list.size
226
- puzzle = list.first
227
- assert_equal '1-1', puzzle.props[:lines]
228
- assert_equal 'puzzle info', puzzle.props[:body]
229
- assert_equal '123', puzzle.props[:ticket]
306
+ stub_source_find_github_user(file, 'hey') do |source|
307
+ list = source.puzzles
308
+ assert_equal 1, list.size
309
+ puzzle = list.first
310
+ assert_equal '1-1', puzzle.props[:lines]
311
+ assert_equal 'puzzle info', puzzle.props[:body]
312
+ assert_equal '123', puzzle.props[:ticket]
313
+ end
230
314
  end
231
315
  end
232
316
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -24,16 +24,18 @@ require_relative '../lib/pdd'
24
24
  require_relative '../lib/pdd/sources'
25
25
 
26
26
  class TestSourceTodo < Minitest::Test
27
- def check_valid_puzzle(text, lines, body, ticket)
27
+ def check_valid_puzzle(text, lines, body, ticket, count = 1)
28
28
  Dir.mktmpdir 'test' do |dir|
29
29
  file = File.join(dir, 'a.txt')
30
30
  File.write(file, text)
31
- list = PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
32
- assert_equal 1, list.size
33
- puzzle = list.first
34
- assert_equal lines, puzzle.props[:lines]
35
- assert_equal body, puzzle.props[:body]
36
- assert_equal ticket, puzzle.props[:ticket]
31
+ stub_source_find_github_user(file, 'hey') do |source|
32
+ list = source.puzzles
33
+ assert_equal count, list.size
34
+ puzzle = list.first
35
+ assert_equal lines, puzzle.props[:lines]
36
+ assert_equal body, puzzle.props[:body]
37
+ assert_equal ticket, puzzle.props[:ticket]
38
+ end
37
39
  end
38
40
  end
39
41
 
@@ -42,7 +44,7 @@ class TestSourceTodo < Minitest::Test
42
44
  file = File.join(dir, 'a.txt')
43
45
  File.write(file, text)
44
46
  error = assert_raises PDD::Error do
45
- PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
47
+ stub_source_find_github_user(file, 'hey', &:puzzles)
46
48
  end
47
49
  assert !error.message.index(error_msg).nil?
48
50
  end
@@ -82,6 +84,19 @@ class TestSourceTodo < Minitest::Test
82
84
  )
83
85
  end
84
86
 
87
+ def test_multiple_todo_colon
88
+ check_valid_puzzle(
89
+ "
90
+ // TODO: #45 task description
91
+ // TODO: #46 another task description
92
+ ",
93
+ '2-2',
94
+ 'task description',
95
+ '45',
96
+ 2
97
+ )
98
+ end
99
+
85
100
  def test_todo_colon_parsing_multi_line
86
101
  check_valid_puzzle(
87
102
  "
data/test/test_sources.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -26,7 +26,7 @@ require_relative '../lib/pdd/sources'
26
26
 
27
27
  # Sources test.
28
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
29
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
30
30
  # License:: MIT
31
31
  class TestSources < Minitest::Test
32
32
  def test_iterator
@@ -89,6 +89,20 @@ class TestSources < Minitest::Test
89
89
  end
90
90
  end
91
91
 
92
+ def test_includes_by_pattern
93
+ in_temp(['a/first.txt', 'b/c/d/second.txt']) do |dir|
94
+ list = PDD::Sources.new(dir).include('b/c/d/second.txt').fetch
95
+ assert_equal 1, list.size
96
+ end
97
+ end
98
+
99
+ def test_includes_recursively
100
+ in_temp(['a/first.txt', 'b/c/second.txt', 'b/c/d/third.txt']) do |dir|
101
+ list = PDD::Sources.new(dir).include('**/*').fetch
102
+ assert_equal 0, list.size
103
+ end
104
+ end
105
+
92
106
  def test_fails_with_verbose_output
93
107
  in_temp do |dir|
94
108
  File.write(File.join(dir, 'z1.txt'), "\x40todobroken\n")
data/test/test_text.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2014-2020 Yegor Bugayenko
1
+ # Copyright (c) 2014-2021 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/text'
24
24
 
25
25
  # PDD::Rule::Text module tests.
26
26
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
- # Copyright:: Copyright (c) 2014-2020 Yegor Bugayenko
27
+ # Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
28
28
  # License:: MIT
29
29
  class TestText < Minitest::Test
30
30
  def test_min_words
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.6
4
+ version: 0.20.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-01 00:00:00.000000000 Z
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -258,7 +258,7 @@ files:
258
258
  - test_assets/cambria.woff
259
259
  - test_assets/elegant-objects.png
260
260
  - test_assets/favicon.ico
261
- homepage: http://github.com/yegor256/pdd
261
+ homepage: http://github.com/cqfn/pdd
262
262
  licenses:
263
263
  - MIT
264
264
  metadata: {}
@@ -278,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
278
278
  - !ruby/object:Gem::Version
279
279
  version: '0'
280
280
  requirements: []
281
- rubygems_version: 3.0.1
281
+ rubygems_version: 3.1.2
282
282
  signing_key:
283
283
  specification_version: 2
284
284
  summary: Puzzle Driven Development collector