github_changelog_generator 1.15.0.pre.alpha → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +332 -275
- data/Rakefile +3 -4
- data/bin/git-generate-changelog +1 -1
- data/lib/github_changelog_generator.rb +10 -6
- data/lib/github_changelog_generator/generator/entry.rb +218 -0
- data/lib/github_changelog_generator/generator/generator.rb +126 -104
- data/lib/github_changelog_generator/generator/generator_fetcher.rb +139 -23
- data/lib/github_changelog_generator/generator/generator_processor.rb +59 -27
- data/lib/github_changelog_generator/generator/generator_tags.rb +26 -22
- data/lib/github_changelog_generator/generator/section.rb +124 -0
- data/lib/github_changelog_generator/helper.rb +1 -1
- data/lib/github_changelog_generator/octo_fetcher.rb +261 -130
- data/lib/github_changelog_generator/options.rb +74 -1
- data/lib/github_changelog_generator/parser.rb +120 -176
- data/lib/github_changelog_generator/parser_file.rb +8 -3
- data/lib/github_changelog_generator/reader.rb +2 -2
- data/lib/github_changelog_generator/task.rb +5 -6
- data/lib/github_changelog_generator/version.rb +1 -1
- data/man/git-generate-changelog.1 +144 -45
- data/man/git-generate-changelog.1.html +157 -84
- data/man/git-generate-changelog.html +19 -7
- data/man/git-generate-changelog.md +151 -84
- data/spec/files/github-changelog-generator.md +114 -114
- data/spec/{install-gem-in-bundler.gemfile → install_gem_in_bundler.gemfile} +2 -0
- data/spec/spec_helper.rb +2 -6
- data/spec/unit/generator/entry_spec.rb +766 -0
- data/spec/unit/generator/generator_processor_spec.rb +103 -41
- data/spec/unit/generator/generator_spec.rb +47 -0
- data/spec/unit/generator/generator_tags_spec.rb +56 -24
- data/spec/unit/generator/section_spec.rb +34 -0
- data/spec/unit/octo_fetcher_spec.rb +247 -197
- data/spec/unit/options_spec.rb +28 -4
- data/spec/unit/parse_file_spec.rb +2 -2
- data/spec/unit/parser_spec.rb +0 -79
- data/spec/unit/reader_spec.rb +4 -4
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -0
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_request_with_proper_key/values.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -1
- data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -1
- metadata +71 -38
- data/bin/ghclgen +0 -5
- data/lib/github_changelog_generator/generator/generator_generation.rb +0 -180
- data/spec/unit/generator/generator_generation_spec.rb +0 -17
@@ -0,0 +1,766 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitHubChangelogGenerator
|
4
|
+
RSpec.describe Entry do
|
5
|
+
def label(name)
|
6
|
+
{ "name" => name }
|
7
|
+
end
|
8
|
+
|
9
|
+
def issue(title, labels, body = "", number = "1", user = { "login" => "user" })
|
10
|
+
{
|
11
|
+
"title" => "issue #{title}",
|
12
|
+
"labels" => labels.map { |l| label(l) },
|
13
|
+
"number" => number,
|
14
|
+
"html_url" => "https://github.com/owner/repo/issue/#{number}",
|
15
|
+
"user" => user,
|
16
|
+
"body" => body,
|
17
|
+
"events" => [{
|
18
|
+
"event" => "closed"
|
19
|
+
}]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def pr(title, labels, body = "", number = "1", user = { "login" => "user" })
|
24
|
+
{
|
25
|
+
"pull_request" => true,
|
26
|
+
"title" => "pr #{title}",
|
27
|
+
"labels" => labels.map { |l| label(l) },
|
28
|
+
"number" => number,
|
29
|
+
"html_url" => "https://github.com/owner/repo/pull/#{number}",
|
30
|
+
"user" => user.merge("html_url" => "https://github.com/#{user['login']}"),
|
31
|
+
"body" => body,
|
32
|
+
"merged_at" => Time.now.utc,
|
33
|
+
"events" => [{
|
34
|
+
"event" => "merged",
|
35
|
+
"commit_id" => "aaaaa#{number}"
|
36
|
+
}]
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def tag(name, sha, shas_in_tag)
|
41
|
+
{
|
42
|
+
"name" => name,
|
43
|
+
"commit" => { "sha" => sha },
|
44
|
+
"shas_in_tag" => shas_in_tag
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def titles_for(issues)
|
49
|
+
issues.map { |issue| issue["title"] }
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_sections
|
53
|
+
%w[breaking enhancements bugs deprecated removed security issues]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Default to no issues, PRs, or tags.
|
57
|
+
let(:issues) { [] }
|
58
|
+
let(:pull_requests) { [] }
|
59
|
+
let(:tags) { [] }
|
60
|
+
|
61
|
+
# Default to standard options minus verbose to avoid output during testing.
|
62
|
+
let(:options) do
|
63
|
+
Parser.default_options.merge(verbose: false)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Mock out fake github fetching for the issues/pull_requests lets and then
|
67
|
+
# expose filtering from the GitHubChangelogGenerator::Generator class
|
68
|
+
# instance for end-to-end entry testing.
|
69
|
+
let(:generator) do
|
70
|
+
fake_fetcher = instance_double(
|
71
|
+
"fetcher",
|
72
|
+
fetch_closed_issues_and_pr: [issues, pull_requests],
|
73
|
+
fetch_closed_pull_requests: [],
|
74
|
+
fetch_events_async: issues + pull_requests,
|
75
|
+
fetch_tag_shas: nil,
|
76
|
+
fetch_comments_async: nil,
|
77
|
+
default_branch: "master",
|
78
|
+
oldest_commit: { "sha" => "aaaaa1" },
|
79
|
+
fetch_commit: { "commit" => { "author" => { "date" => Time.now.utc } } }
|
80
|
+
)
|
81
|
+
allow(fake_fetcher).to receive(:commits_in_branch) do
|
82
|
+
["aaaaa1"]
|
83
|
+
end
|
84
|
+
allow(GitHubChangelogGenerator::OctoFetcher).to receive(:new).and_return(fake_fetcher)
|
85
|
+
generator = GitHubChangelogGenerator::Generator.new(options)
|
86
|
+
generator.instance_variable_set :@sorted_tags, tags
|
87
|
+
generator.send(:fetch_issues_and_pr)
|
88
|
+
generator
|
89
|
+
end
|
90
|
+
let(:filtered_issues) do
|
91
|
+
generator.instance_variable_get :@issues
|
92
|
+
end
|
93
|
+
let(:filtered_pull_requests) do
|
94
|
+
generator.instance_variable_get :@pull_requests
|
95
|
+
end
|
96
|
+
let(:entry_sections) do
|
97
|
+
subject.send(:create_sections)
|
98
|
+
# In normal usage, the entry generation would have received filtered
|
99
|
+
# issues and pull requests so replicate that here for ease of testing.
|
100
|
+
subject.send(:sort_into_sections, filtered_pull_requests, filtered_issues)
|
101
|
+
subject.instance_variable_get :@sections
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#generate_entry_for_tag" do
|
105
|
+
let(:issues) do
|
106
|
+
[
|
107
|
+
issue("no labels", [], "", "5", "login" => "user1"),
|
108
|
+
issue("breaking", ["breaking"], "", "8", "login" => "user5"),
|
109
|
+
issue("enhancement", ["enhancement"], "", "6", "login" => "user2"),
|
110
|
+
issue("bug", ["bug"], "", "7", "login" => "user1"),
|
111
|
+
issue("deprecated", ["deprecated"], "", "13", "login" => "user5"),
|
112
|
+
issue("removed", ["removed"], "", "14", "login" => "user2"),
|
113
|
+
issue("security", ["security"], "", "15", "login" => "user5"),
|
114
|
+
issue("all the labels", %w[breaking enhancement bug deprecated removed security], "", "9", "login" => "user9"),
|
115
|
+
issue("all the labels different order", %w[bug breaking enhancement security removed deprecated], "", "10", "login" => "user5"),
|
116
|
+
issue("some unmapped labels", %w[tests-fail bug], "", "11", "login" => "user5"),
|
117
|
+
issue("no mapped labels", %w[docs maintenance], "", "12", "login" => "user5")
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:pull_requests) do
|
122
|
+
[
|
123
|
+
pr("no labels", [], "", "20", "login" => "user1"),
|
124
|
+
pr("breaking", ["breaking"], "", "23", "login" => "user5"),
|
125
|
+
pr("enhancement", ["enhancement"], "", "21", "login" => "user5"),
|
126
|
+
pr("bug", ["bug"], "", "22", "login" => "user5"),
|
127
|
+
pr("deprecated", ["deprecated"], "", "28", "login" => "user5"),
|
128
|
+
pr("removed", ["removed"], "", "29", "login" => "user2"),
|
129
|
+
pr("security", ["security"], "", "30", "login" => "user5"),
|
130
|
+
pr("all the labels", %w[breaking enhancement bug deprecated removed security], "", "24", "login" => "user5"),
|
131
|
+
pr("all the labels different order", %w[bug breaking enhancement security remove deprecated], "", "25", "login" => "user5"),
|
132
|
+
pr("some unmapped labels", %w[tests-fail bug], "", "26", "login" => "user5"),
|
133
|
+
pr("no mapped labels", %w[docs maintenance], "", "27", "login" => "user5")
|
134
|
+
]
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:tags) do
|
138
|
+
[tag("1.0.0", "aaaaa30", (1..30).collect { |i| "aaaaa#{i}" })]
|
139
|
+
end
|
140
|
+
|
141
|
+
subject { described_class.new(options) }
|
142
|
+
describe "include issues without labels" do
|
143
|
+
let(:options) do
|
144
|
+
Parser.default_options.merge(
|
145
|
+
user: "owner",
|
146
|
+
project: "repo",
|
147
|
+
breaking_labels: ["breaking"],
|
148
|
+
enhancement_labels: ["enhancement"],
|
149
|
+
bug_labels: ["bug"],
|
150
|
+
deprecated_labels: ["deprecated"],
|
151
|
+
removed_labels: ["removed"],
|
152
|
+
security_labels: ["security"],
|
153
|
+
verbose: false
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "generates a header and body" do
|
158
|
+
changelog = <<-CHANGELOG.gsub(/^ {10}/, "")
|
159
|
+
## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04)
|
160
|
+
|
161
|
+
[Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1)
|
162
|
+
|
163
|
+
**Breaking changes:**
|
164
|
+
|
165
|
+
- issue breaking [\\#8](https://github.com/owner/repo/issue/8)
|
166
|
+
- issue all the labels [\\#9](https://github.com/owner/repo/issue/9)
|
167
|
+
- issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10)
|
168
|
+
- pr breaking [\\#23](https://github.com/owner/repo/pull/23) ([user5](https://github.com/user5))
|
169
|
+
- pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5))
|
170
|
+
- pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5))
|
171
|
+
|
172
|
+
**Implemented enhancements:**
|
173
|
+
|
174
|
+
- issue enhancement [\\#6](https://github.com/owner/repo/issue/6)
|
175
|
+
- pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5))
|
176
|
+
|
177
|
+
**Fixed bugs:**
|
178
|
+
|
179
|
+
- issue bug [\\#7](https://github.com/owner/repo/issue/7)
|
180
|
+
- issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11)
|
181
|
+
- pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5))
|
182
|
+
- pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5))
|
183
|
+
|
184
|
+
**Deprecated:**
|
185
|
+
|
186
|
+
- issue deprecated [\\#13](https://github.com/owner/repo/issue/13)
|
187
|
+
- pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5))
|
188
|
+
|
189
|
+
**Removed:**
|
190
|
+
|
191
|
+
- issue removed [\\#14](https://github.com/owner/repo/issue/14)
|
192
|
+
- pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2))
|
193
|
+
|
194
|
+
**Security fixes:**
|
195
|
+
|
196
|
+
- issue security [\\#15](https://github.com/owner/repo/issue/15)
|
197
|
+
- pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5))
|
198
|
+
|
199
|
+
**Closed issues:**
|
200
|
+
|
201
|
+
- issue no labels [\\#5](https://github.com/owner/repo/issue/5)
|
202
|
+
- issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12)
|
203
|
+
|
204
|
+
**Merged pull requests:**
|
205
|
+
|
206
|
+
- pr no labels [\\#20](https://github.com/owner/repo/pull/20) ([user1](https://github.com/user1))
|
207
|
+
- pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5))
|
208
|
+
|
209
|
+
CHANGELOG
|
210
|
+
|
211
|
+
expect(subject.generate_entry_for_tag(pull_requests, issues, "1.0.1", "1.0.1", Time.new(2017, 12, 4, 12, 0, 0, "+00:00").utc, "1.0.0")).to eq(changelog)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "#create_entry_for_tag_with_body" do
|
216
|
+
let(:options) do
|
217
|
+
Parser.default_options.merge(
|
218
|
+
user: "owner",
|
219
|
+
project: "repo",
|
220
|
+
bug_labels: ["bug"],
|
221
|
+
enhancement_labels: ["enhancement"],
|
222
|
+
breaking_labels: ["breaking"],
|
223
|
+
issue_line_body: true
|
224
|
+
)
|
225
|
+
end
|
226
|
+
|
227
|
+
let(:issues_with_body) do
|
228
|
+
[
|
229
|
+
issue("no labels", [], "Issue body description", "5", "login" => "user1"),
|
230
|
+
issue("breaking", ["breaking"], "Issue body description very long: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.", "8", "login" => "user5"),
|
231
|
+
issue("enhancement", ["enhancement"], "Issue body description", "6", "login" => "user2"),
|
232
|
+
issue("bug", ["bug"], "Issue body description", "7", "login" => "user1"),
|
233
|
+
issue("deprecated", ["deprecated"], "Issue body description", "13", "login" => "user5"),
|
234
|
+
issue("removed", ["removed"], "Issue body description", "14", "login" => "user2"),
|
235
|
+
issue("security", ["security"], "Issue body description", "15", "login" => "user5"),
|
236
|
+
issue("all the labels", %w[breaking enhancement bug deprecated removed security], "Issue body description. \nThis part should not appear.", "9", "login" => "user9"),
|
237
|
+
issue("all the labels different order", %w[bug breaking enhancement security removed deprecated], "Issue body description", "10", "login" => "user5"),
|
238
|
+
issue("some unmapped labels", %w[tests-fail bug], "Issue body description", "11", "login" => "user5"),
|
239
|
+
issue("no mapped labels", %w[docs maintenance], "Issue body description", "12", "login" => "user5")
|
240
|
+
]
|
241
|
+
end
|
242
|
+
|
243
|
+
let(:pull_requests_with_body) do
|
244
|
+
[
|
245
|
+
pr("no labels", [], "PR body description", "20", "login" => "user1"),
|
246
|
+
pr("breaking", ["breaking"], "PR body description very long: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.", "23", "login" => "user5"),
|
247
|
+
pr("enhancement", ["enhancement"], "PR body description", "21", "login" => "user5"),
|
248
|
+
pr("bug", ["bug"], "PR body description", "22", "login" => "user5"),
|
249
|
+
pr("deprecated", ["deprecated"], "PR body description", "28", "login" => "user5"),
|
250
|
+
pr("removed", ["removed"], "PR body description", "29", "login" => "user2"),
|
251
|
+
pr("security", ["security"], "PR body description", "30", "login" => "user5"),
|
252
|
+
pr("all the labels", %w[breaking enhancement bug deprecated removed security], "PR body description. \nThis part should not appear", "24", "login" => "user5"),
|
253
|
+
pr("all the labels different order", %w[bug breaking enhancement security remove deprecated], "PR body description", "25", "login" => "user5"),
|
254
|
+
pr("some unmapped labels", %w[tests-fail bug], "PR body description", "26", "login" => "user5"),
|
255
|
+
pr("no mapped labels", %w[docs maintenance], "PR body description", "27", "login" => "user5")
|
256
|
+
]
|
257
|
+
end
|
258
|
+
|
259
|
+
subject { described_class.new(options) }
|
260
|
+
it "generates issues and pull requests with body" do
|
261
|
+
changelog = <<-CHANGELOG.gsub(/^ {10}/, "")
|
262
|
+
## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04)
|
263
|
+
|
264
|
+
[Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1)
|
265
|
+
|
266
|
+
**Breaking changes:**
|
267
|
+
|
268
|
+
- **issue breaking [\\#8](https://github.com/owner/repo/issue/8)** \nIssue body description very long: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.
|
269
|
+
- **issue all the labels [\\#9](https://github.com/owner/repo/issue/9)** \nIssue body description.
|
270
|
+
- **issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10)** \nIssue body description
|
271
|
+
- **pr breaking [\\#23](https://github.com/owner/repo/pull/23) ([user5](https://github.com/user5))** \nPR body description very long: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.
|
272
|
+
- **pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5))** \nPR body description.
|
273
|
+
- **pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5))** \nPR body description
|
274
|
+
|
275
|
+
**Implemented enhancements:**
|
276
|
+
|
277
|
+
- **issue enhancement [\\#6](https://github.com/owner/repo/issue/6)** \nIssue body description
|
278
|
+
- **pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5))** \nPR body description
|
279
|
+
|
280
|
+
**Fixed bugs:**
|
281
|
+
|
282
|
+
- **issue bug [\\#7](https://github.com/owner/repo/issue/7)** \nIssue body description
|
283
|
+
- **issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11)** \nIssue body description
|
284
|
+
- **pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5))** \nPR body description
|
285
|
+
- **pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5))** \nPR body description
|
286
|
+
|
287
|
+
**Deprecated:**
|
288
|
+
|
289
|
+
- **issue deprecated [\\#13](https://github.com/owner/repo/issue/13)** \nIssue body description
|
290
|
+
- **pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5))** \nPR body description
|
291
|
+
|
292
|
+
**Removed:**
|
293
|
+
|
294
|
+
- **issue removed [\\#14](https://github.com/owner/repo/issue/14)** \nIssue body description
|
295
|
+
- **pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2))** \nPR body description
|
296
|
+
|
297
|
+
**Security fixes:**
|
298
|
+
|
299
|
+
- **issue security [\\#15](https://github.com/owner/repo/issue/15)** \nIssue body description
|
300
|
+
- **pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5))** \nPR body description
|
301
|
+
|
302
|
+
**Closed issues:**
|
303
|
+
|
304
|
+
- **issue no labels [\\#5](https://github.com/owner/repo/issue/5)** \nIssue body description
|
305
|
+
- **issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12)** \nIssue body description
|
306
|
+
|
307
|
+
**Merged pull requests:**
|
308
|
+
|
309
|
+
- **pr no labels [\\#20](https://github.com/owner/repo/pull/20) ([user1](https://github.com/user1))** \nPR body description
|
310
|
+
- **pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5))** \nPR body description
|
311
|
+
|
312
|
+
CHANGELOG
|
313
|
+
expect(subject.generate_entry_for_tag(pull_requests_with_body, issues_with_body, "1.0.1", "1.0.1", Time.new(2017, 12, 4, 12, 0, 0, "+00:00").utc, "1.0.0")).to eq(changelog)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe "exclude issues without labels" do
|
318
|
+
let(:options) do
|
319
|
+
Parser.default_options.merge(
|
320
|
+
user: "owner",
|
321
|
+
project: "repo",
|
322
|
+
breaking_labels: ["breaking"],
|
323
|
+
enhancement_labels: ["enhancement"],
|
324
|
+
bug_labels: ["bug"],
|
325
|
+
deprecated_labels: ["deprecated"],
|
326
|
+
removed_labels: ["removed"],
|
327
|
+
security_labels: ["security"],
|
328
|
+
add_pr_wo_labels: false,
|
329
|
+
add_issues_wo_labels: false,
|
330
|
+
verbose: false
|
331
|
+
)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "generates a header and body" do
|
335
|
+
changelog = <<-CHANGELOG.gsub(/^ {10}/, "")
|
336
|
+
## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04)
|
337
|
+
|
338
|
+
[Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1)
|
339
|
+
|
340
|
+
**Breaking changes:**
|
341
|
+
|
342
|
+
- issue breaking [\\#8](https://github.com/owner/repo/issue/8)
|
343
|
+
- issue all the labels [\\#9](https://github.com/owner/repo/issue/9)
|
344
|
+
- issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10)
|
345
|
+
- pr breaking [\\#23](https://github.com/owner/repo/pull/23) ([user5](https://github.com/user5))
|
346
|
+
- pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5))
|
347
|
+
- pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5))
|
348
|
+
|
349
|
+
**Implemented enhancements:**
|
350
|
+
|
351
|
+
- issue enhancement [\\#6](https://github.com/owner/repo/issue/6)
|
352
|
+
- pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5))
|
353
|
+
|
354
|
+
**Fixed bugs:**
|
355
|
+
|
356
|
+
- issue bug [\\#7](https://github.com/owner/repo/issue/7)
|
357
|
+
- issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11)
|
358
|
+
- pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5))
|
359
|
+
- pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5))
|
360
|
+
|
361
|
+
**Deprecated:**
|
362
|
+
|
363
|
+
- issue deprecated [\\#13](https://github.com/owner/repo/issue/13)
|
364
|
+
- pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5))
|
365
|
+
|
366
|
+
**Removed:**
|
367
|
+
|
368
|
+
- issue removed [\\#14](https://github.com/owner/repo/issue/14)
|
369
|
+
- pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2))
|
370
|
+
|
371
|
+
**Security fixes:**
|
372
|
+
|
373
|
+
- issue security [\\#15](https://github.com/owner/repo/issue/15)
|
374
|
+
- pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5))
|
375
|
+
|
376
|
+
**Closed issues:**
|
377
|
+
|
378
|
+
- issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12)
|
379
|
+
|
380
|
+
**Merged pull requests:**
|
381
|
+
|
382
|
+
- pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5))
|
383
|
+
|
384
|
+
CHANGELOG
|
385
|
+
|
386
|
+
expect(subject.generate_entry_for_tag(pull_requests, issues, "1.0.1", "1.0.1", Time.new(2017, 12, 4, 12, 0, 0, "+00:00").utc, "1.0.0")).to eq(changelog)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
describe "#parse_sections" do
|
391
|
+
before do
|
392
|
+
subject { described_class.new }
|
393
|
+
end
|
394
|
+
context "valid json" do
|
395
|
+
let(:sections_string) { "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}" }
|
396
|
+
|
397
|
+
let(:sections_array) do
|
398
|
+
[
|
399
|
+
Section.new(name: "foo", prefix: "foofix", labels: %w[test1 test2]),
|
400
|
+
Section.new(name: "bar", prefix: "barfix", labels: %w[test3 test4])
|
401
|
+
]
|
402
|
+
end
|
403
|
+
|
404
|
+
it "returns an array with 2 objects" do
|
405
|
+
arr = subject.send(:parse_sections, sections_string)
|
406
|
+
expect(arr.size).to eq 2
|
407
|
+
arr.each { |section| expect(section).to be_an_instance_of Section }
|
408
|
+
end
|
409
|
+
|
410
|
+
it "returns correctly constructed sections" do
|
411
|
+
require "json"
|
412
|
+
|
413
|
+
sections_json = JSON.parse(sections_string)
|
414
|
+
sections_array.each_index do |i|
|
415
|
+
aggregate_failures "checks each component" do
|
416
|
+
expect(sections_array[i].name).to eq sections_json.first[0]
|
417
|
+
expect(sections_array[i].prefix).to eq sections_json.first[1]["prefix"]
|
418
|
+
expect(sections_array[i].labels).to eq sections_json.first[1]["labels"]
|
419
|
+
expect(sections_array[i].issues).to eq []
|
420
|
+
end
|
421
|
+
sections_json.shift
|
422
|
+
end
|
423
|
+
end
|
424
|
+
context "parse also body_only" do
|
425
|
+
let(:sections_string) { "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"], \"body_only\": true}}" }
|
426
|
+
|
427
|
+
it "returns correctly constructed sections" do
|
428
|
+
require "json"
|
429
|
+
|
430
|
+
parsed_sections = subject.send(:parse_sections, sections_string)
|
431
|
+
|
432
|
+
expect(parsed_sections[0].body_only).to eq false
|
433
|
+
expect(parsed_sections[1].body_only).to eq true
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
context "hash" do
|
438
|
+
let(:sections_hash) do
|
439
|
+
{
|
440
|
+
breaking: {
|
441
|
+
prefix: "**Breaking**",
|
442
|
+
labels: ["breaking"]
|
443
|
+
},
|
444
|
+
enhancements: {
|
445
|
+
prefix: "**Enhancements**",
|
446
|
+
labels: %w[feature enhancement]
|
447
|
+
},
|
448
|
+
bugs: {
|
449
|
+
prefix: "**Bugs**",
|
450
|
+
labels: ["bug"]
|
451
|
+
},
|
452
|
+
deprecated: {
|
453
|
+
prefix: "**Deprecated**",
|
454
|
+
labels: ["deprecated"]
|
455
|
+
},
|
456
|
+
removed: {
|
457
|
+
prefix: "**Removed**",
|
458
|
+
labels: ["removed"]
|
459
|
+
},
|
460
|
+
security: {
|
461
|
+
prefix: "**Security**",
|
462
|
+
labels: ["security"]
|
463
|
+
}
|
464
|
+
}
|
465
|
+
end
|
466
|
+
|
467
|
+
let(:sections_array) do
|
468
|
+
[
|
469
|
+
Section.new(name: "breaking", prefix: "**Breaking**", labels: ["breaking"]),
|
470
|
+
Section.new(name: "enhancements", prefix: "**Enhancements**", labels: %w[feature enhancement]),
|
471
|
+
Section.new(name: "bugs", prefix: "**Bugs**", labels: ["bug"]),
|
472
|
+
Section.new(name: "deprecated", prefix: "**Deprecated**", labels: ["deprecated"]),
|
473
|
+
Section.new(name: "removed", prefix: "**Removed**", labels: ["removed"]),
|
474
|
+
Section.new(name: "security", prefix: "**Security**", labels: ["security"])
|
475
|
+
]
|
476
|
+
end
|
477
|
+
|
478
|
+
it "returns an array with 6 objects" do
|
479
|
+
arr = subject.send(:parse_sections, sections_hash)
|
480
|
+
expect(arr.size).to eq 6
|
481
|
+
arr.each { |section| expect(section).to be_an_instance_of Section }
|
482
|
+
end
|
483
|
+
|
484
|
+
it "returns correctly constructed sections" do
|
485
|
+
sections_array.each_index do |i|
|
486
|
+
aggregate_failures "checks each component" do
|
487
|
+
expect(sections_array[i].name).to eq sections_hash.first[0].to_s
|
488
|
+
expect(sections_array[i].prefix).to eq sections_hash.first[1][:prefix]
|
489
|
+
expect(sections_array[i].labels).to eq sections_hash.first[1][:labels]
|
490
|
+
expect(sections_array[i].issues).to eq []
|
491
|
+
end
|
492
|
+
sections_hash.shift
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
describe "#sort_into_sections" do
|
499
|
+
context "default sections" do
|
500
|
+
let(:options) do
|
501
|
+
Parser.default_options.merge(
|
502
|
+
breaking_labels: ["breaking"],
|
503
|
+
enhancement_labels: ["enhancement"],
|
504
|
+
bug_labels: ["bug"],
|
505
|
+
deprecated_labels: ["deprecated"],
|
506
|
+
removed_labels: ["removed"],
|
507
|
+
security_labels: ["security"],
|
508
|
+
verbose: false
|
509
|
+
)
|
510
|
+
end
|
511
|
+
|
512
|
+
let(:issues) do
|
513
|
+
[
|
514
|
+
issue("breaking", ["breaking"]),
|
515
|
+
issue("no labels", []),
|
516
|
+
issue("enhancement", ["enhancement"]),
|
517
|
+
issue("bug", ["bug"]),
|
518
|
+
issue("deprecated", ["deprecated"]),
|
519
|
+
issue("removed", ["removed"]),
|
520
|
+
issue("security", ["security"]),
|
521
|
+
issue("all the labels", %w[breaking enhancement bug deprecated removed security]),
|
522
|
+
issue("some unmapped labels", %w[tests-fail bug]),
|
523
|
+
issue("no mapped labels", %w[docs maintenance]),
|
524
|
+
issue("excluded label", %w[wontfix]),
|
525
|
+
issue("excluded and included label", %w[breaking wontfix])
|
526
|
+
]
|
527
|
+
end
|
528
|
+
|
529
|
+
let(:pull_requests) do
|
530
|
+
[
|
531
|
+
pr("no labels", []),
|
532
|
+
pr("breaking", ["breaking"]),
|
533
|
+
pr("enhancement", ["enhancement"]),
|
534
|
+
pr("bug", ["bug"]),
|
535
|
+
pr("deprecated", ["deprecated"]),
|
536
|
+
pr("removed", ["removed"]),
|
537
|
+
pr("security", ["security"]),
|
538
|
+
pr("all the labels", %w[breaking enhancement bug deprecated removed security]),
|
539
|
+
pr("some unmapped labels", %w[tests-fail bug]),
|
540
|
+
pr("no mapped labels", %w[docs maintenance]),
|
541
|
+
pr("excluded label", %w[wontfix]),
|
542
|
+
pr("excluded and included label", %w[breaking wontfix])
|
543
|
+
]
|
544
|
+
end
|
545
|
+
|
546
|
+
subject { described_class.new(options) }
|
547
|
+
|
548
|
+
it "returns 9 sections" do
|
549
|
+
entry_sections.each { |sec| pp(sec.name) }
|
550
|
+
expect(entry_sections.size).to eq 9
|
551
|
+
end
|
552
|
+
|
553
|
+
it "returns default sections" do
|
554
|
+
default_sections.each { |default_section| expect(entry_sections.count { |section| section.name == default_section }).to eq 1 }
|
555
|
+
end
|
556
|
+
|
557
|
+
it "assigns issues to the correct sections" do
|
558
|
+
breaking_section = entry_sections.find { |section| section.name == "breaking" }
|
559
|
+
enhancement_section = entry_sections.find { |section| section.name == "enhancements" }
|
560
|
+
bug_section = entry_sections.find { |section| section.name == "bugs" }
|
561
|
+
deprecated_section = entry_sections.find { |section| section.name == "deprecated" }
|
562
|
+
removed_section = entry_sections.find { |section| section.name == "removed" }
|
563
|
+
security_section = entry_sections.find { |section| section.name == "security" }
|
564
|
+
issue_section = entry_sections.find { |section| section.name == "issues" }
|
565
|
+
merged_section = entry_sections.find { |section| section.name == "merged" }
|
566
|
+
|
567
|
+
expect(titles_for(breaking_section.issues)).to eq(["issue breaking", "issue all the labels", "pr breaking", "pr all the labels"])
|
568
|
+
expect(titles_for(enhancement_section.issues)).to eq(["issue enhancement", "pr enhancement"])
|
569
|
+
expect(titles_for(bug_section.issues)).to eq(["issue bug", "issue some unmapped labels", "pr bug", "pr some unmapped labels"])
|
570
|
+
expect(titles_for(deprecated_section.issues)).to eq(["issue deprecated", "pr deprecated"])
|
571
|
+
expect(titles_for(removed_section.issues)).to eq(["issue removed", "pr removed"])
|
572
|
+
expect(titles_for(security_section.issues)).to eq(["issue security", "pr security"])
|
573
|
+
expect(titles_for(issue_section.issues)).to eq(["issue no labels", "issue no mapped labels"])
|
574
|
+
expect(titles_for(merged_section.issues)).to eq(["pr no labels", "pr no mapped labels"])
|
575
|
+
end
|
576
|
+
end
|
577
|
+
context "configure sections and include labels" do
|
578
|
+
let(:options) do
|
579
|
+
Parser.default_options.merge(
|
580
|
+
configure_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}",
|
581
|
+
include_labels: %w[test1 test2 test3 test4],
|
582
|
+
verbose: false
|
583
|
+
)
|
584
|
+
end
|
585
|
+
|
586
|
+
let(:issues) do
|
587
|
+
[
|
588
|
+
issue("no labels", []),
|
589
|
+
issue("test1", ["test1"]),
|
590
|
+
issue("test3", ["test3"]),
|
591
|
+
issue("test4", ["test4"]),
|
592
|
+
issue("all the labels", %w[test4 test2 test3 test1]),
|
593
|
+
issue("some included labels", %w[unincluded test2]),
|
594
|
+
issue("no included labels", %w[unincluded again])
|
595
|
+
]
|
596
|
+
end
|
597
|
+
|
598
|
+
let(:pull_requests) do
|
599
|
+
[
|
600
|
+
pr("no labels", []),
|
601
|
+
pr("test1", ["test1"]),
|
602
|
+
pr("test3", ["test3"]),
|
603
|
+
pr("test4", ["test4"]),
|
604
|
+
pr("all the labels", %w[test4 test2 test3 test1]),
|
605
|
+
pr("some included labels", %w[unincluded test2]),
|
606
|
+
pr("no included labels", %w[unincluded again])
|
607
|
+
]
|
608
|
+
end
|
609
|
+
|
610
|
+
subject { described_class.new(options) }
|
611
|
+
|
612
|
+
it "returns 4 sections" do
|
613
|
+
expect(entry_sections.size).to eq 4
|
614
|
+
end
|
615
|
+
|
616
|
+
it "returns only configured sections" do
|
617
|
+
expect(entry_sections.count { |section| section.name == "foo" }).to eq 1
|
618
|
+
expect(entry_sections.count { |section| section.name == "bar" }).to eq 1
|
619
|
+
end
|
620
|
+
|
621
|
+
it "assigns issues to the correct sections" do
|
622
|
+
foo_section = entry_sections.find { |section| section.name == "foo" }
|
623
|
+
bar_section = entry_sections.find { |section| section.name == "bar" }
|
624
|
+
issue_section = entry_sections.find { |section| section.name == "issues" }
|
625
|
+
merged_section = entry_sections.find { |section| section.name == "merged" }
|
626
|
+
|
627
|
+
aggregate_failures "checks all sections" do
|
628
|
+
expect(titles_for(foo_section.issues)).to eq(["issue test1", "issue all the labels", "issue some included labels", "pr test1", "pr all the labels", "pr some included labels"])
|
629
|
+
expect(titles_for(bar_section.issues)).to eq(["issue test3", "issue test4", "pr test3", "pr test4"])
|
630
|
+
expect(titles_for(merged_section.issues)).to eq(["pr no labels"])
|
631
|
+
expect(titles_for(issue_section.issues)).to eq(["issue no labels"])
|
632
|
+
end
|
633
|
+
end
|
634
|
+
end
|
635
|
+
context "configure sections and exclude labels" do
|
636
|
+
let(:options) do
|
637
|
+
Parser.default_options.merge(
|
638
|
+
configure_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}",
|
639
|
+
exclude_labels: ["excluded"],
|
640
|
+
verbose: false
|
641
|
+
)
|
642
|
+
end
|
643
|
+
|
644
|
+
let(:issues) do
|
645
|
+
[
|
646
|
+
issue("no labels", []),
|
647
|
+
issue("test1", ["test1"]),
|
648
|
+
issue("test3", ["test3"]),
|
649
|
+
issue("test4", ["test4"]),
|
650
|
+
issue("all the labels", %w[test4 test2 test3 test1]),
|
651
|
+
issue("some excluded labels", %w[excluded test2]),
|
652
|
+
issue("excluded labels", %w[excluded again])
|
653
|
+
]
|
654
|
+
end
|
655
|
+
|
656
|
+
let(:pull_requests) do
|
657
|
+
[
|
658
|
+
pr("no labels", []),
|
659
|
+
pr("test1", ["test1"]),
|
660
|
+
pr("test3", ["test3"]),
|
661
|
+
pr("test4", ["test4"]),
|
662
|
+
pr("all the labels", %w[test4 test2 test3 test1]),
|
663
|
+
pr("some excluded labels", %w[excluded test2]),
|
664
|
+
pr("excluded labels", %w[excluded again])
|
665
|
+
]
|
666
|
+
end
|
667
|
+
|
668
|
+
subject { described_class.new(options) }
|
669
|
+
|
670
|
+
it "returns 4 sections" do
|
671
|
+
expect(entry_sections.size).to eq 4
|
672
|
+
end
|
673
|
+
|
674
|
+
it "returns only configured sections" do
|
675
|
+
expect(entry_sections.count { |section| section.name == "foo" }).to eq 1
|
676
|
+
expect(entry_sections.count { |section| section.name == "bar" }).to eq 1
|
677
|
+
end
|
678
|
+
|
679
|
+
it "assigns issues to the correct sections" do
|
680
|
+
foo_section = entry_sections.find { |section| section.name == "foo" }
|
681
|
+
bar_section = entry_sections.find { |section| section.name == "bar" }
|
682
|
+
issue_section = entry_sections.find { |section| section.name == "issues" }
|
683
|
+
merged_section = entry_sections.find { |section| section.name == "merged" }
|
684
|
+
|
685
|
+
aggregate_failures "checks all sections" do
|
686
|
+
expect(titles_for(foo_section.issues)).to eq(["issue test1", "issue all the labels", "pr test1", "pr all the labels"])
|
687
|
+
expect(titles_for(bar_section.issues)).to eq(["issue test3", "issue test4", "pr test3", "pr test4"])
|
688
|
+
expect(titles_for(merged_section.issues)).to eq(["pr no labels"])
|
689
|
+
expect(titles_for(issue_section.issues)).to eq(["issue no labels"])
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
context "add sections" do
|
694
|
+
let(:options) do
|
695
|
+
Parser.default_options.merge(
|
696
|
+
breaking_labels: ["breaking"],
|
697
|
+
enhancement_labels: ["enhancement"],
|
698
|
+
bug_labels: ["bug"],
|
699
|
+
deprecated_labels: ["deprecated"],
|
700
|
+
removed_labels: ["removed"],
|
701
|
+
security_labels: ["security"],
|
702
|
+
add_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}}",
|
703
|
+
verbose: false
|
704
|
+
)
|
705
|
+
end
|
706
|
+
|
707
|
+
let(:issues) do
|
708
|
+
[
|
709
|
+
issue("no labels", []),
|
710
|
+
issue("test1", ["test1"]),
|
711
|
+
issue("bugaboo", ["bug"]),
|
712
|
+
issue("all the labels", %w[test1 test2 breaking enhancement bug deprecated removed security]),
|
713
|
+
issue("default labels first", %w[enhancement bug test1 test2]),
|
714
|
+
issue("some excluded labels", %w[wontfix breaking]),
|
715
|
+
issue("excluded labels", %w[wontfix again])
|
716
|
+
]
|
717
|
+
end
|
718
|
+
|
719
|
+
let(:pull_requests) do
|
720
|
+
[
|
721
|
+
pr("no labels", []),
|
722
|
+
pr("test1", ["test1"]),
|
723
|
+
pr("enhance", ["enhancement"]),
|
724
|
+
pr("all the labels", %w[test1 test2 breaking enhancement bug deprecated removed security]),
|
725
|
+
pr("default labels first", %w[enhancement bug test1 test2]),
|
726
|
+
pr("some excluded labels", %w[wontfix breaking]),
|
727
|
+
pr("excluded labels", %w[wontfix again])
|
728
|
+
]
|
729
|
+
end
|
730
|
+
|
731
|
+
subject { described_class.new(options) }
|
732
|
+
|
733
|
+
it "returns 10 sections" do
|
734
|
+
entry_sections.each { |sec| pp(sec.name) }
|
735
|
+
expect(entry_sections.size).to eq 10
|
736
|
+
end
|
737
|
+
|
738
|
+
it "returns default sections" do
|
739
|
+
default_sections.each { |default_section| expect(entry_sections.count { |section| section.name == default_section }).to eq 1 }
|
740
|
+
end
|
741
|
+
|
742
|
+
it "returns added section" do
|
743
|
+
expect(entry_sections.count { |section| section.name == "foo" }).to eq 1
|
744
|
+
end
|
745
|
+
|
746
|
+
it "assigns issues to the correct sections" do
|
747
|
+
foo_section = entry_sections.find { |section| section.name == "foo" }
|
748
|
+
breaking_section = entry_sections.find { |section| section.name == "breaking" }
|
749
|
+
enhancement_section = entry_sections.find { |section| section.name == "enhancements" }
|
750
|
+
bug_section = entry_sections.find { |section| section.name == "bugs" }
|
751
|
+
issue_section = entry_sections.find { |section| section.name == "issues" }
|
752
|
+
merged_section = entry_sections.find { |section| section.name == "merged" }
|
753
|
+
|
754
|
+
aggregate_failures "checks all sections" do
|
755
|
+
expect(titles_for(breaking_section.issues)).to eq(["issue all the labels", "pr all the labels"])
|
756
|
+
expect(titles_for(enhancement_section.issues)).to eq(["issue default labels first", "pr enhance", "pr default labels first"])
|
757
|
+
expect(titles_for(bug_section.issues)).to eq(["issue bugaboo"])
|
758
|
+
expect(titles_for(foo_section.issues)).to eq(["issue test1", "pr test1"])
|
759
|
+
expect(titles_for(issue_section.issues)).to eq(["issue no labels"])
|
760
|
+
expect(titles_for(merged_section.issues)).to eq(["pr no labels"])
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
end
|