# frozen_string_literal: true module GitHubChangelogGenerator RSpec.describe Entry do def label(name) { "name" => name } end def issue(title, labels, body = "", number = "1", user = { "login" => "user" }) { "title" => "issue #{title}", "labels" => labels.map { |l| label(l) }, "number" => number, "html_url" => "https://github.com/owner/repo/issue/#{number}", "user" => user, "body" => body, "events" => [{ "event" => "closed" }] } end def pr(title, labels, body = "", number = "1", user = { "login" => "user" }) { "pull_request" => true, "title" => "pr #{title}", "labels" => labels.map { |l| label(l) }, "number" => number, "html_url" => "https://github.com/owner/repo/pull/#{number}", "user" => user.merge("html_url" => "https://github.com/#{user['login']}"), "body" => body, "merged_at" => Time.now.utc, "events" => [{ "event" => "merged", "commit_id" => "aaaaa#{number}" }] } end def tag(name, sha, shas_in_tag) { "name" => name, "commit" => { "sha" => sha }, "shas_in_tag" => shas_in_tag } end def titles_for(issues) issues.map { |issue| issue["title"] } end def default_sections %w[breaking enhancements bugs deprecated removed security issues] end # Default to no issues, PRs, or tags. let(:issues) { [] } let(:pull_requests) { [] } let(:tags) { [] } # Default to standard options minus verbose to avoid output during testing. let(:options) do Parser.default_options.merge(verbose: false) end # Mock out fake github fetching for the issues/pull_requests lets and then # expose filtering from the GitHubChangelogGenerator::Generator class # instance for end-to-end entry testing. let(:generator) do fake_fetcher = instance_double( "fetcher", fetch_closed_issues_and_pr: [issues, pull_requests], fetch_closed_pull_requests: [], fetch_events_async: issues + pull_requests, fetch_tag_shas: nil, fetch_comments_async: nil, default_branch: "master", oldest_commit: { "sha" => "aaaaa1" }, fetch_commit: { "commit" => { "author" => { "date" => Time.now.utc } } } ) allow(fake_fetcher).to receive(:commits_in_branch) do ["aaaaa1"] end allow(GitHubChangelogGenerator::OctoFetcher).to receive(:new).and_return(fake_fetcher) generator = GitHubChangelogGenerator::Generator.new(options) generator.instance_variable_set :@sorted_tags, tags generator.send(:fetch_issues_and_pr) generator end let(:filtered_issues) do generator.instance_variable_get :@issues end let(:filtered_pull_requests) do generator.instance_variable_get :@pull_requests end let(:entry_sections) do subject.send(:create_sections) # In normal usage, the entry generation would have received filtered # issues and pull requests so replicate that here for ease of testing. subject.send(:sort_into_sections, filtered_pull_requests, filtered_issues) subject.instance_variable_get :@sections end describe "#generate_entry_for_tag" do let(:issues) do [ issue("no labels", [], "", "5", "login" => "user1"), issue("breaking", ["breaking"], "", "8", "login" => "user5"), issue("enhancement", ["enhancement"], "", "6", "login" => "user2"), issue("bug", ["bug"], "", "7", "login" => "user1"), issue("deprecated", ["deprecated"], "", "13", "login" => "user5"), issue("removed", ["removed"], "", "14", "login" => "user2"), issue("security", ["security"], "", "15", "login" => "user5"), issue("all the labels", %w[breaking enhancement bug deprecated removed security], "", "9", "login" => "user9"), issue("all the labels different order", %w[bug breaking enhancement security removed deprecated], "", "10", "login" => "user5"), issue("some unmapped labels", %w[tests-fail bug], "", "11", "login" => "user5"), issue("no mapped labels", %w[docs maintenance], "", "12", "login" => "user5") ] end let(:pull_requests) do [ pr("no labels", [], "", "20", "login" => "user1"), pr("breaking", ["breaking"], "", "23", "login" => "user5"), pr("enhancement", ["enhancement"], "", "21", "login" => "user5"), pr("bug", ["bug"], "", "22", "login" => "user5"), pr("deprecated", ["deprecated"], "", "28", "login" => "user5"), pr("removed", ["removed"], "", "29", "login" => "user2"), pr("security", ["security"], "", "30", "login" => "user5"), pr("all the labels", %w[breaking enhancement bug deprecated removed security], "", "24", "login" => "user5"), pr("all the labels different order", %w[bug breaking enhancement security remove deprecated], "", "25", "login" => "user5"), pr("some unmapped labels", %w[tests-fail bug], "", "26", "login" => "user5"), pr("no mapped labels", %w[docs maintenance], "", "27", "login" => "user5") ] end let(:tags) do [tag("1.0.0", "aaaaa30", (1..30).collect { |i| "aaaaa#{i}" })] end subject { described_class.new(options) } describe "include issues without labels" do let(:options) do Parser.default_options.merge( user: "owner", project: "repo", breaking_labels: ["breaking"], enhancement_labels: ["enhancement"], bug_labels: ["bug"], deprecated_labels: ["deprecated"], removed_labels: ["removed"], security_labels: ["security"], verbose: false ) end it "generates a header and body" do changelog = <<-CHANGELOG.gsub(/^ {10}/, "") ## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04) [Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1) **Breaking changes:** - issue breaking [\\#8](https://github.com/owner/repo/issue/8) - issue all the labels [\\#9](https://github.com/owner/repo/issue/9) - issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10) - pr breaking [\\#23](https://github.com/owner/repo/pull/23) ([user5](https://github.com/user5)) - pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5)) - pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5)) **Implemented enhancements:** - issue enhancement [\\#6](https://github.com/owner/repo/issue/6) - pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5)) **Fixed bugs:** - issue bug [\\#7](https://github.com/owner/repo/issue/7) - issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11) - pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5)) - pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5)) **Deprecated:** - issue deprecated [\\#13](https://github.com/owner/repo/issue/13) - pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5)) **Removed:** - issue removed [\\#14](https://github.com/owner/repo/issue/14) - pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2)) **Security fixes:** - issue security [\\#15](https://github.com/owner/repo/issue/15) - pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5)) **Closed issues:** - issue no labels [\\#5](https://github.com/owner/repo/issue/5) - issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12) **Merged pull requests:** - pr no labels [\\#20](https://github.com/owner/repo/pull/20) ([user1](https://github.com/user1)) - pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5)) CHANGELOG 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) end end describe "#create_entry_for_tag_with_body" do let(:options) do Parser.default_options.merge( user: "owner", project: "repo", bug_labels: ["bug"], enhancement_labels: ["enhancement"], breaking_labels: ["breaking"], issue_line_body: true ) end let(:issues_with_body) do [ issue("no labels", [], "Issue body description", "5", "login" => "user1"), 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"), issue("enhancement", ["enhancement"], "Issue body description", "6", "login" => "user2"), issue("bug", ["bug"], "Issue body description", "7", "login" => "user1"), issue("deprecated", ["deprecated"], "Issue body description", "13", "login" => "user5"), issue("removed", ["removed"], "Issue body description", "14", "login" => "user2"), issue("security", ["security"], "Issue body description", "15", "login" => "user5"), issue("all the labels", %w[breaking enhancement bug deprecated removed security], "Issue body description. \nThis part should not appear.", "9", "login" => "user9"), issue("all the labels different order", %w[bug breaking enhancement security removed deprecated], "Issue body description", "10", "login" => "user5"), issue("some unmapped labels", %w[tests-fail bug], "Issue body description", "11", "login" => "user5"), issue("no mapped labels", %w[docs maintenance], "Issue body description", "12", "login" => "user5") ] end let(:pull_requests_with_body) do [ pr("no labels", [], "PR body description", "20", "login" => "user1"), 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"), pr("enhancement", ["enhancement"], "PR body description", "21", "login" => "user5"), pr("bug", ["bug"], "PR body description", "22", "login" => "user5"), pr("deprecated", ["deprecated"], "PR body description", "28", "login" => "user5"), pr("removed", ["removed"], "PR body description", "29", "login" => "user2"), pr("security", ["security"], "PR body description", "30", "login" => "user5"), pr("all the labels", %w[breaking enhancement bug deprecated removed security], "PR body description. \nThis part should not appear", "24", "login" => "user5"), pr("all the labels different order", %w[bug breaking enhancement security remove deprecated], "PR body description", "25", "login" => "user5"), pr("some unmapped labels", %w[tests-fail bug], "PR body description", "26", "login" => "user5"), pr("no mapped labels", %w[docs maintenance], "PR body description", "27", "login" => "user5") ] end subject { described_class.new(options) } it "generates issues and pull requests with body" do changelog = <<-CHANGELOG.gsub(/^ {10}/, "") ## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04) [Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1) **Breaking changes:** - **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. - **issue all the labels [\\#9](https://github.com/owner/repo/issue/9)** \nIssue body description. - **issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10)** \nIssue body description - **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. - **pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5))** \nPR body description. - **pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5))** \nPR body description **Implemented enhancements:** - **issue enhancement [\\#6](https://github.com/owner/repo/issue/6)** \nIssue body description - **pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5))** \nPR body description **Fixed bugs:** - **issue bug [\\#7](https://github.com/owner/repo/issue/7)** \nIssue body description - **issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11)** \nIssue body description - **pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5))** \nPR body description - **pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5))** \nPR body description **Deprecated:** - **issue deprecated [\\#13](https://github.com/owner/repo/issue/13)** \nIssue body description - **pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5))** \nPR body description **Removed:** - **issue removed [\\#14](https://github.com/owner/repo/issue/14)** \nIssue body description - **pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2))** \nPR body description **Security fixes:** - **issue security [\\#15](https://github.com/owner/repo/issue/15)** \nIssue body description - **pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5))** \nPR body description **Closed issues:** - **issue no labels [\\#5](https://github.com/owner/repo/issue/5)** \nIssue body description - **issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12)** \nIssue body description **Merged pull requests:** - **pr no labels [\\#20](https://github.com/owner/repo/pull/20) ([user1](https://github.com/user1))** \nPR body description - **pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5))** \nPR body description CHANGELOG 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) end end describe "exclude issues without labels" do let(:options) do Parser.default_options.merge( user: "owner", project: "repo", breaking_labels: ["breaking"], enhancement_labels: ["enhancement"], bug_labels: ["bug"], deprecated_labels: ["deprecated"], removed_labels: ["removed"], security_labels: ["security"], add_pr_wo_labels: false, add_issues_wo_labels: false, verbose: false ) end it "generates a header and body" do changelog = <<-CHANGELOG.gsub(/^ {10}/, "") ## [1.0.1](https://github.com/owner/repo/tree/1.0.1) (2017-12-04) [Full Changelog](https://github.com/owner/repo/compare/1.0.0...1.0.1) **Breaking changes:** - issue breaking [\\#8](https://github.com/owner/repo/issue/8) - issue all the labels [\\#9](https://github.com/owner/repo/issue/9) - issue all the labels different order [\\#10](https://github.com/owner/repo/issue/10) - pr breaking [\\#23](https://github.com/owner/repo/pull/23) ([user5](https://github.com/user5)) - pr all the labels [\\#24](https://github.com/owner/repo/pull/24) ([user5](https://github.com/user5)) - pr all the labels different order [\\#25](https://github.com/owner/repo/pull/25) ([user5](https://github.com/user5)) **Implemented enhancements:** - issue enhancement [\\#6](https://github.com/owner/repo/issue/6) - pr enhancement [\\#21](https://github.com/owner/repo/pull/21) ([user5](https://github.com/user5)) **Fixed bugs:** - issue bug [\\#7](https://github.com/owner/repo/issue/7) - issue some unmapped labels [\\#11](https://github.com/owner/repo/issue/11) - pr bug [\\#22](https://github.com/owner/repo/pull/22) ([user5](https://github.com/user5)) - pr some unmapped labels [\\#26](https://github.com/owner/repo/pull/26) ([user5](https://github.com/user5)) **Deprecated:** - issue deprecated [\\#13](https://github.com/owner/repo/issue/13) - pr deprecated [\\#28](https://github.com/owner/repo/pull/28) ([user5](https://github.com/user5)) **Removed:** - issue removed [\\#14](https://github.com/owner/repo/issue/14) - pr removed [\\#29](https://github.com/owner/repo/pull/29) ([user2](https://github.com/user2)) **Security fixes:** - issue security [\\#15](https://github.com/owner/repo/issue/15) - pr security [\\#30](https://github.com/owner/repo/pull/30) ([user5](https://github.com/user5)) **Closed issues:** - issue no mapped labels [\\#12](https://github.com/owner/repo/issue/12) **Merged pull requests:** - pr no mapped labels [\\#27](https://github.com/owner/repo/pull/27) ([user5](https://github.com/user5)) CHANGELOG 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) end end end describe "#parse_sections" do before do subject { described_class.new } end context "valid json" do let(:sections_string) { "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}" } let(:sections_array) do [ Section.new(name: "foo", prefix: "foofix", labels: %w[test1 test2]), Section.new(name: "bar", prefix: "barfix", labels: %w[test3 test4]) ] end it "returns an array with 2 objects" do arr = subject.send(:parse_sections, sections_string) expect(arr.size).to eq 2 arr.each { |section| expect(section).to be_an_instance_of Section } end it "returns correctly constructed sections" do require "json" sections_json = JSON.parse(sections_string) sections_array.each_index do |i| aggregate_failures "checks each component" do expect(sections_array[i].name).to eq sections_json.first[0] expect(sections_array[i].prefix).to eq sections_json.first[1]["prefix"] expect(sections_array[i].labels).to eq sections_json.first[1]["labels"] expect(sections_array[i].issues).to eq [] end sections_json.shift end end context "parse also body_only" do let(:sections_string) { "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"], \"body_only\": true}}" } it "returns correctly constructed sections" do require "json" parsed_sections = subject.send(:parse_sections, sections_string) expect(parsed_sections[0].body_only).to eq false expect(parsed_sections[1].body_only).to eq true end end end context "hash" do let(:sections_hash) do { breaking: { prefix: "**Breaking**", labels: ["breaking"] }, enhancements: { prefix: "**Enhancements**", labels: %w[feature enhancement] }, bugs: { prefix: "**Bugs**", labels: ["bug"] }, deprecated: { prefix: "**Deprecated**", labels: ["deprecated"] }, removed: { prefix: "**Removed**", labels: ["removed"] }, security: { prefix: "**Security**", labels: ["security"] } } end let(:sections_array) do [ Section.new(name: "breaking", prefix: "**Breaking**", labels: ["breaking"]), Section.new(name: "enhancements", prefix: "**Enhancements**", labels: %w[feature enhancement]), Section.new(name: "bugs", prefix: "**Bugs**", labels: ["bug"]), Section.new(name: "deprecated", prefix: "**Deprecated**", labels: ["deprecated"]), Section.new(name: "removed", prefix: "**Removed**", labels: ["removed"]), Section.new(name: "security", prefix: "**Security**", labels: ["security"]) ] end it "returns an array with 6 objects" do arr = subject.send(:parse_sections, sections_hash) expect(arr.size).to eq 6 arr.each { |section| expect(section).to be_an_instance_of Section } end it "returns correctly constructed sections" do sections_array.each_index do |i| aggregate_failures "checks each component" do expect(sections_array[i].name).to eq sections_hash.first[0].to_s expect(sections_array[i].prefix).to eq sections_hash.first[1][:prefix] expect(sections_array[i].labels).to eq sections_hash.first[1][:labels] expect(sections_array[i].issues).to eq [] end sections_hash.shift end end end end describe "#sort_into_sections" do context "default sections" do let(:options) do Parser.default_options.merge( breaking_labels: ["breaking"], enhancement_labels: ["enhancement"], bug_labels: ["bug"], deprecated_labels: ["deprecated"], removed_labels: ["removed"], security_labels: ["security"], verbose: false ) end let(:issues) do [ issue("breaking", ["breaking"]), issue("no labels", []), issue("enhancement", ["enhancement"]), issue("bug", ["bug"]), issue("deprecated", ["deprecated"]), issue("removed", ["removed"]), issue("security", ["security"]), issue("all the labels", %w[breaking enhancement bug deprecated removed security]), issue("some unmapped labels", %w[tests-fail bug]), issue("no mapped labels", %w[docs maintenance]), issue("excluded label", %w[wontfix]), issue("excluded and included label", %w[breaking wontfix]) ] end let(:pull_requests) do [ pr("no labels", []), pr("breaking", ["breaking"]), pr("enhancement", ["enhancement"]), pr("bug", ["bug"]), pr("deprecated", ["deprecated"]), pr("removed", ["removed"]), pr("security", ["security"]), pr("all the labels", %w[breaking enhancement bug deprecated removed security]), pr("some unmapped labels", %w[tests-fail bug]), pr("no mapped labels", %w[docs maintenance]), pr("excluded label", %w[wontfix]), pr("excluded and included label", %w[breaking wontfix]) ] end subject { described_class.new(options) } it "returns 9 sections" do entry_sections.each { |sec| pp(sec.name) } expect(entry_sections.size).to eq 9 end it "returns default sections" do default_sections.each { |default_section| expect(entry_sections.count { |section| section.name == default_section }).to eq 1 } end it "assigns issues to the correct sections" do breaking_section = entry_sections.find { |section| section.name == "breaking" } enhancement_section = entry_sections.find { |section| section.name == "enhancements" } bug_section = entry_sections.find { |section| section.name == "bugs" } deprecated_section = entry_sections.find { |section| section.name == "deprecated" } removed_section = entry_sections.find { |section| section.name == "removed" } security_section = entry_sections.find { |section| section.name == "security" } issue_section = entry_sections.find { |section| section.name == "issues" } merged_section = entry_sections.find { |section| section.name == "merged" } expect(titles_for(breaking_section.issues)).to eq(["issue breaking", "issue all the labels", "pr breaking", "pr all the labels"]) expect(titles_for(enhancement_section.issues)).to eq(["issue enhancement", "pr enhancement"]) expect(titles_for(bug_section.issues)).to eq(["issue bug", "issue some unmapped labels", "pr bug", "pr some unmapped labels"]) expect(titles_for(deprecated_section.issues)).to eq(["issue deprecated", "pr deprecated"]) expect(titles_for(removed_section.issues)).to eq(["issue removed", "pr removed"]) expect(titles_for(security_section.issues)).to eq(["issue security", "pr security"]) expect(titles_for(issue_section.issues)).to eq(["issue no labels", "issue no mapped labels"]) expect(titles_for(merged_section.issues)).to eq(["pr no labels", "pr no mapped labels"]) end end context "configure sections and include labels" do let(:options) do Parser.default_options.merge( configure_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}", include_labels: %w[test1 test2 test3 test4], verbose: false ) end let(:issues) do [ issue("no labels", []), issue("test1", ["test1"]), issue("test3", ["test3"]), issue("test4", ["test4"]), issue("all the labels", %w[test4 test2 test3 test1]), issue("some included labels", %w[unincluded test2]), issue("no included labels", %w[unincluded again]) ] end let(:pull_requests) do [ pr("no labels", []), pr("test1", ["test1"]), pr("test3", ["test3"]), pr("test4", ["test4"]), pr("all the labels", %w[test4 test2 test3 test1]), pr("some included labels", %w[unincluded test2]), pr("no included labels", %w[unincluded again]) ] end subject { described_class.new(options) } it "returns 4 sections" do expect(entry_sections.size).to eq 4 end it "returns only configured sections" do expect(entry_sections.count { |section| section.name == "foo" }).to eq 1 expect(entry_sections.count { |section| section.name == "bar" }).to eq 1 end it "assigns issues to the correct sections" do foo_section = entry_sections.find { |section| section.name == "foo" } bar_section = entry_sections.find { |section| section.name == "bar" } issue_section = entry_sections.find { |section| section.name == "issues" } merged_section = entry_sections.find { |section| section.name == "merged" } aggregate_failures "checks all sections" do 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"]) expect(titles_for(bar_section.issues)).to eq(["issue test3", "issue test4", "pr test3", "pr test4"]) expect(titles_for(merged_section.issues)).to eq(["pr no labels"]) expect(titles_for(issue_section.issues)).to eq(["issue no labels"]) end end end context "configure sections and exclude labels" do let(:options) do Parser.default_options.merge( configure_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}, \"bar\": { \"prefix\": \"barfix\", \"labels\": [\"test3\", \"test4\"]}}", exclude_labels: ["excluded"], verbose: false ) end let(:issues) do [ issue("no labels", []), issue("test1", ["test1"]), issue("test3", ["test3"]), issue("test4", ["test4"]), issue("all the labels", %w[test4 test2 test3 test1]), issue("some excluded labels", %w[excluded test2]), issue("excluded labels", %w[excluded again]) ] end let(:pull_requests) do [ pr("no labels", []), pr("test1", ["test1"]), pr("test3", ["test3"]), pr("test4", ["test4"]), pr("all the labels", %w[test4 test2 test3 test1]), pr("some excluded labels", %w[excluded test2]), pr("excluded labels", %w[excluded again]) ] end subject { described_class.new(options) } it "returns 4 sections" do expect(entry_sections.size).to eq 4 end it "returns only configured sections" do expect(entry_sections.count { |section| section.name == "foo" }).to eq 1 expect(entry_sections.count { |section| section.name == "bar" }).to eq 1 end it "assigns issues to the correct sections" do foo_section = entry_sections.find { |section| section.name == "foo" } bar_section = entry_sections.find { |section| section.name == "bar" } issue_section = entry_sections.find { |section| section.name == "issues" } merged_section = entry_sections.find { |section| section.name == "merged" } aggregate_failures "checks all sections" do expect(titles_for(foo_section.issues)).to eq(["issue test1", "issue all the labels", "pr test1", "pr all the labels"]) expect(titles_for(bar_section.issues)).to eq(["issue test3", "issue test4", "pr test3", "pr test4"]) expect(titles_for(merged_section.issues)).to eq(["pr no labels"]) expect(titles_for(issue_section.issues)).to eq(["issue no labels"]) end end end context "add sections" do let(:options) do Parser.default_options.merge( breaking_labels: ["breaking"], enhancement_labels: ["enhancement"], bug_labels: ["bug"], deprecated_labels: ["deprecated"], removed_labels: ["removed"], security_labels: ["security"], add_sections: "{ \"foo\": { \"prefix\": \"foofix\", \"labels\": [\"test1\", \"test2\"]}}", verbose: false ) end let(:issues) do [ issue("no labels", []), issue("test1", ["test1"]), issue("bugaboo", ["bug"]), issue("all the labels", %w[test1 test2 breaking enhancement bug deprecated removed security]), issue("default labels first", %w[enhancement bug test1 test2]), issue("some excluded labels", %w[wontfix breaking]), issue("excluded labels", %w[wontfix again]) ] end let(:pull_requests) do [ pr("no labels", []), pr("test1", ["test1"]), pr("enhance", ["enhancement"]), pr("all the labels", %w[test1 test2 breaking enhancement bug deprecated removed security]), pr("default labels first", %w[enhancement bug test1 test2]), pr("some excluded labels", %w[wontfix breaking]), pr("excluded labels", %w[wontfix again]) ] end subject { described_class.new(options) } it "returns 10 sections" do entry_sections.each { |sec| pp(sec.name) } expect(entry_sections.size).to eq 10 end it "returns default sections" do default_sections.each { |default_section| expect(entry_sections.count { |section| section.name == default_section }).to eq 1 } end it "returns added section" do expect(entry_sections.count { |section| section.name == "foo" }).to eq 1 end it "assigns issues to the correct sections" do foo_section = entry_sections.find { |section| section.name == "foo" } breaking_section = entry_sections.find { |section| section.name == "breaking" } enhancement_section = entry_sections.find { |section| section.name == "enhancements" } bug_section = entry_sections.find { |section| section.name == "bugs" } issue_section = entry_sections.find { |section| section.name == "issues" } merged_section = entry_sections.find { |section| section.name == "merged" } aggregate_failures "checks all sections" do expect(titles_for(breaking_section.issues)).to eq(["issue all the labels", "pr all the labels"]) expect(titles_for(enhancement_section.issues)).to eq(["issue default labels first", "pr enhance", "pr default labels first"]) expect(titles_for(bug_section.issues)).to eq(["issue bugaboo"]) expect(titles_for(foo_section.issues)).to eq(["issue test1", "pr test1"]) expect(titles_for(issue_section.issues)).to eq(["issue no labels"]) expect(titles_for(merged_section.issues)).to eq(["pr no labels"]) end end end end end end