From 4754ba60be3516252c43329cb41c1b1fd74263bc Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 19 Jun 2015 12:26:10 +0300 Subject: [PATCH] adds classes derived from array and hash These are used in parfait and were coming out wrong should be fixed, but hash tests weak --- lib/sof/array_node.rb | 1 - lib/sof/hash_node.rb | 1 - lib/sof/members.rb | 32 ++++++++++++++++++------- lib/sof/object_node.rb | 25 ++++++++++++++++++- lib/sof/writer.rb | 13 +++++++++- test/test_all.rb | 1 + test/test_super.rb | 54 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 test/test_super.rb diff --git a/lib/sof/array_node.rb b/lib/sof/array_node.rb index bfcb328..b015590 100644 --- a/lib/sof/array_node.rb +++ b/lib/sof/array_node.rb @@ -25,7 +25,6 @@ module Sof short end - private # This defines the short output which is basically what you would write in ruby # ie [ value1 , value2 , ...] # The short is used for 7 or less SimpleNodes diff --git a/lib/sof/hash_node.rb b/lib/sof/hash_node.rb index 6a01aee..7129cca 100644 --- a/lib/sof/hash_node.rb +++ b/lib/sof/hash_node.rb @@ -22,7 +22,6 @@ module Sof true end - private # This defines the short output which is basically what you would write in ruby # ie { key1 => value1 , ... } # The short is used for 7 or less SimpleNodes diff --git a/lib/sof/members.rb b/lib/sof/members.rb index cd8f711..cfbd310 100644 --- a/lib/sof/members.rb +++ b/lib/sof/members.rb @@ -50,16 +50,9 @@ module Sof case object.class.name when "Array" , "Parfait::List" - # and array values - object.each do |a| - add(a , level + 1) - end + add_array object , level when "Hash" , "Parfait::Dictionary" - # and hash keys/values - object.each do |a,b| - add(a , level + 1) - add(b , level + 1) - end + add_hash object , level else # and recursively add attributes attributes = attributes_for(object) @@ -67,6 +60,27 @@ module Sof val = get_value( object , a) add(val , level + 1) end + #TODO get all superclsses here, but this covers 99% so . . moving on + superclasses = [object.class.superclass.name] + if superclasses.include?( "Array") or superclasses.include?( "List") + add_array object , level + end + if superclasses.include?( "Hash") or superclasses.include?( "Dictionary") + add_hash object , level + end + end + end + # and hash keys/values + def add_hash hash ,level + hash.each do |a,b| + add(a , level + 1) + add(b , level + 1) + end + end + # and array values + def add_array array , level + array.each do |a| + add(a , level + 1) end end end diff --git a/lib/sof/object_node.rb b/lib/sof/object_node.rb index 3f711bf..4fc82b9 100644 --- a/lib/sof/object_node.rb +++ b/lib/sof/object_node.rb @@ -13,8 +13,13 @@ module Sof @name = name @simple = {} @complex = {} + @super = nil # if derived from array or hash end + # super is a hash or array, if the class of object derives from Hash/Array + def add_super s + @super = s + end # attributes hold key value pairs def add k , v raise "Key should be symbol not #{k}" unless k.is_a? Symbol @@ -25,8 +30,15 @@ module Sof end end + # simple when no complex attributes and any + # possible super is also simple def is_simple? - true if( @referenced.nil? and @complex.empty? and head.length < 30 ) + if( @referenced.nil? and @complex.empty? and head.length < 30 ) + unless(@super and !@super.is_simple?) + return true + end + end + false end # write out at the given level @@ -41,10 +53,21 @@ module Sof io.write " " v.out(io , level + 1) end + if(@super) + io.write " " + @super.long_out(io,level) + end end def short_out io , level io.write head + if(@super) + if( @super.is_simple? ) + @super.short_out(io,level) + else + @super.long_out(io,level) + end + end end def head diff --git a/lib/sof/writer.rb b/lib/sof/writer.rb index 2a113fc..ff6064a 100644 --- a/lib/sof/writer.rb +++ b/lib/sof/writer.rb @@ -45,7 +45,7 @@ module Sof raise "no object #{object}" unless occurence #puts "#{level} ? #{occurence.level} : ref #{occurence.referenced}" if( occurence.referenced ) - puts "ref #{occurence.referenced} level #{level} at #{occurence.level}" + #puts "ref #{occurence.referenced} level #{level} at #{occurence.level}" return SimpleNode.new("->#{occurence.referenced}") unless (level == occurence.level ) if( occurence.written.nil? ) occurence.written = true @@ -73,6 +73,9 @@ module Sof # simple nodes are returned for small objects # small means only simple attributes and only 30 chars of them # object nodes are basically arrays (see there) + # + # objects may be derived from array/hash. In that case the ObjectNode gets a super + # (either ArrayNode or HashNode) def object_to_sof_node( object , level , ref) node = ObjectNode.new(object.class.name , ref) attributes_for(object).each() do |a| @@ -80,6 +83,14 @@ module Sof next if val.nil? node.add( a , to_sof_node( val , level + 1) ) end + #TODO get all superclsses here, but this covers 99% so . . moving on + superclasses = [object.class.superclass.name] + if superclasses.include?( "Array") or superclasses.include?( "List") + node.add_super( array_to_sof_node(object , level , ref ) ) + end + if superclasses.include?( "Hash") or superclasses.include?( "Dictionary") + node.add_super( hash_to_sof_node(object , level , ref ) ) + end node end diff --git a/test/test_all.rb b/test/test_all.rb index d3ea870..9203c22 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -2,3 +2,4 @@ require_relative "test_basic" require_relative "test_object" require_relative "test_ext" require_relative "test_refs" +require_relative "test_super" diff --git a/test/test_super.rb b/test/test_super.rb new file mode 100644 index 0000000..da66789 --- /dev/null +++ b/test/test_super.rb @@ -0,0 +1,54 @@ +require_relative "helper" + +class ASuper < Array + def initialize object + @object = object + end + attr_accessor :object +end +class HSuper < Hash + def initialize object + @object = object + end + attr_accessor :object +end +class TestSuper < MiniTest::Test + include Checker + + def test_asuper_empty + @out = ASuper.new( [] ) + check "ASuper(:object => [])[]" + end + def test_asuper_with_array + @out = ASuper.new( [1,2,3] ) + check "ASuper(:object => [1, 2, 3])[]" + end + def test_asuper_as_array + @out = ASuper.new( nil ) + @out << 1 << 2 << 3 + check "ASuper()[1, 2, 3]" + end + def test_asuper_as_big_array + @out = ASuper.new( nil ) + @out << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 + check "ASuper() - 1\n- 2\n- 3\n- 4\n- 5\n- 6\n- 7\n- 8" + end + def test_asuper_self_ref + @out = ASuper.new( self ) + @out.object = @out + check "&1 ASuper(:object => ->1) " + end + def test_asuper_indirect_ref + object = ObjectWithAttributes.new + @out = ASuper.new( object ) + object.extra = @out + @out << 1 << 2 + check "&1 ASuper()\n :object ObjectWithAttributes(:name => 'some name', :number => 1234, :extra => ->1) - 1\n- 2" + end + + def test_hsuper_empty + @out = HSuper.new( {} ) + check "HSuper(:object => {}){}" + end + +end