Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /************************************************ 00002 00003 coverage.c - 00004 00005 $Author: $ 00006 00007 Copyright (c) 2008 Yusuke Endoh 00008 00009 ************************************************/ 00010 00011 #include "ruby.h" 00012 #include "vm_core.h" 00013 00014 static VALUE rb_coverages = Qundef; 00015 00016 /* 00017 * call-seq: 00018 * Coverage.start => nil 00019 * 00020 * Enables coverage measurement. 00021 */ 00022 static VALUE 00023 rb_coverage_start(VALUE klass) 00024 { 00025 if (!RTEST(rb_get_coverages())) { 00026 if (rb_coverages == Qundef) { 00027 rb_coverages = rb_hash_new(); 00028 RBASIC(rb_coverages)->klass = 0; 00029 } 00030 rb_set_coverages(rb_coverages); 00031 } 00032 return Qnil; 00033 } 00034 00035 static int 00036 coverage_result_i(st_data_t key, st_data_t val, st_data_t h) 00037 { 00038 VALUE path = (VALUE)key; 00039 VALUE coverage = (VALUE)val; 00040 VALUE coverages = (VALUE)h; 00041 coverage = rb_ary_dup(coverage); 00042 rb_ary_clear((VALUE)val); 00043 rb_ary_freeze(coverage); 00044 rb_hash_aset(coverages, path, coverage); 00045 return ST_CONTINUE; 00046 } 00047 00048 /* 00049 * call-seq: 00050 * Coverage.result => hash 00051 * 00052 * Returns a hash that contains filename as key and coverage array as value 00053 * and disables coverage measurement. 00054 */ 00055 static VALUE 00056 rb_coverage_result(VALUE klass) 00057 { 00058 VALUE coverages = rb_get_coverages(); 00059 VALUE ncoverages = rb_hash_new(); 00060 if (!RTEST(coverages)) { 00061 rb_raise(rb_eRuntimeError, "coverage measurement is not enabled"); 00062 } 00063 st_foreach(RHASH_TBL(coverages), coverage_result_i, ncoverages); 00064 rb_hash_freeze(ncoverages); 00065 rb_reset_coverages(); 00066 return ncoverages; 00067 } 00068 00069 /* Coverage provides coverage measurement feature for Ruby. 00070 * This feature is experimental, so these APIs may be changed in future. 00071 * 00072 * = Usage 00073 * 00074 * (1) require "coverage.so" 00075 * (2) do Coverage.start 00076 * (3) require or load Ruby source file 00077 * (4) Coverage.result will return a hash that contains filename as key and 00078 * coverage array as value. 00079 * 00080 * = Example 00081 * 00082 * [foo.rb] 00083 * s = 0 00084 * 10.times do |x| 00085 * s += x 00086 * end 00087 * 00088 * if s == 45 00089 * p :ok 00090 * else 00091 * p :ng 00092 * end 00093 * [EOF] 00094 * 00095 * require "coverage.so" 00096 * Coverage.start 00097 * require "foo.rb" 00098 * p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} 00099 */ 00100 void 00101 Init_coverage(void) 00102 { 00103 VALUE rb_mCoverage = rb_define_module("Coverage"); 00104 rb_define_module_function(rb_mCoverage, "start", rb_coverage_start, 0); 00105 rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, 0); 00106 rb_gc_register_address(&rb_coverages); 00107 } 00108