deep-cover 0.1.1 → 0.1.2
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/.rspec +1 -0
- data/.travis.yml +3 -1
- data/Rakefile +1 -1
- data/bin/selfcov +1 -1
- data/deep_cover.gemspec +2 -1
- data/lib/deep_cover/analyser.rb +1 -2
- data/lib/deep_cover/analyser/base.rb +20 -6
- data/lib/deep_cover/analyser/covered_code_source.rb +0 -12
- data/lib/deep_cover/analyser/node.rb +11 -1
- data/lib/deep_cover/analyser/optionally_covered.rb +14 -0
- data/lib/deep_cover/auto_run.rb +36 -32
- data/lib/deep_cover/backports.rb +9 -0
- data/lib/deep_cover/base.rb +8 -1
- data/lib/deep_cover/cli/debugger.rb +6 -4
- data/lib/deep_cover/cli/deep_cover.rb +37 -6
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +50 -32
- data/lib/deep_cover/config.rb +16 -7
- data/lib/deep_cover/coverage.rb +8 -9
- data/lib/deep_cover/covered_code.rb +17 -18
- data/lib/deep_cover/node/base.rb +28 -4
- data/lib/deep_cover/node/branch.rb +10 -7
- data/lib/deep_cover/node/def.rb +2 -2
- data/lib/deep_cover/node/empty_body.rb +1 -1
- data/lib/deep_cover/node/mixin/can_augment_children.rb +1 -2
- data/lib/deep_cover/node/mixin/execution_location.rb +9 -6
- data/lib/deep_cover/node/mixin/has_child.rb +16 -17
- data/lib/deep_cover/node/mixin/has_tracker.rb +2 -6
- data/lib/deep_cover/node/mixin/rewriting.rb +9 -8
- data/lib/deep_cover/node/send.rb +57 -48
- data/lib/deep_cover/node/{boolean.rb → short_circuit.rb} +0 -0
- data/lib/deep_cover/reporter/istanbul.rb +2 -3
- data/lib/deep_cover/tools.rb +2 -1
- data/lib/deep_cover/tools/dasherize.rb +8 -0
- data/lib/deep_cover/tools/dump_covered_code.rb +12 -6
- data/lib/deep_cover/tools/format_char_cover.rb +2 -3
- data/lib/deep_cover/tools/slice.rb +7 -0
- data/lib/deep_cover/version.rb +1 -1
- metadata +7 -18
| @@ -13,19 +13,20 @@ module DeepCover | |
| 13 13 | 
             
                  def rewrite_child(child, name=nil)
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 | 
            +
                  # Replaces all the '%{local}' or '%{some_tracker}' in rewriting rules
         | 
| 16 17 | 
             
                  def resolve_rewrite(rule, context)
         | 
| 17 | 
            -
                    rule  | 
| 18 | 
            +
                    return if rule == nil
         | 
| 18 19 | 
             
                    sources = context.tracker_sources
         | 
| 19 | 
            -
                    rule | 
| 20 | 
            +
                    rule % {local: covered_code.local_var, node: '%{node}', **sources}
         | 
| 20 21 | 
             
                  end
         | 
| 21 22 |  | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 23 | 
            +
                  # Returns an array of [range, rule], where rule is a string containing '%{node}'
         | 
| 24 | 
            +
                  # Rules must be ordered inner-most first
         | 
| 25 | 
            +
                  def rewriting_rules
         | 
| 25 26 | 
             
                    [
         | 
| 26 | 
            -
                       | 
| 27 | 
            -
                       | 
| 28 | 
            -
                    ]
         | 
| 27 | 
            +
                      resolve_rewrite(rewrite, self),
         | 
| 28 | 
            +
                      resolve_rewrite(parent.rewrite_child(self), parent),
         | 
| 29 | 
            +
                    ].compact.map{|rule| [expression, rule]}
         | 
| 29 30 | 
             
                  end
         | 
| 30 31 | 
             
                end
         | 
| 31 32 | 
             
              end
         | 
    
        data/lib/deep_cover/node/send.rb
    CHANGED
    
    | @@ -1,75 +1,84 @@ | |
| 1 1 | 
             
            require_relative 'literals'
         | 
| 2 | 
            +
            require_relative 'branch'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module DeepCover
         | 
| 4 5 | 
             
              class Node
         | 
| 5 | 
            -
                class MethodName < Node
         | 
| 6 | 
            -
                  has_child name: Symbol
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                  def initialize(name, parent: raise, **kwargs)
         | 
| 9 | 
            -
                    super(parent, **kwargs, parent: parent, base_children: [name])
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  def loc_hash
         | 
| 13 | 
            -
                    # Expression is used in the rewriting
         | 
| 14 | 
            -
                    # if selector_end is present, then this won't be needed
         | 
| 15 | 
            -
                    {expression: parent.loc_hash[:selector_begin]}
         | 
| 16 | 
            -
                  end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  def executable?
         | 
| 19 | 
            -
                    false
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
             | 
| 23 6 | 
             
                class Send < Node
         | 
| 24 7 | 
             
                  check_completion
         | 
| 25 8 | 
             
                  has_child receiver: [Node, nil]
         | 
| 26 | 
            -
                  has_child  | 
| 27 | 
            -
                  has_extra_children arguments: Node | 
| 9 | 
            +
                  has_child message: Symbol
         | 
| 10 | 
            +
                  has_extra_children arguments: Node
         | 
| 28 11 | 
             
                  executed_loc_keys :dot, :selector_begin, :selector_end, :operator
         | 
| 29 12 |  | 
| 30 | 
            -
                  def method_name
         | 
| 31 | 
            -
                    method_name_wrapper.name
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
             | 
| 34 13 | 
             
                  def loc_hash
         | 
| 35 | 
            -
                     | 
| 36 | 
            -
                     | 
| 37 | 
            -
                    selector = base[:selector]
         | 
| 14 | 
            +
                    hash = super.dup
         | 
| 15 | 
            +
                    selector = hash.delete(:selector)
         | 
| 38 16 |  | 
| 39 | 
            -
                     | 
| 17 | 
            +
                    # Special case for foo[bar]=baz, but not for foo.[]= bar, baz: we split selector into begin and end
         | 
| 18 | 
            +
                    if base_node.location.dot == nil && [:[], :[]=].include?(message)
         | 
| 40 19 | 
             
                      hash[:selector_begin] = selector.resize(1)
         | 
| 41 20 | 
             
                      hash[:selector_end] = Parser::Source::Range.new(selector.source_buffer, selector.end_pos - 1, selector.end_pos)
         | 
| 42 21 | 
             
                    else
         | 
| 43 | 
            -
                      hash | 
| 22 | 
            +
                      hash.delete(:dot) if type == :safe_send # Hack. API to get a Parser::AST::Send::Map without the dot is crappy.
         | 
| 23 | 
            +
                      hash[:selector_begin] = selector
         | 
| 44 24 | 
             
                    end
         | 
| 45 25 |  | 
| 46 26 | 
             
                    hash
         | 
| 47 27 | 
             
                  end
         | 
| 48 28 |  | 
| 29 | 
            +
                  # Rules must be ordered inner-most first
         | 
| 30 | 
            +
                  def rewriting_rules
         | 
| 31 | 
            +
                    rules = super
         | 
| 32 | 
            +
                    if need_parentheses?
         | 
| 33 | 
            +
                      range = arguments.last.expression.with(begin_pos: loc_hash[:selector_begin].end_pos)
         | 
| 34 | 
            +
                      rules.unshift [range, '(%{node})']
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                    rules
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  private
         | 
| 40 | 
            +
             | 
| 49 41 | 
             
                  # Only need to add them to deal with ambiguous cases where a method is hidden by a local. Ex:
         | 
| 50 | 
            -
                  #    | 
| 51 | 
            -
                  #    | 
| 52 | 
            -
                  #    | 
| 53 | 
            -
                  #    | 
| 54 | 
            -
                  #    | 
| 55 | 
            -
                  def  | 
| 56 | 
            -
                     | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
                    return if self.loc_hash[:begin]
         | 
| 61 | 
            -
                    true
         | 
| 42 | 
            +
                  #   foo 42, 'hello'  #=> Works
         | 
| 43 | 
            +
                  #   foo (42), 'hello'  #=> Simplification of what DeepCover would generate, still works
         | 
| 44 | 
            +
                  #   foo = 1; foo 42, 'hello'  #=> works
         | 
| 45 | 
            +
                  #   foo = 1; foo (42), 'hello'  #=> syntax error.
         | 
| 46 | 
            +
                  #   foo = 1; foo((42), 'hello')  #=> works
         | 
| 47 | 
            +
                  def need_parentheses?
         | 
| 48 | 
            +
                    true unless
         | 
| 49 | 
            +
                      arguments.empty? || # No issue when no arguments
         | 
| 50 | 
            +
                      receiver || # No ambiguity if there is a receiver
         | 
| 51 | 
            +
                      loc_hash[:begin] # Ok if has parentheses
         | 
| 62 52 | 
             
                  end
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                class Csend < Node
         | 
| 56 | 
            +
                  include Branch
         | 
| 57 | 
            +
                  has_tracker :conditional
         | 
| 58 | 
            +
                  has_child receiver: Node,
         | 
| 59 | 
            +
                            rewrite: '(%{local}=%{node};%{conditional_tracker} if %{local} != nil;%{local})'
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  has_child actual_send: {safe_send: Send},
         | 
| 62 | 
            +
                            flow_entry_count: :conditional_tracker_hits
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def initialize(base_node, base_children: base_node.children, **)
         | 
| 65 | 
            +
                    send_without_receiver = base_node.updated(:safe_send, [nil, *base_node.children.drop(1)])
         | 
| 66 | 
            +
                    base_children = [base_children.first, send_without_receiver]
         | 
| 67 | 
            +
                    super
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  executed_loc_keys :dot
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  alias_method :execution_count, :flow_entry_count
         | 
| 63 73 |  | 
| 64 | 
            -
                  def  | 
| 65 | 
            -
                     | 
| 66 | 
            -
                    "%{node}("
         | 
| 74 | 
            +
                  def message
         | 
| 75 | 
            +
                    actual_send.message
         | 
| 67 76 | 
             
                  end
         | 
| 68 77 |  | 
| 69 | 
            -
                  def  | 
| 70 | 
            -
                     | 
| 71 | 
            -
             | 
| 72 | 
            -
                     | 
| 78 | 
            +
                  def branches
         | 
| 79 | 
            +
                    [ actual_send,
         | 
| 80 | 
            +
                      TrivialBranch.new(receiver, actual_send)
         | 
| 81 | 
            +
                    ]
         | 
| 73 82 | 
             
                  end
         | 
| 74 83 | 
             
                end
         | 
| 75 84 |  | 
| 
            File without changes
         | 
| @@ -46,12 +46,11 @@ module DeepCover | |
| 46 46 |  | 
| 47 47 | 
             
                    def convert_branch(node, branches = node.branches)
         | 
| 48 48 | 
             
                      # Currently, nyc seems to outputs the same location over and over...
         | 
| 49 | 
            -
                      loc = convert_range(node.expression)
         | 
| 50 49 | 
             
                      {
         | 
| 51 | 
            -
                        loc:  | 
| 50 | 
            +
                        loc: convert_range(node.expression),
         | 
| 52 51 | 
             
                        type: node.type,
         | 
| 53 52 | 
             
                        line: node.expression.line,
         | 
| 54 | 
            -
                        locations: branches.map{|n|  | 
| 53 | 
            +
                        locations: branches.map{|n| convert_range(n.expression || node.expression)}
         | 
| 55 54 | 
             
                      }
         | 
| 56 55 | 
             
                    end
         | 
| 57 56 |  | 
    
        data/lib/deep_cover/tools.rb
    CHANGED
    
    | @@ -3,8 +3,9 @@ module DeepCover | |
| 3 3 |  | 
| 4 4 | 
             
              require_relative 'tools/require_relative_dir'
         | 
| 5 5 | 
             
              extend Tools::RequireRelativeDir
         | 
| 6 | 
            -
               | 
| 6 | 
            +
              require_relative 'tools/silence_warnings'
         | 
| 7 7 | 
             
              extend Tools::SilenceWarnings
         | 
| 8 | 
            +
              require_relative_dir 'tools'
         | 
| 8 9 |  | 
| 9 10 | 
             
              # The functions defined in the submodules of Tools can be accessed
         | 
| 10 11 | 
             
              # either by extending the desired module, or all of them by extending
         | 
| @@ -1,20 +1,27 @@ | |
| 1 | 
            -
            require 'with_progress'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module DeepCover
         | 
| 2 | 
            +
              silence_warnings do
         | 
| 3 | 
            +
                require 'with_progress'
         | 
| 4 | 
            +
              end
         | 
| 4 5 | 
             
              module Tools::DumpCoveredCode
         | 
| 5 | 
            -
                def  | 
| 6 | 
            +
                def dump_covered_code_and_save(source_path, dest_path: Dir.mktmpdir)
         | 
| 6 7 | 
             
                  coverage = Coverage.new(tracker_global: '$_sc')
         | 
| 8 | 
            +
                  dump_covered_code(source_path, coverage: coverage, dest_path: dest_path)
         | 
| 9 | 
            +
                  coverage.save(dest_path)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def dump_covered_code(source_path, coverage: raise, dest_path: Dir.mktmpdir, root_path: source_path)
         | 
| 7 13 | 
             
                  source_path = File.join(File.expand_path(source_path), '')
         | 
| 8 14 | 
             
                  dest_path = File.join(File.expand_path(dest_path), '')
         | 
| 15 | 
            +
                  root_path = Pathname.new(root_path)
         | 
| 9 16 | 
             
                  skipped = []
         | 
| 10 17 | 
             
                  Dir.glob("#{source_path}**/*.rb").each.with_progress(title: 'Rewriting') do |path|
         | 
| 18 | 
            +
                    new_path = Pathname(path.gsub(source_path, dest_path))
         | 
| 11 19 | 
             
                    begin
         | 
| 12 | 
            -
                      covered_code = coverage.covered_code(path)
         | 
| 20 | 
            +
                      covered_code = coverage.covered_code(path, name: new_path.relative_path_from(root_path))
         | 
| 13 21 | 
             
                    rescue Parser::SyntaxError
         | 
| 14 22 | 
             
                      skipped << path
         | 
| 15 23 | 
             
                      next
         | 
| 16 24 | 
             
                    end
         | 
| 17 | 
            -
                    new_path = Pathname(path.gsub(source_path, dest_path))
         | 
| 18 25 | 
             
                    new_path.dirname.mkpath
         | 
| 19 26 | 
             
                    new_path.write(covered_code.covered_source)
         | 
| 20 27 | 
             
                  end
         | 
| @@ -25,7 +32,6 @@ module DeepCover | |
| 25 32 | 
             
                      ('...' if skipped.size > 3),
         | 
| 26 33 | 
             
                    ].compact.join("\n")
         | 
| 27 34 | 
             
                  end
         | 
| 28 | 
            -
                  coverage.save(dest_path)
         | 
| 29 35 | 
             
                  dest_path
         | 
| 30 36 | 
             
                end
         | 
| 31 37 | 
             
              end
         | 
| @@ -2,9 +2,8 @@ module DeepCover | |
| 2 2 | 
             
              module Tools::FormatCharCover
         | 
| 3 3 | 
             
                COLOR = {'x' => :red, ' ' => :green, '-' => :faint}
         | 
| 4 4 | 
             
                WHITESPACE_MAP = Hash.new{|_, v| v}.merge!(' ' => '·', "\t" => '→ ')
         | 
| 5 | 
            -
                def format_char_cover(covered_code, show_whitespace: false)
         | 
| 6 | 
            -
                  bc = covered_code.char_cover
         | 
| 7 | 
            -
             | 
| 5 | 
            +
                def format_char_cover(covered_code, show_whitespace: false, **options)
         | 
| 6 | 
            +
                  bc = covered_code.char_cover(**options)
         | 
| 8 7 | 
             
                  covered_code.buffer.source_lines.map.with_index do |line, line_index|
         | 
| 9 8 | 
             
                    next line if line.strip =~ /^#[ >]/
         | 
| 10 9 | 
             
                    line.chars.map.with_index do |c, c_index|
         | 
    
        data/lib/deep_cover/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: deep-cover
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Marc-André Lafortune
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: exe
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2017- | 
| 12 | 
            +
            date: 2017-11-02 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: parser
         | 
| @@ -81,20 +81,6 @@ dependencies: | |
| 81 81 | 
             
                - - ">="
         | 
| 82 82 | 
             
                  - !ruby/object:Gem::Version
         | 
| 83 83 | 
             
                    version: '0'
         | 
| 84 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 85 | 
            -
              name: ruby-progressbar
         | 
| 86 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 87 | 
            -
                requirements:
         | 
| 88 | 
            -
                - - "<"
         | 
| 89 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 90 | 
            -
                    version: 1.9.0
         | 
| 91 | 
            -
              type: :runtime
         | 
| 92 | 
            -
              prerelease: false
         | 
| 93 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 94 | 
            -
                requirements:
         | 
| 95 | 
            -
                - - "<"
         | 
| 96 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 97 | 
            -
                    version: 1.9.0
         | 
| 98 84 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 99 85 | 
             
              name: with_progress
         | 
| 100 86 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -228,6 +214,7 @@ files: | |
| 228 214 | 
             
            - lib/deep_cover/analyser/function.rb
         | 
| 229 215 | 
             
            - lib/deep_cover/analyser/ignore_uncovered.rb
         | 
| 230 216 | 
             
            - lib/deep_cover/analyser/node.rb
         | 
| 217 | 
            +
            - lib/deep_cover/analyser/optionally_covered.rb
         | 
| 231 218 | 
             
            - lib/deep_cover/analyser/per_char.rb
         | 
| 232 219 | 
             
            - lib/deep_cover/analyser/per_line.rb
         | 
| 233 220 | 
             
            - lib/deep_cover/analyser/statement.rb
         | 
| @@ -254,7 +241,6 @@ files: | |
| 254 241 | 
             
            - lib/deep_cover/node/base.rb
         | 
| 255 242 | 
             
            - lib/deep_cover/node/begin.rb
         | 
| 256 243 | 
             
            - lib/deep_cover/node/block.rb
         | 
| 257 | 
            -
            - lib/deep_cover/node/boolean.rb
         | 
| 258 244 | 
             
            - lib/deep_cover/node/branch.rb
         | 
| 259 245 | 
             
            - lib/deep_cover/node/case.rb
         | 
| 260 246 | 
             
            - lib/deep_cover/node/collections.rb
         | 
| @@ -281,6 +267,7 @@ files: | |
| 281 267 | 
             
            - lib/deep_cover/node/module.rb
         | 
| 282 268 | 
             
            - lib/deep_cover/node/root.rb
         | 
| 283 269 | 
             
            - lib/deep_cover/node/send.rb
         | 
| 270 | 
            +
            - lib/deep_cover/node/short_circuit.rb
         | 
| 284 271 | 
             
            - lib/deep_cover/node/splat.rb
         | 
| 285 272 | 
             
            - lib/deep_cover/node/variables.rb
         | 
| 286 273 | 
             
            - lib/deep_cover/parser_ext/range.rb
         | 
| @@ -289,6 +276,7 @@ files: | |
| 289 276 | 
             
            - lib/deep_cover/tools.rb
         | 
| 290 277 | 
             
            - lib/deep_cover/tools/builtin_coverage.rb
         | 
| 291 278 | 
             
            - lib/deep_cover/tools/camelize.rb
         | 
| 279 | 
            +
            - lib/deep_cover/tools/dasherize.rb
         | 
| 292 280 | 
             
            - lib/deep_cover/tools/dump_covered_code.rb
         | 
| 293 281 | 
             
            - lib/deep_cover/tools/execute_sample.rb
         | 
| 294 282 | 
             
            - lib/deep_cover/tools/format.rb
         | 
| @@ -298,6 +286,7 @@ files: | |
| 298 286 | 
             
            - lib/deep_cover/tools/our_coverage.rb
         | 
| 299 287 | 
             
            - lib/deep_cover/tools/require_relative_dir.rb
         | 
| 300 288 | 
             
            - lib/deep_cover/tools/silence_warnings.rb
         | 
| 289 | 
            +
            - lib/deep_cover/tools/slice.rb
         | 
| 301 290 | 
             
            - lib/deep_cover/version.rb
         | 
| 302 291 | 
             
            homepage: http://github.com
         | 
| 303 292 | 
             
            licenses:
         | 
| @@ -311,7 +300,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 311 300 | 
             
              requirements:
         | 
| 312 301 | 
             
              - - ">="
         | 
| 313 302 | 
             
                - !ruby/object:Gem::Version
         | 
| 314 | 
            -
                  version:  | 
| 303 | 
            +
                  version: 2.0.0
         | 
| 315 304 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 316 305 | 
             
              requirements:
         | 
| 317 306 | 
             
              - - ">="
         |