lib/surrogate/api_comparer.rb in surrogate-0.6.1 vs lib/surrogate/api_comparer.rb in surrogate-0.6.2

- old
+ new

@@ -6,11 +6,15 @@ # compares a surrogate to an object class ApiComparer attr_accessor :surrogate, :actual - def initialize(surrogate, actual) + def initialize(actual, surrogate) + unless surrogate.instance_variable_get(:@hatchery).kind_of?(Hatchery) && surrogate.instance_variable_get(:@hatchling).kind_of?(Hatchling) + Kernel.warn "You said #{actual} should substitute for #{surrogate}`, but as of 0.6.2, this should be asserted in the other direction." + surrogate, actual = actual, surrogate + end self.surrogate, self.actual = surrogate, actual end def surrogate_methods @surrogate_methods ||= SurrogateClassReflector.new(surrogate).methods @@ -24,15 +28,17 @@ @compare ||= { instance: { not_on_surrogate: instance_not_on_surrogate, not_on_actual: instance_not_on_actual, types: instance_types, + names: instance_names, }, class: { not_on_surrogate: class_not_on_surrogate, not_on_actual: class_not_on_actual, types: class_types, + names: class_names, }, } end def instance_not_on_surrogate @@ -51,36 +57,67 @@ def class_not_on_actual surrogate_methods[:class][:api] - actual_methods[:class][:inherited] - actual_methods[:class][:other] end + + # there is a lot of duplication in these next four methods -.- + # idk if there is something we can do about it. + # types are only shown for methods on both objects def class_types - surrogate_class_methods = surrogate_methods[:class][:api] + surrogate_methods[:class][:inherited] - actual_class_methods = actual_methods[:class][:inherited] + actual_methods[:class][:other] - class_methods_that_should_match = (surrogate_class_methods & actual_class_methods) - surrogate_methods[:class][:without_bodies] - actual_methods[:class][:without_bodies] class_methods_that_should_match.each_with_object Hash.new do |name, hash| surrogate_type, actual_type = class_types_for name next if surrogate_type == actual_type hash[name] = { surrogate: surrogate_type, actual: actual_type } end end # types are only shown for methods on both objects def instance_types - surrogate_instance_methods = surrogate_methods[:instance][:api] + surrogate_methods[:instance][:inherited] - actual_instance_methods = actual_methods[:instance][:inherited] + actual_methods[:instance][:other] - instance_methods_that_should_match = (surrogate_instance_methods & actual_instance_methods) - surrogate_methods[:instance][:without_bodies] - actual_methods[:instance][:without_bodies] instance_methods_that_should_match.each_with_object Hash.new do |name, hash| surrogate_type, actual_type = instance_types_for name next if surrogate_type == actual_type hash[name] = { surrogate: surrogate_type, actual: actual_type } end end + # names are only shown for methods on both objects + def class_names + class_methods_that_should_match.each_with_object Hash.new do |method_name, hash| + surrogate_name, actual_name = class_parameter_names_for method_name + next if surrogate_name == actual_name + hash[method_name] = { surrogate: surrogate_name, actual: actual_name } + end + end + + # names are only shown for methods on both objects + def instance_names + instance_methods_that_should_match.each_with_object Hash.new do |method_name, hash| + surrogate_name, actual_name = instance_parameter_names_for method_name + next if surrogate_name == actual_name + hash[method_name] = { surrogate: surrogate_name, actual: actual_name } + end + end + private + def instance_methods_that_should_match + surrogate_instance_methods = surrogate_methods[:instance][:api] + surrogate_methods[:instance][:inherited] + actual_instance_methods = actual_methods[:instance][:inherited] + actual_methods[:instance][:other] + instance_methods_that_should_match = (surrogate_instance_methods & actual_instance_methods) - surrogate_methods[:instance][:without_bodies] - actual_methods[:instance][:without_bodies] + end + + def class_methods_that_should_match + surrogate_class_methods = surrogate_methods[:class][:api] + surrogate_methods[:class][:inherited] + actual_class_methods = actual_methods[:class][:inherited] + actual_methods[:class][:other] + (surrogate_class_methods & actual_class_methods) - surrogate_methods[:class][:without_bodies] - actual_methods[:class][:without_bodies] + end + + # there is a lot of duplication in these next four methods -.- + # also, it seems like a lot of this shit could move into the reflectors + def class_types_for(name) surrogate_method = class_api_method_for name surrogate_method &&= to_lambda surrogate_method surrogate_method ||= surrogate.method name actual_method = actual.method name @@ -93,11 +130,31 @@ surrogate_method ||= surrogate.instance_method name actual_method = actual.instance_method name return type_for(surrogate_method), type_for(actual_method) end + def class_parameter_names_for(name) + surrogate_method = class_api_method_for name + surrogate_method &&= to_lambda surrogate_method + surrogate_method ||= surrogate.method name + actual_method = actual.method name + return parameter_names_for(surrogate_method), parameter_names_for(actual_method) + end + + def instance_parameter_names_for(name) + surrogate_method = instance_api_method_for name + surrogate_method &&= to_lambda surrogate_method + surrogate_method ||= surrogate.instance_method name + actual_method = actual.instance_method name + return parameter_names_for(surrogate_method), parameter_names_for(actual_method) + end + def type_for(method) method.parameters.map(&:first) + end + + def parameter_names_for(method) + method.parameters.map(&:last) end def to_lambda(proc) obj = Object.new obj.singleton_class.send :define_method, :abc123, &proc