Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of git://github.com/hooligan495/rcov into hooli…

…gan495/master
  • Loading branch information...
commit 5f794b679867932244d5108f807b511cb49e991b 2 parents 2586447 + ed07441
Chad Humphries authored
115 Rakefile
View
@@ -6,6 +6,8 @@ $:.unshift "lib" if File.directory? "lib"
require 'rcov/rcovtask'
require 'rake/testtask'
require 'rake/rdoctask'
+require 'rake/gempackagetask'
+require 'rake/clean'
# Use the specified rcov executable instead of the one in $PATH
# (this way we get a sort of informal functional test).
@@ -42,10 +44,18 @@ Rcov::RcovTask.new(:rcov_ccanalyzer) do |t|
end
desc "Run the unit tests with rcovrt."
-Rake::TestTask.new(:test_rcovrt => ["ext/rcovrt/rcovrt.so"]) do |t|
- t.libs << "ext/rcovrt"
- t.test_files = FileList['test/*_test.rb']
- t.verbose = true
+if RUBY_PLATFORM == 'java'
+ Rake::TestTask.new(:test_rcovrt => ["lib/rcovrt.jar"]) do |t|
+ t.libs << "lib"
+ t.test_files = FileList['test/*_test.rb']
+ t.verbose = true
+ end
+else
+ Rake::TestTask.new(:test_rcovrt => ["ext/rcovrt/rcovrt.so"]) do |t|
+ t.libs << "ext/rcovrt"
+ t.test_files = FileList['test/*_test.rb']
+ t.verbose = true
+ end
end
file "ext/rcovrt/rcovrt.so" => FileList["ext/rcovrt/*.c"] do
@@ -83,4 +93,101 @@ task :install do
sh "sudo ruby setup.rb install"
end
+
+PKG_FILES = ["bin/rcov", "lib/rcov.rb", "lib/rcov/lowlevel.rb", "lib/rcov/xx.rb", "lib/rcov/version.rb", "lib/rcov/rant.rb", "lib/rcov/report.rb", "lib/rcov/rcovtask.rb", "ext/rcovrt/extconf.rb", "ext/rcovrt/rcovrt.c", "ext/rcovrt/callsite.c", "LEGAL", "LICENSE", "Rakefile", "Rantfile", "README.rake", "README.rant", "README.emacs", "README.en", "README.vim", "README.API", "THANKS", "test/functional_test.rb", "test/file_statistics_test.rb", "test/assets/sample_03.rb", "test/assets/sample_05-new.rb", "test/code_coverage_analyzer_test.rb", "test/assets/sample_04.rb", "test/assets/sample_02.rb", "test/assets/sample_05-old.rb", "test/assets/sample_01.rb", "test/turn_off_rcovrt.rb", "test/call_site_analyzer_test.rb", "test/assets/sample_05.rb", "rcov.vim", "rcov.el", "setup.rb", "BLURB", "CHANGES"]
+
+# gem management tasks Use these to build the java code before creating the gem package
+# this code can also be used to generate the MRI gem. But I left the gemspec file in too.
+spec = Gem::Specification.new do |s|
+ s.name = %q{rcov}
+ s.version = "0.8.1.3.0"
+
+ s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
+ s.authors = ["Mauricio Fernandez"]
+ s.cert_chain = nil
+ s.date = %q{2007-11-21}
+ s.default_executable = %q{rcov}
+ s.description = %q{rcov is a code coverage tool for Ruby. It is commonly used for viewing overall test unit coverage of target code. It features fast execution (20-300 times faster than previous tools), multiple analysis modes, XHTML and several kinds of text reports, easy automation with Rake via a RcovTask, fairly accurate coverage information through code linkage inference using simple heuristics, colorblind-friendliness...}
+ s.email = %q{mfp@acm.org}
+ s.executables = ["rcov"]
+ s.extensions = ["ext/rcovrt/extconf.rb"]
+ s.platform = Gem::Platform::RUBY
+ s.extra_rdoc_files = ["README.API", "README.rake", "README.rant", "README.vim"]
+ s.files = PKG_FILES
+ s.has_rdoc = true
+ s.homepage = %q{http://eigenclass.org/hiki.rb?rcov}
+ s.rdoc_options = ["--main", "README.API", "--title", "rcov code coverage tool"]
+ s.require_paths = ["lib"]
+ s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
+ s.rubygems_version = %q{1.2.0}
+ s.summary = %q{Code coverage analysis tool for Ruby}
+ s.test_files = ["test/functional_test.rb", "test/file_statistics_test.rb", "test/code_coverage_analyzer_test.rb", "test/call_site_analyzer_test.rb"]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 1
+
+ if current_version >= 3 then
+ else
+ end
+ else
+ end
+end
+
+#tasks added in to support generating the JRuby gem.
+if RUBY_PLATFORM == 'java'
+ spec.platform = "jruby"
+ spec.extensions = []
+ #add the jruby extension to the file list
+ PKG_FILES << "lib/rcovrt.jar"
+
+ def java_classpath_arg
+ begin
+ require 'java'
+ classpath = java.lang.System.getProperty('java.class.path')
+ rescue LoadError
+ end
+
+ if classpath.empty?
+ classpath = FileList["#{ENV['JRUBY_HOME']}/lib/*.jar"].join(File::PATH_SEPARATOR)
+ end
+
+ classpath ? "-cp #{classpath}" : ""
+ end
+
+
+ CLEAN.include ["ext/java/classes", "lib/rcovrt.jar", "pkg"]
+
+ def compile_java
+ mkdir_p "ext/java/classes"
+ sh "javac -g -target 1.5 -source 1.5 -d ext/java/classes #{java_classpath_arg} #{FileList['ext/java/src/**/*.java'].join(' ')}"
+ end
+
+ def make_jar
+ require 'fileutils'
+ lib = File.join(File.dirname(__FILE__), 'lib')
+ FileUtils.mkdir(lib) unless File.exists? lib
+ sh "jar cf lib/rcovrt.jar -C ext/java/classes/ ."
+ end
+
+ file 'lib/rcovrt.jar' => FileList["ext/java/src/*.java"] do
+ compile_java
+ make_jar
+ end
+
+ desc "compile the java extension and put it into the lib directory"
+ task :java_compile => ["lib/rcovrt.jar"]
+
+end
+
+Rake::GemPackageTask.new(spec) do |p|
+ p.need_tar = true
+ p.gem_spec = spec
+end
+
+#extend the gem task to include the java_compile
+if RUBY_PLATFORM == 'java'
+ Rake::Task["pkg"].enhance(["java_compile"])
+end
+
# vim: set sw=2 ft=ruby:
134 ext/java/src/CallsiteHook.java
View
@@ -0,0 +1,134 @@
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jruby.Ruby;
+import org.jruby.RubyArray;
+import org.jruby.RubyHash;
+import org.jruby.runtime.Frame;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.RubyEvent;
+import org.jruby.runtime.builtin.IRubyObject;
+
+public class CallsiteHook extends RcovHook {
+
+ private static CallsiteHook callsiteHook;
+
+ public static CallsiteHook getCallsiteHook() {
+ if (callsiteHook == null) {
+ callsiteHook = new CallsiteHook();
+ }
+ return callsiteHook;
+ }
+
+ private boolean active;
+ private RubyHash defsites;
+ private RubyHash callsites;
+
+ private CallsiteHook() {
+ super();
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public boolean isInterestedInEvent(RubyEvent event) {
+ return event == RubyEvent.CALL || event == RubyEvent.C_CALL;
+ }
+
+ public RubyArray getCallsiteInfo(Ruby runtime) {
+ RubyArray info = runtime.newArray();
+ info.add(getCallsites(runtime));
+ info.add(getDefsites(runtime));
+ return info;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ public RubyHash resetDefsites() {
+ defsites.clear();
+ return defsites;
+ }
+
+ public void eventHandler(ThreadContext context, String event, String file, int line,
+ String name, IRubyObject type) {
+ RubyArray currentMethod = context.getRuntime().newArray();
+ currentMethod.add(context.getFrameKlazz());
+ currentMethod.add(context.getRuntime().newSymbol(name));
+
+ RubyArray fileLoc = context.getRuntime().newArray();
+ fileLoc.add(file);
+ fileLoc.add(Long.valueOf(line));
+
+ defsites = getDefsites(context.getRuntime());
+ defsites.put(currentMethod, fileLoc);
+
+ callsites = getCallsites(context.getRuntime());
+ if (!callsites.containsKey(currentMethod)) {
+ callsites.put(currentMethod, RubyHash.newHash(context.getRuntime()));
+ }
+ RubyHash hash = (RubyHash) callsites.get(currentMethod);
+
+ RubyArray callerArray = customBacktrace(context);
+ if (!hash.containsKey(callerArray)) {
+ hash.put(callerArray, Long.valueOf(0));
+ }
+ Long count = (Long) hash.get(callerArray);
+ long itCount = count.longValue() + 1L;
+ hash.put(callerArray, Long.valueOf(itCount));
+
+ }
+
+ private RubyArray customBacktrace(ThreadContext context) {
+ Frame[] frames = context.createBacktrace(1, false);
+ RubyArray ary = context.getRuntime().newArray();
+ ary.addAll(formatBacktrace(context.getRuntime(), frames[frames.length - 1]));
+
+ return context.getRuntime().newArray((IRubyObject) ary);
+ }
+
+ /**
+ * TODO: The logic in this method really needs to be wrapped in a backtrace
+ * object or something. Then I could fix the file path issues that cause
+ * test failures.
+ * @param runtime
+ * @param backtrace
+ * @return
+ */
+ private RubyArray formatBacktrace(Ruby runtime, Frame backtrace) {
+ RubyArray ary = runtime.newArray();
+ if ( backtrace == null ) {
+ ary.add(runtime.getNil());
+ ary.add(runtime.getNil());
+ ary.add("");
+ ary.add(Long.valueOf(0));
+ } else {
+ ary.add( backtrace.getKlazz());
+ ary.add( ( backtrace.getName() == null ?
+ runtime.getNil() :
+ runtime.newSymbol( backtrace.getName() ) ) );
+ ary.add(backtrace.getFile());
+ //Add 1 to compensate for the zero offset in the Frame elements.
+ ary.add(backtrace.getLine() + 1);
+ }
+
+ return ary;
+ }
+
+ private RubyHash getCallsites(Ruby runtime) {
+ if (this.callsites == null) {
+ this.callsites = RubyHash.newHash(runtime);
+ }
+ return this.callsites;
+ }
+
+ private RubyHash getDefsites(Ruby runtime) {
+ if (this.defsites == null) {
+ this.defsites = RubyHash.newHash(runtime);
+ }
+ return this.defsites;
+ }
+
+}
111 ext/java/src/CoverageHook.java
View
@@ -0,0 +1,111 @@
+import org.jruby.Ruby;
+import org.jruby.RubyArray;
+import org.jruby.RubyHash;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.RubyEvent;
+import org.jruby.runtime.builtin.IRubyObject;
+
+
+public class CoverageHook extends RcovHook {
+
+ private static CoverageHook hook;
+
+ public static CoverageHook getCoverageHook() {
+ if (hook == null) {
+ hook = new CoverageHook();
+ }
+ return hook;
+ }
+
+ private boolean active;
+ private RubyHash cover;
+
+ private CoverageHook() {
+ super();
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+ public void eventHandler(ThreadContext context, String event, String file, int line,
+ String name, IRubyObject type) {
+
+ //Line numbers are 1s based. Arrays are zero based. We need to compensate for that.
+ line -= 1;
+
+ // Make sure that we have SCRIPT_LINES__ and it's a hash
+ RubyHash scriptLines = getScriptLines(context.getRuntime());
+ if (scriptLines == null || !scriptLines.containsKey(file)) {
+ return;
+ }
+
+ // make sure the file's source lines are in SCRIPT_LINES__
+ cover = getCover(context.getRuntime());
+ RubyArray lines = (RubyArray) scriptLines.get(file);
+ if (lines == null || cover == null){
+ return;
+ }
+
+ // make sure file's counts are in COVER and set to zero
+ RubyArray counts = (RubyArray) cover.get(file);
+ if (counts == null) {
+ counts = context.getRuntime().newArray();
+ for (int i = 0; i < lines.size(); i++) {
+ counts.add(Long.valueOf(0));
+ }
+ cover.put(file, counts);
+ }
+
+ // in the case of code generation (one example is instance_eval for routes optimization)
+ // We could get here and see that we are not matched up with what we expect
+ if (counts.size() <= line ) {
+ for (int i=counts.size(); i<= line; i++) {
+ counts.add(Long.valueOf(0));
+ }
+ }
+
+ // update counts in COVER
+ Long count = (Long) counts.get(line);
+ if (count == null) {
+ count = Long.valueOf(0);
+ }
+ count = Long.valueOf(count.longValue() + 1);
+ counts.set(line , count);
+ }
+
+ public boolean isInterestedInEvent(RubyEvent event) {
+ return event == RubyEvent.CALL || event == RubyEvent.LINE || event == RubyEvent.RETURN || event == RubyEvent.CLASS;
+ }
+
+ /**
+ * Returns the COVER hash, setting up the COVER constant if necessary.
+ * @param runtime
+ * @return
+ */
+ public RubyHash getCover(Ruby runtime) {
+ if (cover == null) {
+ cover = RubyHash.newHash(runtime);
+ }
+ return cover;
+ }
+
+ public RubyHash getScriptLines(Ruby runtime) {
+ IRubyObject scriptLines = runtime.getObject().getConstantAt("SCRIPT_LINES__");
+ if (scriptLines instanceof RubyHash) {
+ return (RubyHash) scriptLines;
+ } else {
+ return null;
+ }
+ }
+
+ public IRubyObject resetCoverage(Ruby runtime) {
+ getCover(runtime).clear();
+ return runtime.getNil();
+ }
+
+}
11 ext/java/src/RcovHook.java
View
@@ -0,0 +1,11 @@
+import org.jruby.runtime.EventHook;
+
+
+public abstract class RcovHook extends EventHook {
+
+ /** returns true if the hook is set */
+ abstract boolean isActive();
+
+ /** used to mark the hook set or unset */
+ abstract void setActive(boolean active);
+}
134 ext/java/src/RcovrtService.java
View
@@ -0,0 +1,134 @@
+import org.jruby.Ruby;
+import org.jruby.RubyArray;
+import org.jruby.RubyFixnum;
+import org.jruby.RubyHash;
+import org.jruby.RubyModule;
+import org.jruby.RubyObjectAdapter;
+import org.jruby.RubySymbol;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.BasicLibraryService;
+import org.jruby.javasupport.JavaEmbedUtils;
+import org.jruby.javasupport.JavaUtil;
+
+public class RcovrtService implements BasicLibraryService {
+
+ private static RubyObjectAdapter rubyApi;
+
+ public boolean basicLoad(Ruby runtime) {
+ RubyModule rcov = runtime.getOrCreateModule("Rcov");
+ RubyModule rcov__ = runtime.defineModuleUnder("RCOV__", rcov);
+
+ IRubyObject sl = runtime.getObject().getConstantAt("SCRIPT_LINES__");
+ if (sl == null) {
+ runtime.getObject().setConstant("SCRIPT_LINES__", RubyHash.newHash(runtime));
+ }
+
+ rubyApi = JavaEmbedUtils.newObjectAdapter();
+ rcov__.defineAnnotatedMethods(RcovrtService.class);
+ return true;
+ }
+
+
+ @JRubyMethod(name="reset_callsite", meta = true)
+ public static IRubyObject resetCallsite(IRubyObject recv) {
+ CallsiteHook hook = CallsiteHook.getCallsiteHook();
+ if (hook.isActive()) {
+ throw RaiseException.createNativeRaiseException(
+ recv.getRuntime(),
+ new RuntimeException("Cannot reset the callsite info in the middle of a traced run."));
+ }
+ return hook.resetDefsites();
+ }
+
+ @JRubyMethod(name="reset_coverage", meta = true)
+ public static IRubyObject resetCoverage(IRubyObject recv) {
+ CoverageHook hook = CoverageHook.getCoverageHook();
+ if (hook.isActive()) {
+ throw RaiseException.createNativeRaiseException(
+ recv.getRuntime(),
+ new RuntimeException("Cannot reset the coverage info in the middle of a traced run."));
+ }
+ return hook.resetCoverage(recv.getRuntime());
+ }
+
+ @JRubyMethod(name="remove_coverage_hook", meta = true)
+ public static IRubyObject removeCoverageHook(IRubyObject recv) {
+ return removeRcovHook(recv, CoverageHook.getCoverageHook());
+ }
+
+ @JRubyMethod(name="install_coverage_hook", meta = true)
+ public static IRubyObject installCoverageHook(IRubyObject recv) {
+ return installRcovHook(recv, CoverageHook.getCoverageHook());
+ }
+
+ /**
+ TODO: I think this is broken. I'm not sure why, but recreating
+ cover all the time seems bad.
+ */
+ @JRubyMethod(name="generate_coverage_info", meta = true)
+ public static IRubyObject generateCoverageInfo(IRubyObject recv) {
+ Ruby run = recv.getRuntime();
+ RubyHash cover = (RubyHash)CoverageHook.getCoverageHook().getCover(run);
+ RubyHash xcover = RubyHash.newHash(run);
+ RubyArray keys = cover.keys();
+ RubyArray temp;
+ ThreadContext ctx = run.getCurrentContext();
+ for (int i=0; i < keys.length().getLongValue(); i++) {
+ IRubyObject key = keys.aref(JavaUtil.convertJavaToRuby(run, Long.valueOf(i)));
+ temp = ((RubyArray)cover.op_aref(ctx, key)).aryDup();
+ xcover.op_aset(ctx,key, temp);
+ }
+ RubyModule rcov__ = (RubyModule) recv.getRuntime().getModule("Rcov").getConstant("RCOV__");
+
+ if (rcov__.const_defined_p(ctx, RubySymbol.newSymbol(recv.getRuntime(), "COVER")).isTrue()) {
+ rcov__.remove_const(ctx, recv.getRuntime().newString("COVER"));
+ }
+ rcov__.defineConstant( "COVER", xcover );
+
+ return xcover;
+ }
+
+ @JRubyMethod(name="remove_callsite_hook", meta = true)
+ public static IRubyObject removeCallsiteHook(IRubyObject recv) {
+ return removeRcovHook( recv, CallsiteHook.getCallsiteHook() );
+ }
+
+ @JRubyMethod(name="install_callsite_hook", meta = true)
+ public static IRubyObject installCallsiteHook(IRubyObject recv) {
+ return installRcovHook( recv, CallsiteHook.getCallsiteHook() );
+ }
+
+ @JRubyMethod(name="generate_callsite_info", meta = true)
+ public static IRubyObject generateCallsiteInfo(IRubyObject recv) {
+ return CallsiteHook.getCallsiteHook().getCallsiteInfo( recv.getRuntime() ).dup();
+ }
+
+ @JRubyMethod(name="ABI", meta = true)
+ public static IRubyObject getAbi( IRubyObject recv ) {
+ RubyArray ary = recv.getRuntime().newArray();
+ ary.add( RubyFixnum.int2fix( recv.getRuntime(), 2L ) );
+ ary.add( RubyFixnum.int2fix( recv.getRuntime(), 0L ) );
+ ary.add( RubyFixnum.int2fix( recv.getRuntime(), 0L ) );
+ return ary;
+ }
+
+ private static IRubyObject removeRcovHook( IRubyObject recv, RcovHook hook ) {
+ hook.setActive( false );
+ recv.getRuntime().removeEventHook( hook );
+ return recv.getRuntime().getFalse();
+ }
+
+ private static IRubyObject installRcovHook( IRubyObject recv, RcovHook hook ) {
+ if ( !hook.isActive() ) {
+ hook.setActive( true );
+ recv.getRuntime().addEventHook( hook );
+ return recv.getRuntime().getTrue();
+ } else {
+ return recv.getRuntime().getFalse();
+ }
+ }
+
+}
24 ext/rcovrt/extconf.rb
View
@@ -1,11 +1,13 @@
-require 'mkmf'
-
-dir_config("gcov")
-if ENV["USE_GCOV"] and Config::CONFIG['CC'] =~ /gcc/ and
- have_library("gcov", "__gcov_open")
-
- $CFLAGS << " -fprofile-arcs -ftest-coverage"
- create_makefile("rcovrt")
-else
- create_makefile("rcovrt")
-end
+unless RUBY_PLATFORM == 'java' then
+ require 'mkmf'
+
+ dir_config("gcov")
+ if ENV["USE_GCOV"] and Config::CONFIG['CC'] =~ /gcc/ and
+ have_library("gcov", "__gcov_open")
+
+ $CFLAGS << " -fprofile-arcs -ftest-coverage"
+ create_makefile("rcovrt")
+ else
+ create_makefile("rcovrt")
+ end
+end
BIN  lib/rcovrt.jar
View
Binary file not shown
35 rcov-jruby.gemspec
View
@@ -0,0 +1,35 @@
+Gem::Specification.new do |s|
+ s.name = %q{rcov}
+ s.version = "0.8.1.3.0"
+
+ s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
+ s.authors = ["Mauricio Fernandez"]
+ s.cert_chain = nil
+ s.date = %q{2007-11-21}
+ s.default_executable = %q{rcov}
+ s.description = %q{rcov is a code coverage tool for Ruby. It is commonly used for viewing overall test unit coverage of target code. It features fast execution (20-300 times faster than previous tools), multiple analysis modes, XHTML and several kinds of text reports, easy automation with Rake via a RcovTask, fairly accurate coverage information through code linkage inference using simple heuristics, colorblind-friendliness...}
+ s.email = %q{mfp@acm.org}
+ s.executables = ["rcov"]
+ s.extensions = []
+ s.extra_rdoc_files = ["README.API", "README.rake", "README.rant", "README.vim"]
+ s.files = ["bin/rcov", "lib/rcov.rb", "lib/rcov/lowlevel.rb", "lib/rcov/xx.rb", "lib/rcov/version.rb", "lib/rcov/rant.rb", "lib/rcov/report.rb", "lib/rcov/rcovtask.rb", "lib/rcovrt.jar", "LEGAL", "LICENSE", "Rakefile", "Rantfile", "README.rake", "README.rant", "README.emacs", "README.en", "README.vim", "README.API", "THANKS", "test/functional_test.rb", "test/file_statistics_test.rb", "test/assets/sample_03.rb", "test/assets/sample_05-new.rb", "test/code_coverage_analyzer_test.rb", "test/assets/sample_04.rb", "test/assets/sample_02.rb", "test/assets/sample_05-old.rb", "test/assets/sample_01.rb", "test/turn_off_rcovrt.rb", "test/call_site_analyzer_test.rb", "test/assets/sample_05.rb", "rcov.vim", "rcov.el", "setup.rb", "BLURB", "CHANGES"]
+ s.has_rdoc = true
+ s.homepage = %q{http://eigenclass.org/hiki.rb?rcov}
+ s.platform = 'jruby'
+ s.rdoc_options = ["--main", "README.API", "--title", "rcov code coverage tool"]
+ s.require_paths = ["lib"]
+ s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
+ s.rubygems_version = %q{1.2.0}
+ s.summary = %q{Code coverage analysis tool for Ruby/JRuby}
+ s.test_files = ["test/functional_test.rb", "test/file_statistics_test.rb", "test/code_coverage_analyzer_test.rb", "test/call_site_analyzer_test.rb"]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 1
+
+ if current_version >= 3 then
+ else
+ end
+ else
+ end
+end
2  setup.rb
View
@@ -1255,7 +1255,7 @@ def setup_dir_bin(rel)
alias setup_dir_lib noop
def setup_dir_ext(rel)
- make if extdir?(curr_srcdir())
+ make if extdir?(curr_srcdir()) and File.exist?("#{curr_srcdir()}/Makefile")
end
alias setup_dir_data noop
21 test/call_site_analyzer_test.rb
View
@@ -15,14 +15,28 @@ def verify_callsites_equal(expected, actual)
unless $".any?{|x| %r{\brcovrt\b} =~ x}
backtrace = backtrace.map{|_, mid, file, line| [nil, mid, file, line] }
end
+ backtrace[0][2] = File.expand_path(backtrace[0][2])
s[Rcov::CallSiteAnalyzer::CallSite.new(backtrace)] = count
s
end
- assert_equal(callsites, actual)
+
+ act_callsites = actual.inject({}) do |s, (key, value)|
+ #wow thats obtuse. In a callsite we have an array of arrays. We have to deep copy them because
+ # if we muck with the actual backtrace it messes things up for accumulation type tests.
+ # we have to muck with backtrace so that we can normalize file names (it's an issue between MRI and JRuby)
+ backtrace = key.backtrace.inject([]) {|y, val| y << val.inject([]) {|z, v2| z<< v2}}
+ backtrace[0][2] = File.expand_path(key.backtrace[0][2])
+ s[Rcov::CallSiteAnalyzer::CallSite.new(backtrace)] = value
+ s
+ end
+ assert_equal(callsites.to_s, act_callsites.to_s)
end
def verify_defsite_equal(expected, actual)
- assert_equal(Rcov::CallSiteAnalyzer::DefSite.new(*expected), actual)
+ defsite = Rcov::CallSiteAnalyzer::DefSite.new(*expected)
+ defsite.file = File.expand_path defsite.file
+ actual.file = File.expand_path actual.file
+ assert_equal(defsite.to_s, actual.to_s)
end
def test_callsite_compute_raw_difference
@@ -92,7 +106,8 @@ def test_basic_callsite_recording_API
@a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
callsites = @a.callsites("Rcov::Test::Temporary::Sample03", "f2")
callsite = callsites.keys[0]
- assert_equal("./test/assets/sample_03.rb", callsite.file)
+ #expand path is used here to compensate for differences between JRuby and MRI
+ assert_equal(File.expand_path("./test/assets/sample_03.rb"), File.expand_path(callsite.file))
assert_equal(4, callsite.line)
assert_equal(:f1, callsite.calling_method)
end
11 test/code_coverage_analyzer_test.rb
View
@@ -47,7 +47,9 @@ def test_raw_coverage_info
line_info, cov_info, count_info = analyzer.data(sample_file)
assert_equal(lines, line_info)
assert_equal([true, true, false, false, true, false, true], cov_info)
- assert_equal([1, 2, 0, 0, 1, 0, 11], count_info)
+ assert_equal([1, 2, 0, 0, 1, 0, 11], count_info) unless PLATFORM =~ /java/
+ # JRUBY reports an if x==blah as hitting this type of line once, JRUBY also optimizes this stuff so you'd have to run with --debug to get "extra" information. MRI hits it twice.
+ assert_equal([1, 1, 0, 0, 1, 0, 11], count_info) if PLATFORM =~ /java/
analyzer.reset
assert_equal(nil, analyzer.data(sample_file))
assert_equal([], analyzer.analyzed_files)
@@ -86,9 +88,12 @@ def test_differential_coverage_data
analyzer = Rcov::CodeCoverageAnalyzer.new
analyzer.run_hooked{ load sample_file }
line_info, cov_info, count_info = analyzer.data(sample_file)
- assert_equal([1, 2, 0, 0, 1, 0, 11], count_info)
+ assert_equal([1, 2, 0, 0, 1, 0, 11], count_info) unless PLATFORM =~ /java/
+ # JRUBY reports an if x==blah as hitting this type of line once, JRUBY also optimizes this stuff so you'd have to run with --debug to get "extra" information. MRI hits it twice.
+ assert_equal([1, 1, 0, 0, 1, 0, 11], count_info) if PLATFORM =~ /java/
analyzer.reset
+ #set_trace_func proc { |event, file, line, id, binding, classname| printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname if (file =~ /sample_02.rb/) }
sample_file = File.join(File.dirname(__FILE__), "assets/sample_02.rb")
analyzer.run_hooked{ load sample_file }
@@ -160,7 +165,7 @@ def test_reset
sample_file = File.join(File.dirname(__FILE__), "assets/sample_02.rb")
load sample_file
-
+
a1.run_hooked do
100.times do |i|
Rcov::Test::Temporary::Sample02.foo(1, 1)
Please sign in to comment.
Something went wrong with that request. Please try again.