morph 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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