danger-jacoco-instacart 0.1.15 → 0.1.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0dd4a48316de722878c9a9a93259094c27b8ac841391399eb11bfec956379fee
4
- data.tar.gz: 8d0f4f5cdaa727efd0d6edcc119790661bc9c63b1e28a16d3fce4adc7f6239ba
3
+ metadata.gz: 3b3e380696d9d2e8ce64b52d20baa6c09aa53259133e6b256769929e68b1d32b
4
+ data.tar.gz: b33b2c86616b7f93aeda7a669a3b27882a08b6a38205895636da62ae73e3a022
5
5
  SHA512:
6
- metadata.gz: b8eb83937c2a0cf5b1fad92fa98c160d9cc481793b3eeb51f1b8a71239ecc8cd0bcd4b5f6d32fc093c5b01a4cfba9e4bd119b66e13ebd58d797ca9486e3a3e72
7
- data.tar.gz: 14567a96d7cb741c17a5dbaff165ee9bc6dd09b3e293319c644081938a20c7f6bcfe363cb34d9370f0a1b637fb8d89788f8d00632b2c164e628c510821330b3b
6
+ metadata.gz: 2ae620e33819d2e1ce7a13b3e2633071e5564ac3fe01a201b429f32364b47069fae9cb28e736f7f8a23bf94c03552d82171473df4561c070e79ff86cdcb3dd8e
7
+ data.tar.gz: 4e18673c11b8147510fcf5e1456b11145b8632d32de75005fcd3702e71515284ea219389ae41e4e61932d7f472454ee119d9167b4000df88ce18c664407f01ec
data/.rubocop.yml CHANGED
@@ -1,4 +1,4 @@
1
- Metrics/LineLength:
1
+ Layout/LineLength:
2
2
  Max: 120
3
3
  Metrics/MethodLength:
4
4
  Max: 20
data/README.md CHANGED
@@ -35,5 +35,11 @@ to your `Dangerfile`
35
35
  1. Clone this repo
36
36
  2. Run `bundle install` to setup dependencies.
37
37
  3. Run `bundle exec rake spec` to run the tests.
38
+ 4. Run `bundle exec rubocop -A` to fix in-place what's fixable
38
39
  4. Use `bundle exec guard` to automatically have tests run as you make changes.
39
40
  5. Make your changes.
41
+
42
+ ### How to release new version
43
+ 1. Bump version in `lib/jacoco/gem_version.rb - X.Y.Z`
44
+ 2. `rake build`
45
+ 3. `gem push pkg/danger-jacoco-instacart-X.Y.Z.gem`
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jacoco
4
- VERSION = '0.1.15'
4
+ VERSION = '0.1.17'
5
5
  end
data/lib/jacoco/plugin.rb CHANGED
@@ -105,14 +105,61 @@ module Danger
105
105
 
106
106
  def classes(delimiter)
107
107
  class_to_file_path_hash = {}
108
- files_to_check.select { |file| files_extension.reduce(false) { |state, el| state || file.end_with?(el) } }
109
- .each do |file| # "src/java/com/example/CachedRepository.java"
110
- classname = file.split('.').first.split(delimiter)[1] # "com/example/CachedRepository"
111
- class_to_file_path_hash[classname] = file
112
- end
108
+ # Initialize files_extension if it's nil
109
+ @files_extension = ['.kt', '.java'] if @files_extension.nil?
110
+
111
+ filtered_files_to_check.each do |file| # "src/java/com/example/CachedRepository.java"
112
+ # Get the package path
113
+ package_path = file.split('.').first.split(delimiter)[1] # "com/example/CachedRepository"
114
+ next unless package_path
115
+
116
+ # Add the primary class (filename-based class)
117
+ class_to_file_path_hash[package_path] = file
118
+
119
+ # For Kotlin files, we need to look for multiple classes/interfaces in the same file
120
+ add_kotlin_declarations(file, package_path, class_to_file_path_hash) if file.end_with?('.kt')
121
+ end
113
122
  class_to_file_path_hash
114
123
  end
115
124
 
125
+ # Returns files that match the configured file extensions
126
+ def filtered_files_to_check
127
+ files_to_check.select { |file| @files_extension.reduce(false) { |state, el| state || file.end_with?(el) } }
128
+ end
129
+
130
+ # Scans a Kotlin file for additional class/interface declarations and adds them to the hash
131
+ def add_kotlin_declarations(file, package_path, class_to_file_path_hash)
132
+ return unless File.exist?(file)
133
+
134
+ file_content = File.read(file)
135
+
136
+ # Kotlin compiles top-level functions (e.g. @Composable funs) into a `<FileNameKt>` class.
137
+ # Always register it — the SAX parser skips it silently if it's absent from the XML.
138
+ parts = package_path.split('/')
139
+ kt_class_path = (parts[0..-2] + ["#{parts[-1]}Kt"]).join('/')
140
+ class_to_file_path_hash[kt_class_path] = file
141
+
142
+ # Look for class and interface declarations in the file
143
+ # Regex catches class/interface/object declarations with modifiers and generics
144
+ regex = /\b(?:(?:data|sealed|abstract|open|internal|private|protected|public|inline)\s+)*
145
+ (?:class|interface|object)\s+([A-Za-z0-9_]+)(?:<.*?>)?/x
146
+ declarations = file_content.scan(regex).flatten
147
+
148
+ # For each additional class/interface found (excluding the one matching the filename)
149
+ declarations.each do |class_name|
150
+ # Skip if it matches the primary class name (already added)
151
+ next if package_path.end_with?("/#{class_name}")
152
+
153
+ # Create full class path by replacing the last part with the class name
154
+ parts = package_path.split('/')
155
+ parts[-1] = class_name
156
+ additional_class_path = parts.join('/')
157
+
158
+ # Add to hash
159
+ class_to_file_path_hash[additional_class_path] = file
160
+ end
161
+ end
162
+
116
163
  # It returns a specific class code coverage and an emoji status as well
117
164
  def report_class(jacoco_class, file_path)
118
165
  report_result = {
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?><!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN"
2
+ "report.dtd">
3
+ <report name="test_report">
4
+ <sessioninfo id="test-id" start="1480057517395" dump="1480057526412"/>
5
+ <package name="com/example">
6
+ <class name="com/example/TopLevelFunctionsKt">
7
+ <counter type="INSTRUCTION" missed="5" covered="15"/>
8
+ <counter type="LINE" missed="1" covered="4"/>
9
+ <counter type="COMPLEXITY" missed="1" covered="3"/>
10
+ <counter type="METHOD" missed="1" covered="3"/>
11
+ <counter type="CLASS" missed="0" covered="1"/>
12
+ </class>
13
+ <sourcefile name="TopLevelFunctions.kt">
14
+ <counter type="INSTRUCTION" missed="5" covered="15"/>
15
+ <counter type="LINE" missed="1" covered="4"/>
16
+ <counter type="COMPLEXITY" missed="1" covered="3"/>
17
+ <counter type="METHOD" missed="1" covered="3"/>
18
+ <counter type="CLASS" missed="0" covered="1"/>
19
+ </sourcefile>
20
+ <counter type="INSTRUCTION" missed="5" covered="15"/>
21
+ <counter type="BRANCH" missed="0" covered="0"/>
22
+ <counter type="LINE" missed="1" covered="4"/>
23
+ <counter type="COMPLEXITY" missed="1" covered="3"/>
24
+ <counter type="METHOD" missed="1" covered="3"/>
25
+ <counter type="CLASS" missed="0" covered="1"/>
26
+ </package>
27
+ <counter type="INSTRUCTION" missed="5" covered="15"/>
28
+ <counter type="BRANCH" missed="0" covered="0"/>
29
+ <counter type="LINE" missed="1" covered="4"/>
30
+ <counter type="COMPLEXITY" missed="1" covered="3"/>
31
+ <counter type="METHOD" missed="1" covered="3"/>
32
+ <counter type="CLASS" missed="0" covered="1"/>
33
+ </report>
data/spec/jacoco_spec.rb CHANGED
@@ -384,6 +384,110 @@ module Danger
384
384
  expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 55% | :warning: |')
385
385
  end
386
386
  end
387
+
388
+ it 'detects top-level Kotlin functions file via the generated Kt-suffixed class' do
389
+ path_g = "#{File.dirname(__FILE__)}/fixtures/output_g.xml"
390
+
391
+ kotlin_file_path = 'src/kotlin/com/example/TopLevelFunctions.kt'
392
+ kotlin_file_content = <<~KOTLIN
393
+ package com.example
394
+
395
+ @Composable
396
+ fun FirstComposable() {}
397
+
398
+ @Composable
399
+ fun SecondComposable() {}
400
+ KOTLIN
401
+
402
+ allow(File).to receive(:exist?).and_call_original
403
+ allow(File).to receive(:exist?).with(kotlin_file_path).and_return(true)
404
+ allow(File).to receive(:read).and_call_original
405
+ allow(File).to receive(:read).with(kotlin_file_path).and_return(kotlin_file_content)
406
+
407
+ @my_plugin.files_to_check = [kotlin_file_path]
408
+ @my_plugin.minimum_project_coverage_percentage = 0
409
+ @my_plugin.minimum_class_coverage_percentage = 80
410
+ @my_plugin.minimum_composable_class_coverage_percentage = 80
411
+
412
+ class_file_hash = @my_plugin.classes(%r{/kotlin/})
413
+ expect(class_file_hash.keys).to include('com/example/TopLevelFunctionsKt')
414
+
415
+ @my_plugin.report path_g
416
+
417
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/TopLevelFunctionsKt` | 75% | 80% | :warning: |')
418
+ end
419
+
420
+ it 'test with kotlin multiples classes in same file' do
421
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
422
+
423
+ # Mock the Kotlin file with multiple classes
424
+ kotlin_file_path = 'src/kotlin/com/example/MultiClass.kt'
425
+ kotlin_file_content = <<~KOTLIN
426
+ package com.example
427
+
428
+ class MultiClass {
429
+ // some code
430
+ }
431
+
432
+ data class DataClass(val property: String) {
433
+ // some code
434
+ }
435
+
436
+ sealed class SealedClass {
437
+ // some code
438
+ }
439
+
440
+ private class PrivateClass {
441
+ // some code
442
+ }
443
+
444
+ abstract class AbstractClass {
445
+ // some code
446
+ }
447
+
448
+ class GenericClass<T> {
449
+ // some code
450
+ }
451
+
452
+ interface SomeInterface {
453
+ // some code
454
+ }
455
+
456
+ object SingletonObject {
457
+ // some code
458
+ }
459
+ KOTLIN
460
+
461
+ allow(File).to receive(:exist?).and_call_original
462
+ allow(File).to receive(:exist?).with(kotlin_file_path).and_return(true)
463
+ allow(File).to receive(:read).and_call_original
464
+ allow(File).to receive(:read).with(kotlin_file_path).and_return(kotlin_file_content)
465
+
466
+ @my_plugin.files_to_check = [kotlin_file_path]
467
+ @my_plugin.minimum_project_coverage_percentage = 0 # Avoid project coverage errors
468
+
469
+ # Use a block to capture the key-value pairs passed to classes
470
+ expect { |b| @my_plugin.classes(%r{/kotlin/}).each(&b) }.to yield_control.at_least(8).times
471
+
472
+ # Call report
473
+ @my_plugin.report path_a
474
+
475
+ # Check the class-to-file hash from SAXParser
476
+ class_file_hash = @my_plugin.classes(%r{/kotlin/})
477
+ expect(class_file_hash.keys).to include('com/example/MultiClass')
478
+ expect(class_file_hash.keys).to include('com/example/DataClass')
479
+ expect(class_file_hash.keys).to include('com/example/SealedClass')
480
+ expect(class_file_hash.keys).to include('com/example/PrivateClass')
481
+ expect(class_file_hash.keys).to include('com/example/AbstractClass')
482
+ expect(class_file_hash.keys).to include('com/example/GenericClass')
483
+ expect(class_file_hash.keys).to include('com/example/SomeInterface')
484
+ expect(class_file_hash.keys).to include('com/example/SingletonObject')
485
+
486
+ # All keys should map to the same file path
487
+ class_file_hash.each_value do |file_path|
488
+ expect(file_path).to eq(kotlin_file_path)
489
+ end
490
+ end
387
491
  end
388
492
  end
389
493
  end
data/spec/spec_helper.rb CHANGED
@@ -29,7 +29,6 @@ require 'danger_plugin'
29
29
  # it comes with an extra function `.string` which will
30
30
  # strip all ANSI colours from the string.
31
31
 
32
- # rubocop:disable Lint/NestedMethodDefinition
33
32
  def testing_ui
34
33
  @output = StringIO.new
35
34
  def @output.winsize
@@ -42,7 +41,6 @@ def testing_ui
42
41
  end
43
42
  cork
44
43
  end
45
- # rubocop:enable Lint/NestedMethodDefinition
46
44
 
47
45
  # Example environment (ENV) that would come from
48
46
  # running a PR on TravisCI
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danger-jacoco-instacart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.15
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Malinskiy
8
8
  - Alexander Bezverhni
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-06-21 00:00:00.000000000 Z
12
+ date: 2026-05-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: danger-plugin-api
@@ -211,13 +211,14 @@ files:
211
211
  - spec/fixtures/output_d.xml
212
212
  - spec/fixtures/output_e.xml
213
213
  - spec/fixtures/output_f.xml
214
+ - spec/fixtures/output_g.xml
214
215
  - spec/jacoco_spec.rb
215
216
  - spec/spec_helper.rb
216
217
  homepage: https://github.com/alexanderbezverhni/danger-jacoco
217
218
  licenses:
218
219
  - MIT
219
220
  metadata: {}
220
- post_install_message:
221
+ post_install_message:
221
222
  rdoc_options: []
222
223
  require_paths:
223
224
  - lib
@@ -232,8 +233,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
233
  - !ruby/object:Gem::Version
233
234
  version: '0'
234
235
  requirements: []
235
- rubygems_version: 3.1.2
236
- signing_key:
236
+ rubygems_version: 3.5.3
237
+ signing_key:
237
238
  specification_version: 4
238
239
  summary: A longer description of danger-jacoco.
239
240
  test_files:
@@ -243,5 +244,6 @@ test_files:
243
244
  - spec/fixtures/output_d.xml
244
245
  - spec/fixtures/output_e.xml
245
246
  - spec/fixtures/output_f.xml
247
+ - spec/fixtures/output_g.xml
246
248
  - spec/jacoco_spec.rb
247
249
  - spec/spec_helper.rb