xcov 0.12.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3bdbe837c78361b3aeaf31da767e58129ccd508d
4
- data.tar.gz: 4f2f77ba7fd3921e11a89f12f974181d33e8f469
3
+ metadata.gz: a541fad0337d84ad690cb556ead08462a202d4ca
4
+ data.tar.gz: 92103ad669d1a7b30a7873ed400ea928bc1ba296
5
5
  SHA512:
6
- metadata.gz: a8ac0d10a2ece773d76ff02f7394c244f8d992bc951826367fbaa2e4e5df9b1601a3c71c4c0a4be42221e8243c4f9237b4d55281ab79ea1bbbfb2650037322f7
7
- data.tar.gz: 5ba1246ccfb26b870b46494848b901592c61a2e68bc1bf72a7d37977bdea6864859b7f3fcd9fef976793fbf630a78a409f6b600dd40e4602653c8dd466904726
6
+ metadata.gz: 0a0cd8ee13eec12362f5b89e92c3b91711f7fa7ead460985166439026cdc34c858a7f2b281503203f86e4aa8d75280359d0ca4ad2ef7a49b74e01da2e3b7f754
7
+ data.tar.gz: 25996d44347d50e596b0c0546917c146417c24498f6ef71534730aa8560c13aa603163aae0c5e50cc8ae42a157a2e3a6bde380c20eca7bcd9fc6e3357d678c85
data/README.md CHANGED
@@ -58,6 +58,7 @@ xcov -w LystSDK.xcworkspace -s LystSDK -o xcov_output
58
58
  * `--json_report`: Enables the creation of a json report (optional).
59
59
  * `--markdown_report`: Enables the creation of a markdown report (optional).
60
60
  * `--skip_slack`: Add this flag to avoid publishing results on Slack (optional).
61
+ * `--only_project_targets`: Display the coverage only for main project targets (e.g. skip Pods targets).
61
62
 
62
63
  _**Note:** All paths you provide should be absolute and unescaped_
63
64
 
@@ -0,0 +1,31 @@
1
+ module Xcov
2
+ class Line
3
+
4
+ attr_reader :execution_count
5
+ attr_reader :executable
6
+ attr_reader :ranges
7
+
8
+ def initialize (execution_count, executable, ranges = nil)
9
+ @execution_count = execution_count
10
+ @executable = executable
11
+ @ranges = ranges
12
+ end
13
+
14
+ def covered?
15
+ execution_count > 0
16
+ end
17
+
18
+ # Class methods
19
+
20
+ def self.map (dictionary)
21
+ ranges = map_ranges(dictionary["ranges"])
22
+ Line.new(dictionary["executionCount"], dictionary["executable"], ranges)
23
+ end
24
+
25
+ def self.map_ranges (dictionaries)
26
+ return nil if dictionaries.nil?
27
+ dictionaries.map { |dictionary| Range.map(dictionary) }
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ module Xcov
2
+ class Range
3
+
4
+ attr_reader :execution_count
5
+ attr_reader :location
6
+ attr_reader :length
7
+
8
+ def initialize (execution_count, location, length)
9
+ @execution_count = execution_count
10
+ @location = location
11
+ @length = length
12
+ end
13
+
14
+ # Class methods
15
+
16
+ def self.map (dictionary)
17
+ Range.new(
18
+ dictionary["executionCount"],
19
+ dictionary["location"],
20
+ dictionary["length"]
21
+ )
22
+ end
23
+
24
+ end
25
+ end
@@ -17,12 +17,19 @@ module Xcov
17
17
 
18
18
  def average_coverage targets
19
19
  return 0 if targets.count == 0
20
+ return targets.first.coverage if targets.count == 1
20
21
 
21
- coverage = 0
22
- targets.each do |target|
23
- coverage = coverage + target.coverage
22
+ executable = targets.reduce(0) do |partial_result, target|
23
+ partial_result + target.executable_lines
24
24
  end
25
- coverage / targets.count
25
+
26
+ covered = targets.reduce(0) do |partial_result, target|
27
+ partial_result + target.covered_lines
28
+ end
29
+
30
+ return 0 if executable == 0 # avoid ZeroDivisionError
31
+
32
+ covered.to_f / executable.to_f
26
33
  end
27
34
 
28
35
  def print_description
@@ -75,6 +82,15 @@ module Xcov
75
82
  filtered_targets = filtered_targets.select { |target| self.included_targets.include?(target["name"])}
76
83
  end
77
84
 
85
+ supported_targets = Xcov.project.targets
86
+ if Xcov.config[:only_project_targets] && !supported_targets.empty?
87
+ filtered_targets = filtered_targets.select do |target|
88
+ name = target["name"]
89
+ name.slice! File.extname(name) # remove target extensions
90
+ supported_targets.include?(name)
91
+ end
92
+ end
93
+
78
94
  filtered_targets
79
95
  end
80
96
 
@@ -10,8 +10,9 @@ module Xcov
10
10
  attr_accessor :coverage
11
11
  attr_accessor :functions
12
12
  attr_accessor :function_templates
13
+ attr_accessor :lines
13
14
 
14
- def initialize (name, location, coverage, functions)
15
+ def initialize (name, location, coverage, functions, lines = nil)
15
16
  @name = CGI::escapeHTML(name)
16
17
  @location = CGI::escapeHTML(location)
17
18
  @coverage = coverage
@@ -21,6 +22,7 @@ module Xcov
21
22
  @coverage_color = self.create_coverage_color
22
23
  @id = Source.create_id(name)
23
24
  @type = Source.type(name)
25
+ @lines = lines
24
26
 
25
27
  if @ignored
26
28
  UI.message "Ignoring #{name} coverage".yellow
@@ -60,6 +62,15 @@ module Xcov
60
62
  return value
61
63
  end
62
64
 
65
+ def number_of_executable_lines
66
+ return 0 if lines.nil? || lines.empty?
67
+ lines.select { |line| line.executable }.count
68
+ end
69
+
70
+ def number_of_covered_lines
71
+ return 0 if lines.nil? || lines.empty?
72
+ lines.select { |line| line.covered? }.count
73
+ end
63
74
 
64
75
  # Class methods
65
76
 
@@ -68,8 +79,13 @@ module Xcov
68
79
  location = dictionary["location"]
69
80
  coverage = dictionary["coverage"]
70
81
  functions = dictionary["functions"].map { |function| Function.map(function)}
82
+ lines = map_lines(dictionary["lines"])
83
+ Source.new(name, location, coverage, functions, lines)
84
+ end
71
85
 
72
- Source.new(name, location, coverage, functions)
86
+ def self.map_lines (dictionaries)
87
+ return nil if dictionaries.nil?
88
+ dictionaries.map { |line| Line.map(line) }
73
89
  end
74
90
 
75
91
  def self.type (name)
@@ -4,14 +4,18 @@ module Xcov
4
4
  class Target < Xcov::Base
5
5
 
6
6
  attr_accessor :name
7
- attr_accessor :coverage
7
+ attr_accessor :executable_lines # number of executable lines in target
8
+ attr_accessor :covered_lines # number of covered lines in target
8
9
  attr_accessor :files
9
10
  attr_accessor :file_templates
10
11
 
11
- def initialize (name, coverage, files)
12
+ def initialize (name, executable, covered, files)
12
13
  @name = CGI::escapeHTML(name)
13
- @coverage = coverage
14
+ @executable_lines = executable
15
+ @covered_lines = covered
14
16
  @files = files
17
+ # we cast to floats because integers always return 0
18
+ @coverage = executable == 0 ? 0.0 : covered.to_f / executable # avoid ZeroDivisionError
15
19
  @displayable_coverage = self.create_displayable_coverage
16
20
  @coverage_color = self.create_coverage_color
17
21
  @id = Target.create_id(name)
@@ -56,18 +60,13 @@ module Xcov
56
60
  name = dictionary["name"]
57
61
  files = dictionary["files"].map { |file| Source.map(file)}
58
62
  files = files.sort &by_coverage_with_ignored_at_the_end
59
- coverage = Target.calculate_coverage(files)
60
63
 
61
- Target.new(name, coverage, files)
62
- end
64
+ non_ignored_files = Target.select_non_ignored_files(files)
65
+ executable = Target.calculate_number_of_executable_lines(non_ignored_files)
66
+ covered = Target.calculate_number_of_covered_lines(non_ignored_files)
63
67
 
64
- def self.calculate_coverage (files)
65
- coverage = 0
66
- non_ignored_files = files.select { |file| !file.ignored }
67
- non_ignored_files.each { |file| coverage += file.coverage }
68
- coverage = coverage / non_ignored_files.count unless non_ignored_files.empty?
69
68
 
70
- coverage
69
+ Target.new(name, executable, covered, files)
71
70
  end
72
71
 
73
72
  def self.by_coverage_with_ignored_at_the_end
@@ -83,5 +82,25 @@ module Xcov
83
82
  }
84
83
  end
85
84
 
85
+ def self.select_non_ignored_files(files)
86
+ files.select { |file| !file.ignored }
87
+ end
88
+
89
+ def self.calculate_number_of_covered_lines (files)
90
+ return 0 if files.nil? || files.empty?
91
+
92
+ files.reduce(0) do |partial_result, file|
93
+ partial_result + file.number_of_covered_lines
94
+ end
95
+ end
96
+
97
+ def self.calculate_number_of_executable_lines (files)
98
+ return 0 if files.nil? || files.empty?
99
+
100
+ files.reduce(0) do |partial_result, file|
101
+ partial_result + file.number_of_executable_lines
102
+ end
103
+ end
104
+
86
105
  end
87
106
  end
data/lib/xcov/options.rb CHANGED
@@ -119,12 +119,19 @@ module Xcov
119
119
  default_value: false),
120
120
  FastlaneCore::ConfigItem.new(key: :exclude_targets,
121
121
  optional: true,
122
- conflicting_options: [:include_targets],
122
+ conflicting_options: [:include_targets, :only_project_targets],
123
123
  description: "Comma separated list of targets to exclude from coverage report"),
124
124
  FastlaneCore::ConfigItem.new(key: :include_targets,
125
125
  optional: true,
126
- conflicting_options: [:exclude_targets],
127
- description: "Comma separated list of targets to include in coverage report. If specified then exlude_targets will be ignored")
126
+ conflicting_options: [:exclude_targets, :only_project_targets],
127
+ description: "Comma separated list of targets to include in coverage report. If specified then exlude_targets will be ignored"),
128
+ FastlaneCore::ConfigItem.new(key: :only_project_targets,
129
+ optional: true,
130
+ conflicting_options: [:exclude_targets, :include_targets],
131
+ description: "Display the coverage only for main project targets (e.g. skip Pods targets)",
132
+ is_string: false,
133
+ default_value: false)
134
+
128
135
  ]
129
136
  end
130
137
 
@@ -0,0 +1,33 @@
1
+ require "fastlane_core"
2
+ require "xcodeproj"
3
+
4
+ module FastlaneCore
5
+ class Project
6
+
7
+ # Returns project targets
8
+ def targets
9
+ project_path = get_project_path
10
+ return [] if project_path.nil?
11
+
12
+ proj = Xcodeproj::Project.open(project_path)
13
+
14
+ proj.targets.map do |target|
15
+ target.name
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def get_project_path
22
+ # Given the workspace and scheme, we can compute project path
23
+ if workspace?
24
+ if options[:workspace] && options[:scheme]
25
+ build_settings(key: "PROJECT_FILE_PATH")
26
+ end
27
+ else
28
+ options[:project]
29
+ end
30
+ end
31
+
32
+ end
33
+ end
data/lib/xcov/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Xcov
2
2
 
3
- VERSION = "0.12.5"
3
+ VERSION = "1.0.0"
4
4
  DESCRIPTION = "xcov is a friendly visualizer for Xcode's code coverage files"
5
5
 
6
6
  end
Binary file
@@ -1,5 +1,5 @@
1
1
  module Xcov
2
2
  module Core
3
- VERSION = "0.3"
3
+ VERSION = "0.4"
4
4
  end
5
5
  end
data/lib/xcov-core.rb CHANGED
@@ -13,7 +13,7 @@ module Xcov
13
13
 
14
14
  def self.parse(file)
15
15
  report_output = Tempfile.new("report.json")
16
- command = "#{ENV['XCOV_CORE_LIBRARY_PATH'].shellescape} -s #{file.shellescape} -o #{report_output.path.shellescape} --add-location"
16
+ command = "#{ENV['XCOV_CORE_LIBRARY_PATH'].shellescape} -s #{file.shellescape} -o #{report_output.path.shellescape} --include-lines-info"
17
17
  description = [{ prefix: "Parsing .xccoverage file: " }]
18
18
  execute_command(command, description)
19
19
  output_file = File.read(report_output.path)
data/lib/xcov.rb CHANGED
@@ -11,6 +11,9 @@ require 'xcov/model/report'
11
11
  require 'xcov/model/target'
12
12
  require 'xcov/model/source'
13
13
  require 'xcov/model/function'
14
+ require 'xcov/model/line'
15
+ require 'xcov/model/range'
16
+ require 'xcov/project_extensions'
14
17
  require 'fastlane_core'
15
18
 
16
19
  module Xcov
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.5
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Vidal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-17 00:00:00.000000000 Z
11
+ date: 2017-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastlane
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: xcodeproj
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.4'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.4'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: terminal-table
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -203,10 +217,13 @@ files:
203
217
  - lib/xcov/manager.rb
204
218
  - lib/xcov/model/base.rb
205
219
  - lib/xcov/model/function.rb
220
+ - lib/xcov/model/line.rb
221
+ - lib/xcov/model/range.rb
206
222
  - lib/xcov/model/report.rb
207
223
  - lib/xcov/model/source.rb
208
224
  - lib/xcov/model/target.rb
209
225
  - lib/xcov/options.rb
226
+ - lib/xcov/project_extensions.rb
210
227
  - lib/xcov/runner.rb
211
228
  - lib/xcov/slack_poster.rb
212
229
  - lib/xcov/version.rb