require 'spec_helper' require ::File.expand_path("../../../lib/cornucopia/util/report_builder", File.dirname(__FILE__)) describe Cornucopia::Util::ReportBuilder do let(:current_report) { Cornucopia::Util::ReportBuilder.new_report } let(:custom_report) { Cornucopia::Util::ReportBuilder.new_report("cool_report", "diag_reports") } report_variation_settings = [ { report: :current_report, index_folder: "cornucopia_report", sub_folder: "cornucopia_report" }, { report: :custom_report, index_folder: "diag_reports", sub_folder: "cool_report" } ] # Make sure that all tests start clean and get cleaned up afterwards... around(:each) do |example| expect(File.directory?(Rails.root.join("cornucopia_report/"))).to be_falsey expect(File.directory?(Rails.root.join("diag_reports/"))).to be_falsey begin example.run ensure if (Cornucopia::Util::ReportBuilder.class_variable_get("@@current_report")) Cornucopia::Util::ReportBuilder.current_report.close end FileUtils.rm_rf Rails.root.join("cornucopia_report/") FileUtils.rm_rf Rails.root.join("diag_reports/") end end describe "#on_close" do around(:each) do |example| num_close_calls = Cornucopia::Util::ReportBuilder.class_variable_get("@@on_close_blocks").length example.run while num_close_calls != Cornucopia::Util::ReportBuilder.class_variable_get("@@on_close_blocks").length Cornucopia::Util::ReportBuilder.class_variable_get("@@on_close_blocks").pop end end it "calls each on_close block" do report_results = [] Cornucopia::Util::ReportBuilder.on_close do report_results << 1 end Cornucopia::Util::ReportBuilder.on_close do report_results << 2 end Cornucopia::Util::ReportBuilder.on_close do report_results << 3 end Cornucopia::Util::ReportBuilder.current_report.close expect(report_results).to be == [1, 2, 3] expect(Cornucopia::Util::ReportBuilder.class_variable_get("@@current_report")).not_to be end it "calls each on_close block even if an exception is thrown" do report_results = [] Cornucopia::Util::ReportBuilder.on_close do report_results << 1 raise "1" end Cornucopia::Util::ReportBuilder.on_close do report_results << 2 raise "2" end Cornucopia::Util::ReportBuilder.on_close do report_results << 3 raise "3" end expect do Cornucopia::Util::ReportBuilder.current_report.close end.to raise_exception expect(report_results).to be == [1, 2, 3] expect(Cornucopia::Util::ReportBuilder.class_variable_get("@@current_report")).not_to be end end describe "#escape_string" do it "makes a string html_safe" do expect(Cornucopia::Util::ReportBuilder.escape_string("test_value")).to be_html_safe end it "escapes html characters" do expect(Cornucopia::Util::ReportBuilder.escape_string("")).to be == "<test_value>" end end describe "#format_code_refs" do it "does not alter a string without refs" do sample_string = "This is a sample string /fred/george.html:45" expect(Cornucopia::Util::ReportBuilder.format_code_refs(sample_string)).to be == sample_string end it "ensures that the string is html_safe" do sample_string = "This is a sample string /fred/george.html:45" expect(Cornucopia::Util::ReportBuilder.format_code_refs(sample_string)).to be_html_safe end end describe "#root_folder" do it "returns the rails root if it is available" do expect(Cornucopia::Util::ReportBuilder.root_folder).to be == Rails.root end it "returns the pwd if Rails is not available" do expect(Object).to receive(:const_defined?).with("Rails").and_return false expect(Cornucopia::Util::ReportBuilder.root_folder).to be == FileUtils.pwd end end describe "#pretty_array" do let(:array_values) { [ "Turner & Hooch", "Barney Rubble", "Harvey" ] } it "ignores a non-array value" do expect(Cornucopia::Util::ReportBuilder.pretty_array("a string")).to be == "a string" end it "calls #pretty_format for a non-array value" do expect(Cornucopia::Util::ReportBuilder).to receive(:pretty_format).once.and_call_original expect(Cornucopia::Util::ReportBuilder.pretty_array("a string")).to be_html_safe end it "calls #pretty_format for each element in the array" do expect(Cornucopia::Util::ReportBuilder).to receive(:pretty_format).exactly(3).and_call_original formatted_code = Cornucopia::Util::ReportBuilder.pretty_array(array_values) expect(formatted_code).to be_html_safe expect(formatted_code).to be == "Turner &amp; Hooch\nBarney Rubble\nHarvey" end it "calls #pretty_format on a sub-array after it is converted to a string" do expect(Cornucopia::Util::ReportBuilder).to receive(:pretty_format).exactly(4).and_call_original array_values << [1, 2, 3] formatted_code = Cornucopia::Util::ReportBuilder.pretty_array(array_values) expect(formatted_code).to be_html_safe expect(formatted_code).to be == "Turner &amp; Hooch\nBarney Rubble\nHarvey\n[1, 2, 3]" end end describe "#pretty_object" do around(:each) do |example| orig_timeout = Cornucopia::Util::Configuration.print_timeout_min begin Cornucopia::Util::Configuration.print_timeout_min = 2 example.run ensure Cornucopia::Util::Configuration.print_timeout_min = orig_timeout end end it "returns a string as-is" do test_object = "a string" expect(test_object).not_to receive(:pretty_inspect) expect(test_object).not_to receive(:to_s) expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) Cornucopia::Util::ReportBuilder.pretty_object(test_object) end it "calls pretty_inspect on most objects" do test_object = { a: "b" } expect(test_object).to receive(:pretty_inspect).and_call_original expect(test_object).not_to receive(:to_s) expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) Cornucopia::Util::ReportBuilder.pretty_object(test_object) end it "times out after a long time" do test_object = { a: "b" } expect(test_object).to receive(:pretty_inspect) { sleep 60 } expect(test_object).to receive(:to_s).and_call_original expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) expect(Cornucopia::Util::ReportBuilder.pretty_object(test_object)).to be == "{:a=>\"b\"}" end it "times out after a long time with t_s too" do test_object = { a: "b" } expect(test_object).to receive(:pretty_inspect) { sleep 60 } expect(test_object).to receive(:to_s) { sleep 60 } expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) expect(Cornucopia::Util::ReportBuilder.pretty_object(test_object)).to be == "Timed out rendering" end it "calls to_s after an exception is raised" do test_object = { a: "b" } expect(test_object).to receive(:pretty_inspect) { raise Exception.new("This is an error") } expect(test_object).to receive(:to_s).and_call_original expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) expect(Cornucopia::Util::ReportBuilder.pretty_object(test_object)).to be == "{:a=>\"b\"}" end it "times out after an exception is raised" do test_object = { a: "b" } expect(test_object).to receive(:pretty_inspect) { raise Exception.new("This is an error") } expect(test_object).to receive(:to_s) { sleep 60 } expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) expect(Cornucopia::Util::ReportBuilder.pretty_object(test_object)).to be == "Timed out rendering" end it "returns an array by formatting it" do test_object = [:a, "b"] expect(test_object).not_to receive(:pretty_inspect) expect(test_object).not_to receive(:to_s) expect(Cornucopia::Util::ReportBuilder).to receive(:pretty_array).and_call_original Cornucopia::Util::ReportBuilder.pretty_object(test_object) end it "returns an object that cannot be inspected as a string" do test_object = { a: "b" } expect(test_object).to receive(:respond_to?).and_return false expect(test_object).not_to receive(:pretty_inspect) expect(test_object).to receive(:to_s).and_call_original expect(Cornucopia::Util::ReportBuilder).not_to receive(:pretty_array) Cornucopia::Util::ReportBuilder.pretty_object(test_object) end end it "should create a new report" do orig_report = Cornucopia::Util::ReportBuilder.current_report report = Cornucopia::Util::ReportBuilder.new_report expect(report).to_not be == orig_report alt_report = Cornucopia::Util::ReportBuilder.current_report expect(report).to be == alt_report end it "should create a new report if the current report doesn't match" do orig_report = Cornucopia::Util::ReportBuilder.current_report report = Cornucopia::Util::ReportBuilder.current_report("cool_report", "diag_reports") expect(report).to_not be == orig_report alt_report = Cornucopia::Util::ReportBuilder.current_report("cool_report", "diag_reports") expect(report).to be == alt_report alt_report = Cornucopia::Util::ReportBuilder.current_report("cool_report") expect(report).to be == alt_report alt_report = Cornucopia::Util::ReportBuilder.current_report expect(report).to be == alt_report end describe "#folder_name_to_section_name" do it "returns a special value for cornucopia_report" do expect(Cornucopia::Util::ReportBuilder.folder_name_to_section_name("cornucopia_report")). to be == "Feature Tests" end it "returns a special value for diagnostics_rspec_report" do expect(Cornucopia::Util::ReportBuilder.folder_name_to_section_name("diagnostics_rspec_report")). to be == "RSPEC Tests" end it "returns the passed in value if nothing else" do value = Faker::Lorem.word expect(Cornucopia::Util::ReportBuilder.folder_name_to_section_name("#{value}")).to be == value end it "returns the basename of the passed in value" do value = Faker::Lorem.word expect(Cornucopia::Util::ReportBuilder.folder_name_to_section_name("#{Faker::Lorem.word}/#{value}")). to be == value end end describe "#build_index_section_item" do it "creates a list item with an anchor" do result_string = Cornucopia::Util::ReportBuilder.build_index_section_item("harold/fred/george.html") expect(result_string).to match /href=\"harold\/fred\/george.html\"/ expect(result_string).to match /\>harold\/fred\/ expect(result_string).to match /\<\/li\>/ end end describe "#build_index_section" do it "creates a list item with an anchor" do a_title = Faker::Lorem.sentence strings = Faker::Lorem.sentences(5) strings.map! { |string| string.gsub(" ", "/") } result_string = Cornucopia::Util::ReportBuilder.build_index_section(a_title, strings) expect(result_string).to match /#{a_title}/ strings.each do |a_string| expect(result_string).to match /href=\"#{a_string}\"/ expect(result_string).to match /\>#{File.dirname(a_string)}\/ expect(result_string).to match /\<\/ul\>/ end end describe "#page_dump" do it "outputs a text area with the page html_encoded" do source_html = "\n\nThis is some & awesome text\n" page_html = Cornucopia::Util::ReportBuilder.page_dump(source_html) source_html = "".html_safe + source_html expect(page_html).to match /\>#{source_html}\..\/coverage\Feature Tests\RSPEC Tests\#{group_name}\#{group_name}\#{folder_name}\<\/a\>/i) end groups.each do |group_name, group_indexes| group_indexes.each do |index_value| expect(index_value).to be expect(index_value).to be >= 0 end groups.each do |other_group_name, other_group_indexes| if (other_group_name != group_name) expect((group_indexes.min < other_group_indexes.min && group_indexes.max < other_group_indexes.min) || (group_indexes.min > other_group_indexes.max && group_indexes.max > other_group_indexes.max)). to be_truthy end end end empty_folder_names.each do |file_name| expect(post_file).not_to match /#{file_name}\/other.html/i end file_names.each do |file_name| expect(post_file).not_to match /\/#{file_name}/i end end end describe "#initialize_report_files" do it "should create the report folder" do current_report = send(report_settings[:report]) FileUtils.mkdir_p current_report.index_folder_name current_report.rebuild_index_page post_file = File.read(File.join(current_report.index_folder_name, "report_contents.html")) expect(post_file).not_to match /\>#{report_settings[:sub_folder]}\#{report_settings[:sub_folder]}\#{section_name}\\n".length..-1]).to be == "\<\/div\>\n" end end describe "#within_table" do it "should output the table within a section" do current_report = send(report_settings[:report]) section_name = "".html_safe + Faker::Lorem.sentence table_label = "".html_safe + Faker::Lorem.sentence table_data = "".html_safe + Faker::Lorem.paragraphs.join("\n") current_report.within_section(section_name) do |report_object| report_object.within_table do |report_table| report_table.write_stats(table_label, table_data) end end post_data = File.read(current_report.report_contents_page_name) expect(post_data[-1 * "\<\/div\>\n".length..-1]).to be == "\<\/div\>\n" expect(post_data).to match /\>\n#{table_label}\n\#{table_data}\\n".length..-1]).to be == "\<\/div\>\n" expect(post_data).to match /\>\n#{table_label}\n\#{table_data}\\nstat\n\\nstat\n\\n\nThis is some & awesome text\n" FileUtils.mkdir_p report_folder Cornucopia::Util::FileAsset.asset("cornucopia.css").add_file(File.join(report_folder, "page_dump.html")) expect(File.exists?(File.join(report_folder, "page_dump.html"))).to be_truthy expect(File.exists?(File.join(report_folder, "page_dump_1.html"))).to be_falsey page_link = current_report.page_frame(source_html) expect(File.exists?(File.join(report_folder, "page_dump.html"))).to be_truthy expect(File.exists?(File.join(report_folder, "page_dump_1.html"))).to be_truthy expect(page_link).to be_html_safe expect(page_link).to match /\