1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
require_relative "spec_helper"
describe "unused_associations plugin" do
require 'rbconfig'
require 'json'
ua_file = "spec/tua-#{$$}.json"
uac_file = "spec/tua-coverage-#{$$}.json"
after do
File.delete(ua_file) if File.file?(ua_file)
File.delete(uac_file) if File.file?(uac_file)
end
def check(code, env={})
ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['RUBY_INSTALL_NAME'])
runner = File.expand_path('../files/unused_associations/run_tua.rb', File.dirname(__FILE__))
input_read, input_write = IO.pipe
output_read, output_write = IO.pipe
Process.spawn(env, ruby, runner, :in=>input_read, :out=>output_write)
input_write.write(code)
input_write.close
output_write.close
result = output_read.read
input_read.close
output_read.close
res = Sequel.parse_json(result)
raise res if res.is_a?(String)
res
end
it "should correctly determine which associations are unused or partially used" do
ua, uao = check("TUA::O.a1")
ua.must_equal [["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}]]
ua, uao = check(<<-RUBY)
obj = TUA::O
obj.a1
obj.a1_dataset
obj.a1 = nil
obj.a2s_dataset
obj.remove_all_a2s
obj.a3 = nil
obj.add_a4(obj)
obj.remove_a6(obj)
obj = TUA::SC::O
obj.a7
obj.a7_dataset
RUBY
ua.must_equal [["TUA", "a5"]]
uao.must_equal [
["TUA", "a2s", {"no_association_method"=>true, "adder"=>nil, "remover"=>nil}],
["TUA", "a3", {"no_dataset_method"=>true, "no_association_method"=>true}],
["TUA", "a4s", {"no_dataset_method"=>true, "no_association_method"=>true, "remover"=>nil, "clearer"=>nil}],
["TUA", "a6s", {"no_association_method"=>true, "adder"=>nil, "clearer"=>nil}],
["TUA::SC", "a7", {"read_only"=>true}]]
end
it "should use association reflection access to determine which associations are used" do
ua, uao = check("TUA.association_reflection(:a1); TUA::O.a2s")
ua.must_equal [["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [
["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true, "no_association_method"=>true}],
["TUA", "a2s", {"read_only"=>true, "no_dataset_method"=>true}]]
end
it "should work with :file and :coverage_file plugin options" do
ua, uao = check("TUA::O.a1", 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file))
ua.must_equal [["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}]]
Sequel.parse_json(File.binread(ua_file)).must_be_kind_of(Hash)
File.file?(uac_file).must_equal false
end
it "should work without arguments when using :file and :coverage_file plugin options" do
ua, uao = check("TUA::O.a1", 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file), 'NO_COVERAGE_RESULT'=>'1', 'NO_COVERAGE_DATA'=>'1', 'NO_DATA'=>'1')
ua.must_equal [["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}]]
Sequel.parse_json(File.binread(ua_file)).must_be_kind_of(Hash)
File.file?(uac_file).must_equal false
end
it "should be able to combine information from multiple coverage runs" do
ua, uao = check("TUA::O.a1", 'KEEP_COVERAGE'=>'1', 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file))
ua.must_equal [["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}]]
Sequel.parse_json(File.binread(ua_file)).must_be_kind_of(Hash)
Sequel.parse_json(File.binread(uac_file)).must_be_kind_of(Hash)
ua, uao = check("TUA::O.a2s", 'KEEP_COVERAGE'=>'1', 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file))
ua.must_equal [["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [
["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}],
["TUA", "a2s", {"read_only"=>true, "no_dataset_method"=>true}]]
end
it "should respect association_reflection information from multiple coverage runs" do
check("", 'KEEP_COVERAGE'=>'1', 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file))
ua, uao = check("TUA.association_reflection(:a1); TUA::O.a2s", 'KEEP_COVERAGE'=>'1', 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file))
ua.must_equal [["TUA", "a3"], ["TUA", "a4s"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [
["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true, "no_association_method"=>true}],
["TUA", "a2s", {"read_only"=>true, "no_dataset_method"=>true}]]
end
it "should not define unused associations when using :modify_associations and :file plugin options" do
check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:file=>ua_file), 'NO_DATA'=>'1')
obj = TUA::O
obj.a1
obj.a1_dataset
obj.a1 = nil
obj.a2s_dataset
obj.remove_all_a2s
obj.a3 = nil
obj.add_a4(obj)
obj.remove_a6(obj)
RUBY
assocs, meths = check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:modify_associations=>true, :file=>ua_file), 'NO_COVERAGE_RESULT'=>'1')
print Sequel.object_to_json([TUA.associations.sort, TUA.instance_methods])
exit
RUBY
assocs.must_equal %w'a1 a2s a3 a4s a6s'
%w'a1 a1_dataset a1= a2s_dataset remove_all_a2s a3= add_a4 a6s_dataset remove_a6'.each do |meth|
meths.must_include meth
end
%w'a2s add_a2 remove_a2 a3 a3_dataset a4s a4s_dataset remove_a4 remove_all_a4s a5 a5_dataset a5= a6s add_a6 remove_all_a6s'.each do |meth|
meths.wont_include meth
end
end
it "should not define unused associations when using :modify_associations and :unused_associations_data options" do
check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:coverage_file=>uac_file, :file=>ua_file), 'NO_COVERAGE_DATA'=>'1')
obj = TUA::O
obj.a1
obj.a1_dataset
obj.a1 = nil
obj.a2s_dataset
obj.remove_all_a2s
obj.a3 = nil
obj.add_a4(obj)
obj.remove_a6(obj)
RUBY
assocs, meths = check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:modify_associations=>true, :unused_associations_data=>Sequel.parse_json(File.binread(ua_file))))
print Sequel.object_to_json([TUA.associations.sort, TUA.instance_methods])
exit
RUBY
assocs.must_equal %w'a1 a2s a3 a4s a6s'
%w'a1 a1_dataset a1= a2s_dataset remove_all_a2s a3= add_a4 a6s_dataset remove_a6'.each do |meth|
meths.must_include meth
end
%w'a2s add_a2 remove_a2 a3 a3_dataset a4s a4s_dataset remove_a4 remove_all_a4s a5 a5_dataset a5= a6s add_a6 remove_all_a6s'.each do |meth|
meths.wont_include meth
end
end
it "should respect :is_used association option when modifying associations" do
check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:file=>ua_file), 'NO_DATA'=>'1')
obj = TUA::O
obj.a1
obj.a1_dataset
obj.a1 = nil
obj.a2s_dataset
obj.remove_all_a2s
obj.a3 = nil
obj.add_a4(obj)
obj.remove_a6(obj)
RUBY
assocs, meths = check(<<-RUBY, 'PLUGIN_OPTS'=>Sequel.object_to_json(:modify_associations=>true, :file=>ua_file), 'NO_COVERAGE_RESULT'=>'1', 'A5_IS_USED'=>'1', 'A6S_IS_USED'=>'1')
print Sequel.object_to_json([TUA.associations.sort, TUA.instance_methods])
exit
RUBY
assocs.must_equal %w'a1 a2s a3 a4s a5 a6s'
%w'a1 a1_dataset a1= a2s_dataset remove_all_a2s a3= add_a4 a5 a5_dataset a5= a6s a6s_dataset add_a6 remove_a6 remove_all_a6s'.each do |meth|
meths.must_include meth
end
%w'a2s add_a2 remove_a2 a3 a3_dataset a4s a4s_dataset remove_a4 remove_all_a4s'.each do |meth|
meths.wont_include meth
end
end
it "should skip associations that use :methods_module" do
ua, uao = check("TUA::O.a1", 'A4S_METHODS_MODULE'=>'1')
ua.must_equal [["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a1", {"read_only"=>true, "no_dataset_method"=>true}]]
end
it "should ignore association modification methods for read_only associations" do
ua, uao = check("TUA::O.a4s", 'A4S_READ_ONLY'=>'1')
ua.must_equal [["TUA", "a1"], ["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal [["TUA", "a4s", {"no_dataset_method"=>true}]]
end
it "should ignore missing association modification methods" do
ua, uao = check("nil", 'A4S_NO_METHODS'=>'1')
ua.must_equal [["TUA", "a1"], ["TUA", "a2s"], ["TUA", "a3"], ["TUA", "a5"], ["TUA", "a6s"], ["TUA::SC", "a7"]]
uao.must_equal []
end
end if RUBY_VERSION >= '2.5' && RUBY_ENGINE == 'ruby'
|