morph 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.2.6. handle more types of value types in from_hash()
2
+
1
3
  v0.2.5. camelize names for classes in from_hash()
2
4
 
3
5
  v0.2.4. from_hash() creates classes in Morph namespace and handles arrays of hashes
data/lib/morph.rb CHANGED
@@ -1,66 +1,112 @@
1
1
  require 'activesupport'
2
2
 
3
3
  module Morph
4
- VERSION = "0.2.5"
5
-
6
- def self.from_hash hash, namespace=Morph
7
- if hash.keys.size == 1
8
- key = hash.keys.first
9
- object = object_from_key key, namespace
10
- if hash[key].is_a? Hash
11
- attributes = hash[key]
12
- add_to_object object, attributes, namespace
13
- end
14
- object
15
- else
16
- raise 'hash must have single key'
4
+ VERSION = "0.2.6"
5
+
6
+ class << self
7
+ def generate_migrations object, options={}
8
+ options[:ignore] ||= []
9
+ options[:belongs_to_id] ||= ''
10
+ migrations = []
11
+ name = object.class.name.demodulize.underscore
12
+ add_migration name, object.morph_attributes, migrations, options
17
13
  end
18
- end
19
-
20
- def self.included(base)
21
- base.extend ClassMethods
22
- base.send(:include, InstanceMethods)
23
- base.send(:include, MethodMissing)
24
- end
25
14
 
26
- private
27
- def self.object_from_key key, namespace
28
- begin
29
- name = key.to_s.camelize
30
- type = "#{namespace.name}::#{name}".constantize
31
- rescue NameError => e
32
- namespace.const_set name, Class.new
33
- type = "#{namespace.name}::#{name}".constantize
34
- type.send(:include, Morph)
15
+ def from_hash hash, namespace=Morph
16
+ if hash.keys.size == 1
17
+ key = hash.keys.first
18
+ object = object_from_name key, namespace
19
+ if hash[key].is_a? Hash
20
+ attributes = hash[key]
21
+ add_to_object object, attributes, namespace
22
+ end
23
+ object
24
+ else
25
+ raise 'hash must have single key'
35
26
  end
36
- object = type.new
37
27
  end
38
28
 
39
- def self.add_to_object object, attributes, namespace
40
- attributes.each do |key, value|
41
- attribute = key.gsub(':',' ')
42
- attribute = attribute.underscore
43
-
44
- if value.is_a?(String)
45
- object.morph(attribute, value)
46
- elsif value.is_a?(Array)
47
- array = value
48
- if array.size > 0 && array.collect(&:class).uniq == [Hash]
49
- array = array.collect do |hash|
50
- child = object_from_key key.singularize, namespace
51
- add_to_object child, hash, namespace
52
- child
53
- end
29
+ def included(base)
30
+ base.extend ClassMethods
31
+ base.send(:include, InstanceMethods)
32
+ base.send(:include, MethodMissing)
33
+ end
34
+
35
+ private
36
+ def add_migration name, attributes, migrations, options
37
+ migration = "./script/generate model #{name}#{options[:belongs_to_id]}"
38
+ options[:belongs_to_id] = ''
39
+ migrations << migration
40
+ attributes.to_a.sort{|a,b| a[0].to_s <=> b[0].to_s}.each do |attribute, value|
41
+ case value
42
+ when String
43
+ attribute_name = attribute.to_s
44
+ unless options[:ignore].include?(attribute_name)
45
+ type = attribute_name.ends_with?('date') ? 'date' : 'string'
46
+ attribute_def = "#{attribute}:#{type}"
47
+ migration.sub!(migration, "#{migration} #{attribute_def}")
48
+ end
49
+ when Array
50
+ options[:belongs_to_id] = " #{name}_id:integer"
51
+ migrations = add_migration(attribute, '', migrations, options)
52
+ when Hash
53
+ options[:belongs_to_id] = " #{name}_id:integer"
54
+ migrations = add_migration(attribute, value, migrations, options)
55
+ else
56
+ puts 'hi'
54
57
  end
58
+ end
59
+ migrations
60
+ end
61
+
62
+ def class_constant namespace, name
63
+ "#{namespace.name}::#{name}".constantize
64
+ end
55
65
 
56
- object.morph(attribute.pluralize, array)
57
- elsif value.is_a? Hash
58
- child_object = object_from_key key, namespace
59
- add_to_object child_object, value, namespace
60
- object.morph(attribute, child_object)
66
+ def object_from_name name, namespace
67
+ name = name.to_s.camelize
68
+ begin
69
+ type = class_constant namespace, name
70
+ rescue NameError => e
71
+ namespace.const_set name, Class.new
72
+ type = class_constant namespace, name
73
+ type.send(:include, Morph)
61
74
  end
75
+ type.new
62
76
  end
63
- end
77
+
78
+ def object_from_hash hash, name, namespace
79
+ object = object_from_name(name, namespace)
80
+ add_to_object(object, hash, namespace)
81
+ end
82
+
83
+ def objects_from_array array, name, namespace
84
+ if array.size > 0 && array.collect(&:class).uniq == [Hash]
85
+ array.map! { |hash| object_from_hash(hash, name.singularize, namespace) }
86
+ else
87
+ array
88
+ end
89
+ end
90
+
91
+ def add_to_object object, attributes, namespace
92
+ attributes.each do |name, value|
93
+ attribute = name.gsub(':',' ').underscore
94
+ case value
95
+ when String, Date
96
+ object.morph(attribute, value)
97
+ when Array
98
+ object.morph(attribute.pluralize, objects_from_array(value, name, namespace))
99
+ when Hash
100
+ object.morph(attribute, object_from_hash(value, name, namespace))
101
+ when NilClass
102
+ object.morph(attribute, nil)
103
+ else
104
+ raise "cannot handle adding #{name} value of class: #{value.class.name}"
105
+ end
106
+ end
107
+ object
108
+ end
109
+ end
64
110
 
65
111
  public
66
112
 
data/morph.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{morph}
5
- s.version = "0.2.5"
5
+ s.version = "0.2.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Rob McKinnon"]
9
- s.date = %q{2009-03-16}
9
+ s.date = %q{2009-03-30}
10
10
  s.description = %q{Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.}
11
11
  s.email = ["rob ~@nospam@~ rubyforge.org"]
12
12
  s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README"]
@@ -352,6 +352,29 @@ describe Morph do
352
352
  end
353
353
 
354
354
  describe 'creating from hash' do
355
+ it 'should create classes and object instances with array of hashes' do
356
+ h = {
357
+ "CompanyDetails"=> {
358
+ "SearchItems"=> [
359
+ { "CompanyDate"=> '',
360
+ "CompanyIndexStatus"=> '',
361
+ "DataSet"=>"LIVE",
362
+ "CompanyName"=>"CANONGROVE LIMITED",
363
+ "CompanyNumber"=>"SC244777" },
364
+ { "CompanyDate"=>"",
365
+ "CompanyIndexStatus"=>"",
366
+ "DataSet"=>"LIVE",
367
+ "CompanyName"=>"CANONHALL ACCOUNTANCY LTD",
368
+ "CompanyNumber"=>"05110715" }
369
+ ]
370
+ }
371
+ }
372
+ company_details = Morph.from_hash(h)
373
+ company_details.search_items.first.class.name.should == 'Morph::SearchItem'
374
+ company_details.search_items.first.data_set.should == 'LIVE'
375
+ company_details.search_items.first.company_name.should == 'CANONGROVE LIMITED'
376
+ end
377
+
355
378
  it 'should create classes and object instances' do
356
379
  h = {
357
380
  "CompanyDetails"=> {
@@ -390,19 +413,7 @@ describe Morph do
390
413
  "AccountRefDate"=>"0000-30-04"},
391
414
  "IncorporationDate"=>"1996-03-25",
392
415
  "CompanyNumber"=>"03176906",
393
- "xmlns"=>"http://xmlgw.companieshouse.gov.uk/v1-0",
394
- "SearchItems"=> [
395
- { "CompanyDate"=> '',
396
- "CompanyIndexStatus"=> '',
397
- "DataSet"=>"LIVE",
398
- "CompanyName"=>"CANONGROVE LIMITED",
399
- "CompanyNumber"=>"SC244777" },
400
- { "CompanyDate"=>"",
401
- "CompanyIndexStatus"=>"",
402
- "DataSet"=>"LIVE",
403
- "CompanyName"=>"CANONHALL ACCOUNTANCY LTD",
404
- "CompanyNumber"=>"05110715" }
405
- ]
416
+ "xmlns"=>"http://xmlgw.companieshouse.gov.uk/v1-0"
406
417
  }
407
418
  }
408
419
  Object.const_set 'Company', Module.new
@@ -419,10 +430,56 @@ describe Morph do
419
430
  company_details.sic_codes.sic_text.should == 'stadiums'
420
431
  company_details.reg_address.address_lines.should == ["ST DAVID'S HOUSE", "WEST WING", "WOOD STREET", "CARDIFF CF10 1ES"]
421
432
 
422
- company_details.search_items.first.class.name.should == 'Company::House::SearchItem'
423
- company_details.search_items.first.data_set.should == 'LIVE'
424
- company_details.search_items.first.company_name.should == 'CANONGROVE LIMITED'
425
- # puts company_details.to_yaml
433
+ list = Morph.generate_migrations company_details, :ignore=>['xmlns','xmlns_xsi','xsi_schema_location']
434
+ list.size.should == 7
435
+ list[0].should == "./script/generate model company_details company_category:string company_name:string company_number:string company_status:string country_of_origin:string has_appointments:string has_branch_info:string in_liquidation:string incorporation_date:date last_full_mem_date:date"
436
+ list[1].should == './script/generate model accounts company_details_id:integer account_category:string account_ref_date:date document_available:string last_made_up_date:date next_due_date:date overdue:string'
437
+ list[2].should == './script/generate model mortgages company_details_id:integer mortgage_ind:string num_mort_charges:string num_mort_outstanding:string num_mort_part_satisfied:string num_mort_satisfied:string'
438
+ list[3].should == './script/generate model reg_address company_details_id:integer'
439
+ list[4].should == './script/generate model address_lines reg_address_id:integer'
440
+ list[5].should == './script/generate model returns company_details_id:integer document_available:string last_made_up_date:date next_due_date:date overdue:string'
441
+ list[6].should == './script/generate model sic_codes company_details_id:integer sic_text:string'
442
+
443
+ yaml = %Q|--- !ruby/object:Company::House::CompanyDetails
444
+ accounts: !ruby/object:Company::House::Accounts
445
+ account_category: FULL
446
+ account_ref_date: "0000-30-04"
447
+ document_available: "1"
448
+ last_made_up_date: "2001-04-30"
449
+ next_due_date: "2002-11-30"
450
+ overdue: "NO"
451
+ company_category: Public Limited Company
452
+ company_name: MILLENNIUM STADIUM PLC
453
+ company_number: 03176906
454
+ company_status: Active
455
+ country_of_origin: United Kingdom
456
+ has_appointments: "1"
457
+ has_branch_info: "0"
458
+ in_liquidation: "0"
459
+ incorporation_date: "1996-03-25"
460
+ last_full_mem_date: "2002-03-25"
461
+ mortgages: !ruby/object:Company::House::Mortgages
462
+ mortgage_ind: LT300
463
+ num_mort_charges: "7"
464
+ num_mort_outstanding: "7"
465
+ num_mort_part_satisfied: "0"
466
+ num_mort_satisfied: "0"
467
+ reg_address: !ruby/object:Company::House::RegAddress
468
+ address_lines:
469
+ - ST DAVID'S HOUSE
470
+ - WEST WING
471
+ - WOOD STREET
472
+ - CARDIFF CF10 1ES
473
+ returns: !ruby/object:Company::House::Returns
474
+ document_available: "1"
475
+ last_made_up_date: "2002-03-25"
476
+ next_due_date: "2003-04-22"
477
+ overdue: "NO"
478
+ sic_codes: !ruby/object:Company::House::SICCodes
479
+ sic_text: stadiums
480
+ xmlns: http://xmlgw.companieshouse.gov.uk/v1-0
481
+ xmlns_xsi: http://www.w3.org/2001/XMLSchema-instance
482
+ xsi_schema_location: xmlgwdev.companieshouse.gov.uk/v1-0/schema/CompanyDetails.xsd|
426
483
  end
427
484
  end
428
485
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob McKinnon
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-16 00:00:00 +00:00
12
+ date: 2009-03-30 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency