Ruby
2.0.0p247(2013-06-27revision41674)
|
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. A coverage array gives, for each line, the 00079 * number of line execution by the interpreter. A +nil+ value means 00080 * coverage is disabled for this line (lines like +else+ and +end+). 00081 * 00082 * = Example 00083 * 00084 * [foo.rb] 00085 * s = 0 00086 * 10.times do |x| 00087 * s += x 00088 * end 00089 * 00090 * if s == 45 00091 * p :ok 00092 * else 00093 * p :ng 00094 * end 00095 * [EOF] 00096 * 00097 * require "coverage.so" 00098 * Coverage.start 00099 * require "foo.rb" 00100 * p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} 00101 */ 00102 void 00103 Init_coverage(void) 00104 { 00105 VALUE rb_mCoverage = rb_define_module("Coverage"); 00106 rb_define_module_function(rb_mCoverage, "start", rb_coverage_start, 0); 00107 rb_define_module_function(rb_mCoverage, "result", rb_coverage_result, 0); 00108 rb_gc_register_address(&rb_coverages); 00109 } 00110