slather 2.4.6 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +5 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +49 -0
- data/README.md +35 -1
- data/lib/slather.rb +1 -0
- data/lib/slather/command/coverage_command.rb +6 -0
- data/lib/slather/coverage_file.rb +14 -9
- data/lib/slather/coverage_service/coveralls.rb +57 -0
- data/lib/slather/coverage_service/sonarqube_xml_output.rb +61 -0
- data/lib/slather/profdata_coverage_file.rb +24 -10
- data/lib/slather/project.rb +78 -40
- data/lib/slather/version.rb +1 -1
- data/slather.gemspec +14 -14
- data/spec/fixtures/sonarqube-generic-coverage.xml +93 -0
- data/spec/slather/cocoapods_plugin_spec.rb +1 -1
- data/spec/slather/coverage_service/coveralls_spec.rb +20 -0
- data/spec/slather/coverage_service/sonarqube_xml_spec.rb +46 -0
- data/spec/slather/profdata_coverage_spec.rb +21 -0
- data/spec/slather/project_spec.rb +78 -8
- data/spec/spec_helper.rb +1 -0
- metadata +48 -38
    
        data/lib/slather/project.rb
    CHANGED
    
    | @@ -118,32 +118,66 @@ module Slather | |
| 118 118 |  | 
| 119 119 | 
             
                def profdata_coverage_files
         | 
| 120 120 | 
             
                  coverage_files = []
         | 
| 121 | 
            -
                  line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
         | 
| 122 121 |  | 
| 123 122 | 
             
                  if self.binary_file
         | 
| 124 123 | 
             
                    self.binary_file.each do |binary_path|
         | 
| 125 | 
            -
                       | 
| 126 | 
            -
                       | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
                          Pathname(file["filename"]).realpath
         | 
| 130 | 
            -
                        end)
         | 
| 131 | 
            -
                      end
         | 
| 124 | 
            +
                      pathnames_per_binary = pathnames_per_binary(binary_path)
         | 
| 125 | 
            +
                      coverage_files.concat(create_coverage_files_for_binary(binary_path, pathnames_per_binary))
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
                  end
         | 
| 132 128 |  | 
| 133 | 
            -
             | 
| 129 | 
            +
                  coverage_files
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
                private :profdata_coverage_files
         | 
| 134 132 |  | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
                       | 
| 133 | 
            +
                def pathnames_per_binary(binary_path)
         | 
| 134 | 
            +
                  coverage_json_string = llvm_cov_export_output(binary_path)
         | 
| 135 | 
            +
                  coverage_json = JSON.parse(coverage_json_string)
         | 
| 136 | 
            +
                  coverage_json["data"].reduce([]) do |result, chunk|
         | 
| 137 | 
            +
                    result.concat(chunk["files"].map do |file|
         | 
| 138 | 
            +
                      Pathname(file["filename"]).realpath
         | 
| 139 | 
            +
                    end)
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
                private :pathnames_per_binary
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                def create_coverage_files_for_binary(binary_path, pathnames_per_binary)
         | 
| 145 | 
            +
                  coverage_files = []
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                  begin
         | 
| 148 | 
            +
                    coverage_files.concat(create_coverage_files(binary_path, pathnames_per_binary))
         | 
| 149 | 
            +
                  rescue Errno::E2BIG => e
         | 
| 150 | 
            +
                    # pathnames_per_binary is too big for the OS to handle so it's split in two halfs which are processed independently
         | 
| 151 | 
            +
                    if pathnames_per_binary.count > 1
         | 
| 152 | 
            +
                      left, right = pathnames_per_binary.each_slice( (pathnames_per_binary.size/2.0).round ).to_a
         | 
| 153 | 
            +
                      coverage_files.concat(create_coverage_files_for_binary(binary_path, left))
         | 
| 154 | 
            +
                      coverage_files.concat(create_coverage_files_for_binary(binary_path, right))
         | 
| 155 | 
            +
                    else
         | 
| 156 | 
            +
                      # pathnames_per_binary contains one element which is too big for the OS to handle. 
         | 
| 157 | 
            +
                      raise e, "#{e}. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414", e.backtrace
         | 
| 141 158 | 
             
                    end
         | 
| 142 159 | 
             
                  end
         | 
| 143 160 |  | 
| 144 161 | 
             
                  coverage_files
         | 
| 145 162 | 
             
                end
         | 
| 146 | 
            -
                private : | 
| 163 | 
            +
                private :create_coverage_files_for_binary
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                def create_coverage_files(binary_path, pathnames)
         | 
| 166 | 
            +
                  line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
         | 
| 167 | 
            +
                  files = create_profdata(binary_path, pathnames)
         | 
| 168 | 
            +
                  files.map do |source|
         | 
| 169 | 
            +
                    coverage_file = coverage_file_class.new(self, source, line_numbers_first)
         | 
| 170 | 
            +
                    # If a single source file is used, the resulting output does not contain the file name.
         | 
| 171 | 
            +
                    coverage_file.source_file_pathname = pathnames.first if pathnames.count == 1
         | 
| 172 | 
            +
                    !coverage_file.ignored? ? coverage_file : nil
         | 
| 173 | 
            +
                  end.compact
         | 
| 174 | 
            +
                end
         | 
| 175 | 
            +
                private :create_coverage_files
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                def create_profdata(binary_path, pathnames)
         | 
| 178 | 
            +
                  profdata_llvm_cov_output(binary_path, pathnames).split("\n\n")
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
                private :create_profdata
         | 
| 147 181 |  | 
| 148 182 | 
             
                def remove_extension(path)
         | 
| 149 183 | 
             
                  path.split(".")[0..-2].join(".")
         | 
| @@ -157,36 +191,38 @@ module Slather | |
| 157 191 | 
             
                end
         | 
| 158 192 |  | 
| 159 193 | 
             
                def profdata_coverage_dir
         | 
| 160 | 
            -
                   | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
                     | 
| 164 | 
            -
             | 
| 165 | 
            -
                     | 
| 166 | 
            -
             | 
| 194 | 
            +
                  @profdata_coverage_dir ||= begin
         | 
| 195 | 
            +
                    raise StandardError, "The specified build directory (#{self.build_directory}) does not exist" unless File.exists?(self.build_directory)
         | 
| 196 | 
            +
                    dir = nil
         | 
| 197 | 
            +
                    if self.scheme
         | 
| 198 | 
            +
                      dir = Dir[File.join(build_directory,"/**/CodeCoverage/#{self.scheme}")].first
         | 
| 199 | 
            +
                    else
         | 
| 200 | 
            +
                      dir = Dir[File.join(build_directory,"/**/#{first_product_name}")].first
         | 
| 201 | 
            +
                    end
         | 
| 167 202 |  | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 203 | 
            +
                    if dir == nil
         | 
| 204 | 
            +
                      # Xcode 7.3 moved the location of Coverage.profdata
         | 
| 205 | 
            +
                      dir = Dir[File.join(build_directory,"/**/CodeCoverage")].first
         | 
| 206 | 
            +
                    end
         | 
| 172 207 |  | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 208 | 
            +
                    if dir == nil && Slather.xcode_version[0] >= 9
         | 
| 209 | 
            +
                      # Xcode 9 moved the location of Coverage.profdata
         | 
| 210 | 
            +
                      coverage_files = Dir[File.join(build_directory, "/**/ProfileData/*/Coverage.profdata")]
         | 
| 176 211 |  | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 212 | 
            +
                      if coverage_files.count == 0
         | 
| 213 | 
            +
                        # Look up one directory
         | 
| 214 | 
            +
                        # The ProfileData directory is next to Intermediates.noindex (in previous versions of Xcode the coverage was inside Intermediates)
         | 
| 215 | 
            +
                        coverage_files = Dir[File.join(build_directory, "../**/ProfileData/*/Coverage.profdata")]
         | 
| 216 | 
            +
                      end
         | 
| 182 217 |  | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 218 | 
            +
                      if coverage_files != nil && coverage_files.count != 0
         | 
| 219 | 
            +
                        dir = Pathname.new(coverage_files.first).parent()
         | 
| 220 | 
            +
                      end
         | 
| 185 221 | 
             
                    end
         | 
| 186 | 
            -
                  end
         | 
| 187 222 |  | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 223 | 
            +
                    raise StandardError, "No coverage directory found." unless dir != nil
         | 
| 224 | 
            +
                    dir
         | 
| 225 | 
            +
                  end
         | 
| 190 226 | 
             
                end
         | 
| 191 227 |  | 
| 192 228 | 
             
                def profdata_file
         | 
| @@ -388,6 +424,8 @@ module Slather | |
| 388 424 | 
             
                    extend(Slather::CoverageService::HtmlOutput)
         | 
| 389 425 | 
             
                  when :json
         | 
| 390 426 | 
             
                    extend(Slather::CoverageService::JsonOutput)
         | 
| 427 | 
            +
                  when :sonarqube_xml
         | 
| 428 | 
            +
                    extend(Slather::CoverageService::SonarqubeXmlOutput)
         | 
| 391 429 | 
             
                  else
         | 
| 392 430 | 
             
                    raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal`, `coveralls`, `gutter_json`, `cobertura_xml` or `html`"
         | 
| 393 431 | 
             
                  end
         | 
    
        data/lib/slather/version.rb
    CHANGED
    
    
    
        data/slather.gemspec
    CHANGED
    
    | @@ -17,20 +17,20 @@ Gem::Specification.new do |spec| | |
| 17 17 | 
             
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 18 18 | 
             
              spec.require_paths = ['lib']
         | 
| 19 19 |  | 
| 20 | 
            -
              spec.add_development_dependency 'bundler', '~>  | 
| 21 | 
            -
              spec.add_development_dependency 'coveralls'
         | 
| 22 | 
            -
              spec.add_development_dependency 'simplecov'
         | 
| 23 | 
            -
              spec.add_development_dependency 'rake', '~>  | 
| 24 | 
            -
              spec.add_development_dependency 'rspec', '~> 3. | 
| 25 | 
            -
              spec.add_development_dependency 'pry', '~> 0. | 
| 26 | 
            -
              spec.add_development_dependency 'cocoapods', '~> 1. | 
| 27 | 
            -
              spec.add_development_dependency 'json_spec', '~> 1.1 | 
| 28 | 
            -
              spec.add_development_dependency 'equivalent-xml', '~> 0. | 
| 20 | 
            +
              spec.add_development_dependency 'bundler', '~> 2.0'
         | 
| 21 | 
            +
              spec.add_development_dependency 'coveralls', '~> 0.8'
         | 
| 22 | 
            +
              spec.add_development_dependency 'simplecov', '~> 0'
         | 
| 23 | 
            +
              spec.add_development_dependency 'rake', '~> 12.3'
         | 
| 24 | 
            +
              spec.add_development_dependency 'rspec', '~> 3.8'
         | 
| 25 | 
            +
              spec.add_development_dependency 'pry', '~> 0.12'
         | 
| 26 | 
            +
              spec.add_development_dependency 'cocoapods', '~> 1.10.beta.1'
         | 
| 27 | 
            +
              spec.add_development_dependency 'json_spec', '~> 1.1'
         | 
| 28 | 
            +
              spec.add_development_dependency 'equivalent-xml', '~> 0.6'
         | 
| 29 29 |  | 
| 30 | 
            -
              spec.add_dependency 'clamp', '~>  | 
| 31 | 
            -
              spec.add_dependency 'xcodeproj', '~> 1. | 
| 32 | 
            -
              spec.add_dependency 'nokogiri', '~> 1.8 | 
| 33 | 
            -
              spec.add_dependency 'CFPropertyList', ' | 
| 30 | 
            +
              spec.add_dependency 'clamp', '~> 1.3'
         | 
| 31 | 
            +
              spec.add_dependency 'xcodeproj', '~> 1.7'
         | 
| 32 | 
            +
              spec.add_dependency 'nokogiri', '~> 1.8'
         | 
| 33 | 
            +
              spec.add_dependency 'CFPropertyList', '>= 2.2', '< 4'
         | 
| 34 34 |  | 
| 35 | 
            -
              spec.add_runtime_dependency 'activesupport' | 
| 35 | 
            +
              spec.add_runtime_dependency 'activesupport'
         | 
| 36 36 | 
             
            end
         | 
| @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            <?xml version="1.0"?>
         | 
| 2 | 
            +
            <coverage version="1">
         | 
| 3 | 
            +
              <file path="spec/fixtures/fixtures/fixtures.m">
         | 
| 4 | 
            +
                <lineToCover lineNumber="14" covered="true"/>
         | 
| 5 | 
            +
                <lineToCover lineNumber="15" covered="true"/>
         | 
| 6 | 
            +
                <lineToCover lineNumber="16" covered="true"/>
         | 
| 7 | 
            +
                <lineToCover lineNumber="19" covered="false"/>
         | 
| 8 | 
            +
                <lineToCover lineNumber="20" covered="false"/>
         | 
| 9 | 
            +
                <lineToCover lineNumber="21" covered="false"/>
         | 
| 10 | 
            +
              </file>
         | 
| 11 | 
            +
              <file path="spec/fixtures/fixtures/more_files/Branches.m">
         | 
| 12 | 
            +
                <lineToCover lineNumber="14" covered="true"/>
         | 
| 13 | 
            +
                <lineToCover lineNumber="15" covered="true"/>
         | 
| 14 | 
            +
                <lineToCover lineNumber="16" covered="true"/>
         | 
| 15 | 
            +
                <lineToCover lineNumber="17" covered="true"/>
         | 
| 16 | 
            +
                <lineToCover lineNumber="18" covered="true"/>
         | 
| 17 | 
            +
                <lineToCover lineNumber="19" covered="false"/>
         | 
| 18 | 
            +
                <lineToCover lineNumber="20" covered="false"/>
         | 
| 19 | 
            +
                <lineToCover lineNumber="21" covered="true"/>
         | 
| 20 | 
            +
                <lineToCover lineNumber="22" covered="true"/>
         | 
| 21 | 
            +
                <lineToCover lineNumber="23" covered="true"/>
         | 
| 22 | 
            +
                <lineToCover lineNumber="24" covered="true"/>
         | 
| 23 | 
            +
                <lineToCover lineNumber="25" covered="true"/>
         | 
| 24 | 
            +
                <lineToCover lineNumber="26" covered="true"/>
         | 
| 25 | 
            +
                <lineToCover lineNumber="27" covered="true"/>
         | 
| 26 | 
            +
                <lineToCover lineNumber="28" covered="true"/>
         | 
| 27 | 
            +
                <lineToCover lineNumber="29" covered="false"/>
         | 
| 28 | 
            +
                <lineToCover lineNumber="30" covered="false"/>
         | 
| 29 | 
            +
                <lineToCover lineNumber="31" covered="false"/>
         | 
| 30 | 
            +
                <lineToCover lineNumber="32" covered="false"/>
         | 
| 31 | 
            +
                <lineToCover lineNumber="33" covered="false"/>
         | 
| 32 | 
            +
                <lineToCover lineNumber="34" covered="false"/>
         | 
| 33 | 
            +
                <lineToCover lineNumber="35" covered="false"/>
         | 
| 34 | 
            +
                <lineToCover lineNumber="36" covered="false"/>
         | 
| 35 | 
            +
                <lineToCover lineNumber="37" covered="false"/>
         | 
| 36 | 
            +
                <lineToCover lineNumber="38" covered="false"/>
         | 
| 37 | 
            +
                <lineToCover lineNumber="39" covered="false"/>
         | 
| 38 | 
            +
                <lineToCover lineNumber="40" covered="false"/>
         | 
| 39 | 
            +
                <lineToCover lineNumber="41" covered="false"/>
         | 
| 40 | 
            +
                <lineToCover lineNumber="42" covered="false"/>
         | 
| 41 | 
            +
                <lineToCover lineNumber="43" covered="false"/>
         | 
| 42 | 
            +
              </file>
         | 
| 43 | 
            +
              <file path="spec/fixtures/fixturesTests/BranchesTests.m">
         | 
| 44 | 
            +
                <lineToCover lineNumber="18" covered="true"/>
         | 
| 45 | 
            +
                <lineToCover lineNumber="19" covered="true"/>
         | 
| 46 | 
            +
                <lineToCover lineNumber="20" covered="true"/>
         | 
| 47 | 
            +
                <lineToCover lineNumber="21" covered="true"/>
         | 
| 48 | 
            +
                <lineToCover lineNumber="23" covered="true"/>
         | 
| 49 | 
            +
                <lineToCover lineNumber="24" covered="true"/>
         | 
| 50 | 
            +
                <lineToCover lineNumber="25" covered="true"/>
         | 
| 51 | 
            +
                <lineToCover lineNumber="26" covered="true"/>
         | 
| 52 | 
            +
                <lineToCover lineNumber="28" covered="true"/>
         | 
| 53 | 
            +
                <lineToCover lineNumber="29" covered="true"/>
         | 
| 54 | 
            +
                <lineToCover lineNumber="30" covered="true"/>
         | 
| 55 | 
            +
                <lineToCover lineNumber="31" covered="true"/>
         | 
| 56 | 
            +
                <lineToCover lineNumber="33" covered="true"/>
         | 
| 57 | 
            +
                <lineToCover lineNumber="34" covered="true"/>
         | 
| 58 | 
            +
                <lineToCover lineNumber="35" covered="true"/>
         | 
| 59 | 
            +
                <lineToCover lineNumber="36" covered="true"/>
         | 
| 60 | 
            +
              </file>
         | 
| 61 | 
            +
              <file path="spec/fixtures/fixturesTests/fixturesTests.m">
         | 
| 62 | 
            +
                <lineToCover lineNumber="20" covered="true"/>
         | 
| 63 | 
            +
                <lineToCover lineNumber="21" covered="true"/>
         | 
| 64 | 
            +
                <lineToCover lineNumber="22" covered="true"/>
         | 
| 65 | 
            +
                <lineToCover lineNumber="23" covered="true"/>
         | 
| 66 | 
            +
                <lineToCover lineNumber="26" covered="true"/>
         | 
| 67 | 
            +
                <lineToCover lineNumber="27" covered="true"/>
         | 
| 68 | 
            +
                <lineToCover lineNumber="28" covered="true"/>
         | 
| 69 | 
            +
                <lineToCover lineNumber="29" covered="true"/>
         | 
| 70 | 
            +
                <lineToCover lineNumber="32" covered="true"/>
         | 
| 71 | 
            +
                <lineToCover lineNumber="33" covered="true"/>
         | 
| 72 | 
            +
                <lineToCover lineNumber="34" covered="true"/>
         | 
| 73 | 
            +
                <lineToCover lineNumber="35" covered="true"/>
         | 
| 74 | 
            +
                <lineToCover lineNumber="38" covered="true"/>
         | 
| 75 | 
            +
                <lineToCover lineNumber="39" covered="true"/>
         | 
| 76 | 
            +
                <lineToCover lineNumber="40" covered="true"/>
         | 
| 77 | 
            +
                <lineToCover lineNumber="41" covered="true"/>
         | 
| 78 | 
            +
                <lineToCover lineNumber="42" covered="true"/>
         | 
| 79 | 
            +
              </file>
         | 
| 80 | 
            +
              <file path="spec/fixtures/fixturesTests/peekaviewTests💣.m">
         | 
| 81 | 
            +
                <lineToCover lineNumber="18" covered="true"/>
         | 
| 82 | 
            +
                <lineToCover lineNumber="19" covered="true"/>
         | 
| 83 | 
            +
                <lineToCover lineNumber="20" covered="true"/>
         | 
| 84 | 
            +
                <lineToCover lineNumber="21" covered="true"/>
         | 
| 85 | 
            +
                <lineToCover lineNumber="24" covered="true"/>
         | 
| 86 | 
            +
                <lineToCover lineNumber="25" covered="true"/>
         | 
| 87 | 
            +
                <lineToCover lineNumber="26" covered="true"/>
         | 
| 88 | 
            +
                <lineToCover lineNumber="27" covered="true"/>
         | 
| 89 | 
            +
                <lineToCover lineNumber="30" covered="true"/>
         | 
| 90 | 
            +
                <lineToCover lineNumber="31" covered="true"/>
         | 
| 91 | 
            +
                <lineToCover lineNumber="32" covered="true"/>
         | 
| 92 | 
            +
              </file>
         | 
| 93 | 
            +
            </coverage>
         | 
| @@ -13,7 +13,7 @@ describe Slather do | |
| 13 13 | 
             
                  # Execute the post_install hook via CocoaPods
         | 
| 14 14 | 
             
                  sandbox_root = 'Pods'
         | 
| 15 15 | 
             
                  sandbox = Pod::Sandbox.new(sandbox_root)
         | 
| 16 | 
            -
                  context = Pod::Installer::PostInstallHooksContext.generate(sandbox, [])
         | 
| 16 | 
            +
                  context = Pod::Installer::PostInstallHooksContext.generate(sandbox, mock_project, [])
         | 
| 17 17 | 
             
                  Pod::HooksManager.run(:post_install, context, {'slather' => nil})
         | 
| 18 18 | 
             
                end
         | 
| 19 19 | 
             
              end
         | 
| @@ -151,6 +151,26 @@ describe Slather::CoverageService::Coveralls do | |
| 151 151 | 
             
                    ENV['GIT_BRANCH'] = git_branch
         | 
| 152 152 | 
             
                  end
         | 
| 153 153 | 
             
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                context "coverage_service is :github" do
         | 
| 156 | 
            +
                  before(:each) { fixtures_project.ci_service = :github }
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                  it "should return valid json for coveralls coverage data" do
         | 
| 159 | 
            +
                    allow(fixtures_project).to receive(:github_job_id).and_return("9182")
         | 
| 160 | 
            +
                    allow(fixtures_project).to receive(:coverage_access_token).and_return("abc123")
         | 
| 161 | 
            +
                    allow(fixtures_project).to receive(:github_pull_request).and_return("1")
         | 
| 162 | 
            +
                    allow(fixtures_project).to receive(:github_build_url).and_return("https://github.com/Bruce/Wayne/actions/runs/1")
         | 
| 163 | 
            +
                    allow(fixtures_project).to receive(:github_git_info).and_return({ :head => { :id => "ababa123", :author_name => "bwayne", :message => "hello" }, :branch => "master" })
         | 
| 164 | 
            +
                    expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"github\",\"repo_name\":\"\",\"repo_token\":\"abc123\",\"service_pull_request\":\"1\",\"service_build_url\":\"https://github.com/Bruce/Wayne/actions/runs/1\",\"git\":{\"head\":{\"id\":\"ababa123\",\"author_name\":\"bwayne\",\"message\":\"hello\"},\"branch\":\"master\"}}").excluding("source_files")
         | 
| 165 | 
            +
                    expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.coverage_files.map(&:as_json).to_json).at_path("source_files")
         | 
| 166 | 
            +
                  end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                  it "should raise an error if there is no GITHUB_RUN_ID" do
         | 
| 169 | 
            +
                    allow(fixtures_project).to receive(:github_job_id).and_return(nil)
         | 
| 170 | 
            +
                    expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
         | 
| 171 | 
            +
                  end
         | 
| 172 | 
            +
                end
         | 
| 173 | 
            +
             | 
| 154 174 | 
             
              end
         | 
| 155 175 |  | 
| 156 176 | 
             
              describe '#coveralls_coverage_data' do
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
         | 
| 2 | 
            +
            require 'json'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Slather::CoverageService::SonarqubeXmlOutput do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:fixtures_project) do
         | 
| 7 | 
            +
                proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
         | 
| 8 | 
            +
                proj.build_directory = TEMP_DERIVED_DATA_PATH
         | 
| 9 | 
            +
                proj.input_format = "profdata"
         | 
| 10 | 
            +
                proj.coverage_service = "sonarqube_xml"
         | 
| 11 | 
            +
                proj.configure
         | 
| 12 | 
            +
                proj
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              describe '#coverage_file_class' do
         | 
| 16 | 
            +
                it "should return CoverageFile" do
         | 
| 17 | 
            +
                  expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::ProfdataCoverageFile)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              describe '#post' do
         | 
| 22 | 
            +
                it "should create an XML report spanning all coverage files" do
         | 
| 23 | 
            +
                  fixtures_project.post
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  file = File.open(FIXTURES_SONARQUBE_XML_PATH)
         | 
| 26 | 
            +
                  fixture_xml_doc = Nokogiri::XML(file)
         | 
| 27 | 
            +
                  file.close
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  file = File.open('sonarqube-generic-coverage.xml')
         | 
| 30 | 
            +
                  current_xml_doc = Nokogiri::XML(file)
         | 
| 31 | 
            +
                  file.close
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  expect(EquivalentXml.equivalent?(current_xml_doc, fixture_xml_doc)).to be_truthy
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                it "should create an XML report in the given output directory" do
         | 
| 37 | 
            +
                  fixtures_project.output_directory = "./output"
         | 
| 38 | 
            +
                  fixtures_project.post
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  filepath = "#{fixtures_project.output_directory}/sonarqube-generic-coverage.xml"
         | 
| 41 | 
            +
                  expect(File.exists?(filepath)).to be_truthy
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  FileUtils.rm_rf(fixtures_project.output_directory)
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -90,6 +90,23 @@ describe Slather::ProfdataCoverageFile do | |
| 90 90 | 
             
                end
         | 
| 91 91 | 
             
              end
         | 
| 92 92 |  | 
| 93 | 
            +
              describe '#ignore_error_lines' do
         | 
| 94 | 
            +
                it 'should ignore lines starting with - when line_numbers_first is true' do
         | 
| 95 | 
            +
                  expect(profdata_coverage_file.ignore_error_lines(['--------'], true)).to eq([])
         | 
| 96 | 
            +
                  expect(profdata_coverage_file.ignore_error_lines(['--------', 'not ignored'], true)).to eq(['not ignored'])
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                it 'should ignore lines starting with | when line_numbers_first is true' do
         | 
| 100 | 
            +
                  expect(profdata_coverage_file.ignore_error_lines(['| Unexecuted instantiation'], true)).to eq([])
         | 
| 101 | 
            +
                  expect(profdata_coverage_file.ignore_error_lines(['| Unexecuted instantiation', 'not ignored'], true)).to eq(['not ignored'])
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                it 'should not ignore any lines when line_numbers_first is false' do
         | 
| 105 | 
            +
                  lines = ['| Unexecuted instantiation', '------']
         | 
| 106 | 
            +
                  expect(profdata_coverage_file.ignore_error_lines(lines, false)).to eq(lines)
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 93 110 | 
             
              describe "#coverage_for_line" do
         | 
| 94 111 | 
             
                it "should return the number of hits for the line" do
         | 
| 95 112 | 
             
                  expect(profdata_coverage_file.coverage_for_line("      10|   40|    func applicationWillTerminate(application: UIApplication) {", false)).to eq(10)
         | 
| @@ -116,6 +133,10 @@ describe Slather::ProfdataCoverageFile do | |
| 116 133 | 
             
                  expect(profdata_coverage_file.coverage_for_line("   18|  11.8k|    return a + b;", true)).to eq(11800)
         | 
| 117 134 | 
             
                  expect(profdata_coverage_file.coverage_for_line("   18|  2.58M|    return a + b;", true)).to eq(2580000)
         | 
| 118 135 | 
             
                end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                it 'should ignore errors in profdata' do
         | 
| 138 | 
            +
                  expect(profdata_coverage_file.coverage_for_line('------------------', true)).to eq(nil)
         | 
| 139 | 
            +
                end
         | 
| 119 140 | 
             
              end
         | 
| 120 141 |  | 
| 121 142 | 
             
              describe "#num_lines_tested" do
         | 
| @@ -64,15 +64,78 @@ describe Slather::Project do | |
| 64 64 | 
             
                end
         | 
| 65 65 | 
             
              end
         | 
| 66 66 |  | 
| 67 | 
            -
              describe "#profdata_coverage_files" do
         | 
| 67 | 
            +
              describe "#profdata_coverage_files with large file lists" do
         | 
| 68 68 | 
             
                class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
         | 
| 69 69 | 
             
                end
         | 
| 70 70 |  | 
| 71 | 
            +
                llvm_cov_export_output = %q(
         | 
| 72 | 
            +
                    {
         | 
| 73 | 
            +
                       "data":[
         | 
| 74 | 
            +
                          {
         | 
| 75 | 
            +
                             "files":[
         | 
| 76 | 
            +
                                {
         | 
| 77 | 
            +
                                   "filename":"spec/fixtures/fixtures/Fixtures.swift"
         | 
| 78 | 
            +
                                }
         | 
| 79 | 
            +
                             ]
         | 
| 80 | 
            +
                          },
         | 
| 81 | 
            +
                          {
         | 
| 82 | 
            +
                             "files":[
         | 
| 83 | 
            +
                                {
         | 
| 84 | 
            +
                                   "filename":"spec/fixtures/fixtures/Fixtures.swift"
         | 
| 85 | 
            +
                                }
         | 
| 86 | 
            +
                             ]
         | 
| 87 | 
            +
                          }
         | 
| 88 | 
            +
                       ]
         | 
| 89 | 
            +
                    })
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                profdata_llvm_cov_output = "#{FIXTURES_SWIFT_FILE_PATH}:
         | 
| 92 | 
            +
                   |    0|
         | 
| 93 | 
            +
                   |    1|import UIKit
         | 
| 94 | 
            +
                   |    2|
         | 
| 95 | 
            +
                   |    3|@UIApplicationMain
         | 
| 96 | 
            +
                   |    4|class AppDelegate: UIResponder, UIApplicationDelegate {
         | 
| 97 | 
            +
                   |    5|
         | 
| 98 | 
            +
                   |    6|    var window: UIWindow?
         | 
| 99 | 
            +
                   |    7|
         | 
| 100 | 
            +
                  1|    8|    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
         | 
| 101 | 
            +
                  1|    9|        return true
         | 
| 102 | 
            +
                  1|   10|    }
         | 
| 103 | 
            +
                   |   11|
         | 
| 104 | 
            +
                  0|   12|    func applicationWillResignActive(application: UIApplication) {
         | 
| 105 | 
            +
                  0|   13|    }
         | 
| 106 | 
            +
                  0|   14|}"
         | 
| 107 | 
            +
             | 
| 71 108 | 
             
                before(:each) do
         | 
| 72 109 | 
             
                  allow(Dir).to receive(:[]).and_call_original
         | 
| 73 110 | 
             
                  allow(Dir).to receive(:[]).with("#{fixtures_project.build_directory}/**/Coverage.profdata").and_return(["/some/path/Coverage.profdata"])
         | 
| 74 111 | 
             
                  allow(fixtures_project).to receive(:binary_file).and_return(["Fixtures"])
         | 
| 75 | 
            -
                  allow(fixtures_project).to receive(:llvm_cov_export_output).and_return( | 
| 112 | 
            +
                  allow(fixtures_project).to receive(:llvm_cov_export_output).and_return(llvm_cov_export_output)
         | 
| 113 | 
            +
                  allow(fixtures_project).to receive(:coverage_file_class).and_return(SpecXcode7CoverageFile)
         | 
| 114 | 
            +
                  allow(fixtures_project).to receive(:ignore_list).and_return([])
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                it "Should catch Errno::E2BIG and re-raise if the input is too large to split into multiple chunks" do
         | 
| 118 | 
            +
                  allow(fixtures_project).to receive(:unsafe_profdata_llvm_cov_output).and_raise(Errno::E2BIG)
         | 
| 119 | 
            +
                  expect { fixtures_project.send(:profdata_coverage_files) }.to raise_error(Errno::E2BIG, "Argument list too long. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414")
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                it "Should catch Errno::E2BIG and return Coverage.profdata file objects when the work can be split into two" do
         | 
| 123 | 
            +
                  allow(fixtures_project).to receive(:unsafe_profdata_llvm_cov_output).once { 
         | 
| 124 | 
            +
                    # raise once and then insert the stub
         | 
| 125 | 
            +
                    allow(fixtures_project).to receive(:profdata_llvm_cov_output).and_return(profdata_llvm_cov_output)
         | 
| 126 | 
            +
                    raise Errno::E2BIG 
         | 
| 127 | 
            +
                  }
         | 
| 128 | 
            +
                  profdata_coverage_files = fixtures_project.send(:profdata_coverage_files)
         | 
| 129 | 
            +
                  profdata_coverage_files.each { |cf| expect(cf.kind_of?(SpecXcode7CoverageFile)).to be_truthy }
         | 
| 130 | 
            +
                  expect(profdata_coverage_files.map { |cf| cf.source_file_pathname.basename.to_s }).to eq(["Fixtures.swift", "Fixtures.swift"])
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              describe "#profdata_coverage_files" do
         | 
| 135 | 
            +
                class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                llvm_cov_export_output = %q(
         | 
| 76 139 | 
             
                    {
         | 
| 77 140 | 
             
                       "data":[
         | 
| 78 141 | 
             
                          {
         | 
| @@ -83,9 +146,9 @@ describe Slather::Project do | |
| 83 146 | 
             
                             ]
         | 
| 84 147 | 
             
                          }
         | 
| 85 148 | 
             
                       ]
         | 
| 86 | 
            -
                    }
         | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 149 | 
            +
                    })
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                profdata_llvm_cov_output = "#{FIXTURES_SWIFT_FILE_PATH}:
         | 
| 89 152 | 
             
                   |    0|
         | 
| 90 153 | 
             
                   |    1|import UIKit
         | 
| 91 154 | 
             
                   |    2|
         | 
| @@ -100,7 +163,14 @@ describe Slather::Project do | |
| 100 163 | 
             
                   |   11|
         | 
| 101 164 | 
             
                  0|   12|    func applicationWillResignActive(application: UIApplication) {
         | 
| 102 165 | 
             
                  0|   13|    }
         | 
| 103 | 
            -
                  0|   14|}" | 
| 166 | 
            +
                  0|   14|}"
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                before(:each) do
         | 
| 169 | 
            +
                  allow(Dir).to receive(:[]).and_call_original
         | 
| 170 | 
            +
                  allow(Dir).to receive(:[]).with("#{fixtures_project.build_directory}/**/Coverage.profdata").and_return(["/some/path/Coverage.profdata"])
         | 
| 171 | 
            +
                  allow(fixtures_project).to receive(:binary_file).and_return(["Fixtures"])
         | 
| 172 | 
            +
                  allow(fixtures_project).to receive(:llvm_cov_export_output).and_return(llvm_cov_export_output)
         | 
| 173 | 
            +
                  allow(fixtures_project).to receive(:profdata_llvm_cov_output).and_return(profdata_llvm_cov_output)
         | 
| 104 174 | 
             
                  allow(fixtures_project).to receive(:coverage_file_class).and_return(SpecXcode7CoverageFile)
         | 
| 105 175 | 
             
                  allow(fixtures_project).to receive(:ignore_list).and_return([])
         | 
| 106 176 | 
             
                end
         | 
| @@ -583,8 +653,8 @@ describe Slather::Project do | |
| 583 653 | 
             
                it "should find relevant source files" do
         | 
| 584 654 | 
             
                  source_files = fixtures_project.find_source_files
         | 
| 585 655 | 
             
                  expect(source_files.count).to eq(2)
         | 
| 586 | 
            -
                  expect(source_files.first.to_s).to include(" | 
| 587 | 
            -
                  expect(source_files.last.to_s).to include(" | 
| 656 | 
            +
                  expect(source_files.first.to_s).to include("fixturesTwo.m")
         | 
| 657 | 
            +
                  expect(source_files.last.to_s).to include("fixtures.m")
         | 
| 588 658 | 
             
                end
         | 
| 589 659 |  | 
| 590 660 | 
             
                it "should print out the coverage for each file, and then total coverage" do
         |