hydra_attribute 0.2.0 → 0.3.0.beta1

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.
Files changed (63) hide show
  1. data/README.md +74 -68
  2. data/cucumber.yml +1 -0
  3. data/features/attributes/create.feature +22 -0
  4. data/features/attributes/destroy.feature +18 -0
  5. data/features/attributes/update.feature +19 -0
  6. data/features/create.feature +47 -0
  7. data/features/define.feature +33 -0
  8. data/features/query_methods/group.feature +13 -14
  9. data/features/query_methods/order.feature +63 -52
  10. data/features/query_methods/select.feature +36 -37
  11. data/features/query_methods/where.feature +36 -38
  12. data/features/step_definitions/model_steps.rb +23 -19
  13. data/features/step_definitions/query_methods.rb +6 -2
  14. data/features/step_definitions/record_steps.rb +28 -10
  15. data/features/support/env.rb +12 -6
  16. data/features/support/schema.rb +62 -35
  17. data/features/support/world.rb +14 -5
  18. data/features/update.feature +114 -0
  19. data/gemfiles/3.1.gemfile.lock +10 -10
  20. data/gemfiles/3.2.gemfile.lock +10 -10
  21. data/lib/hydra_attribute/active_record/association.rb +77 -0
  22. data/lib/hydra_attribute/active_record/association_preloader.rb +82 -0
  23. data/lib/hydra_attribute/active_record/attribute_methods.rb +145 -37
  24. data/lib/hydra_attribute/active_record/migration.rb +21 -0
  25. data/lib/hydra_attribute/active_record/reflection.rb +16 -0
  26. data/lib/hydra_attribute/active_record/relation/query_methods.rb +73 -71
  27. data/lib/hydra_attribute/active_record/relation.rb +1 -24
  28. data/lib/hydra_attribute/active_record.rb +16 -2
  29. data/lib/hydra_attribute/association_builder.rb +44 -20
  30. data/lib/hydra_attribute/builder.rb +15 -13
  31. data/lib/hydra_attribute/configuration.rb +9 -30
  32. data/lib/hydra_attribute/entity_callbacks.rb +46 -0
  33. data/lib/hydra_attribute/hydra_attribute.rb +27 -0
  34. data/lib/hydra_attribute/migrator.rb +106 -0
  35. data/lib/hydra_attribute/railtie.rb +2 -0
  36. data/lib/hydra_attribute/version.rb +2 -2
  37. data/lib/hydra_attribute.rb +8 -6
  38. data/lib/rails/generators/hydra_attribute/install/templates/hydra_attribute.txt +4 -0
  39. data/spec/spec_helper.rb +1 -2
  40. metadata +42 -60
  41. data/features/attribute_methods.feature +0 -146
  42. data/features/define_attributes.feature +0 -56
  43. data/features/load_associations.feature +0 -40
  44. data/features/step_definitions/class_steps.rb +0 -32
  45. data/features/typecast_attributes.feature +0 -24
  46. data/lib/generators/hydra_attribute/install/templates/hydra_attribute.txt +0 -11
  47. data/lib/hydra_attribute/active_record/attribute_methods/before_type_cast.rb +0 -16
  48. data/lib/hydra_attribute/active_record/attribute_methods/read.rb +0 -13
  49. data/lib/hydra_attribute/attribute_builder.rb +0 -57
  50. data/lib/hydra_attribute/attribute_proxy.rb +0 -16
  51. data/lib/hydra_attribute/migration.rb +0 -27
  52. data/spec/hydra_attribute/active_record/relation/query_methods_spec.rb +0 -334
  53. data/spec/hydra_attribute/active_record/relation_spec.rb +0 -67
  54. data/spec/hydra_attribute/active_record/scoping_spec.rb +0 -23
  55. data/spec/hydra_attribute/active_record_spec.rb +0 -18
  56. data/spec/hydra_attribute/association_builder_spec.rb +0 -95
  57. data/spec/hydra_attribute/attribute_builder_spec.rb +0 -70
  58. data/spec/hydra_attribute/attribute_helpers_spec.rb +0 -70
  59. data/spec/hydra_attribute/builder_spec.rb +0 -39
  60. data/spec/hydra_attribute/configuration_spec.rb +0 -65
  61. data/spec/hydra_attribute_spec.rb +0 -20
  62. /data/lib/{generators → rails/generators}/hydra_attribute/install/USAGE +0 -0
  63. /data/lib/{generators → rails/generators}/hydra_attribute/install/install_generator.rb +0 -0
@@ -1,29 +1,28 @@
1
1
  Feature: hydra attribute where conditions
2
2
  When filter by hydra attribute and this value is not nil
3
- Then the correct hydra attribute table should be joined and filter by this value should be added
3
+ Then records with this attribute should be selected
4
4
 
5
5
  When filter by hydra attribute and this value is nil
6
- Then records with nil value should be selected or records which don't have this hydra attribute
6
+ Then records with nil and blank value should be selected
7
7
 
8
- Background: create models and describe hydra attributes
9
- Given create model class "Product"
10
- And create model class "SimpleProduct" as "Product" with hydra attributes:
11
- | type | name |
12
- | string | code |
13
- | string | summary |
14
- | string | title |
15
- | float | price |
16
- | boolean | active |
17
- | integer | state |
8
+ Background: create hydra attributes
9
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
10
+ | entity_type | name | backend_type |
11
+ | Product | code | string |
12
+ | Product | summary | string |
13
+ | Product | title | string |
14
+ | Product | price | float |
15
+ | Product | active | boolean |
16
+ | Product | state | integer |
18
17
 
19
- Scenario: add filter by one hydra attribute
20
- Given create models:
21
- | model | attributes |
22
- | SimpleProduct | code=[string:1] price=[float:2.75] |
23
- | SimpleProduct | code=[string:2] price=[float:2.75] |
24
- | SimpleProduct | code=[string:3] price=[float:2.76] |
25
- | SimpleProduct | code=[string:4] price=[nil:] |
26
- When filter "SimpleProduct" by:
18
+ Scenario: filter by one hydra attribute
19
+ Given create "Product" model with attributes as "hashes":
20
+ | code | price |
21
+ | [string:1] | [float:2.75] |
22
+ | [string:2] | [float:2.75] |
23
+ | [string:3] | [float:2.76] |
24
+ | [string:4] | [nil:] |
25
+ When filter "Product" by:
27
26
  | field | value |
28
27
  | price | [string:2.75] |
29
28
  Then total records should be "2"
@@ -32,13 +31,13 @@ Feature: hydra attribute where conditions
32
31
  | code | [string:1] |
33
32
  | code | [string:2] |
34
33
 
35
- Scenario: add nil filter by one hydra attribute
36
- Given create models:
37
- | model | attributes |
38
- | SimpleProduct | code=[string:1] price=[nil:] |
39
- | SimpleProduct | code=[string:2] price=[float:0] |
40
- | SimpleProduct | code=[string:3] |
41
- When filter "SimpleProduct" by:
34
+ Scenario: filter by one hydra attribute with nil value
35
+ Given create "Product" model with attributes as "hashes":
36
+ | code | price |
37
+ | [string:1] | [nil:] |
38
+ | [string:2] | [float:0] |
39
+ | [string:3] | |
40
+ When filter "Product" by:
42
41
  | field | value |
43
42
  | price | [nil:] |
44
43
  Then total records should be "2"
@@ -47,23 +46,22 @@ Feature: hydra attribute where conditions
47
46
  | code | [string:1] |
48
47
  | code | [string:3] |
49
48
 
50
- Scenario: add filter by several fields including both the hydra and general attributes
51
- Given create models:
52
- | model | attributes |
53
- | SimpleProduct | name=[string:toy] code=[string:1] title=[string:story] price=[float:2.45] active=[boolean:true] info=[string:] |
54
- | SimpleProduct | name=[string:toy] code=[string:2] title=[string:story] price=[float:2.45] active=[boolean:true] info=[string:a] summary=[nil:] |
55
- | SimpleProduct | name=[string:toy] code=[string:3] title=[string:story] price=[float:2.45] active=[boolean:true] state=[nil:] info=[string:a] summary=[nil:] |
56
- | SimpleProduct | name=[string:toy] code=[string:4] price=[float:2.45] active=[boolean:false] state=[nil:] info=[string:a] summary=[nil:] |
57
- | SimpleProduct | code=[string:5] price=[float:2.45] active=[boolean:true] state=[nil:] info=[string:a] summary=[nil:] |
58
- | SimpleProduct | name=[string:toy] code=[string:6] price=[float:2.46] active=[boolean:true] state=[nil:] info=[string:a] summary=[nil:] |
59
- When filter "SimpleProduct" by:
49
+ Scenario: filter by several fields including both the hydra and general attributes
50
+ Given create "Product" model with attributes as "hashes":
51
+ | name | code | title | price | active | state | summary |
52
+ | [string:toy] | [string:1] | [string:story] | [float:2.40] | [boolean:true] | | |
53
+ | [string:toy] | [string:2] | [string:story] | [float:2.45] | [boolean:true] | | [nil:] |
54
+ | [string:toy] | [string:3] | [string:story] | [float:2.45] | [boolean:true] | [nil:] | [nil:] |
55
+ | [string:toy] | [string:4] | | [float:2.45] | [boolean:false] | [nil:] | [nil:] |
56
+ | | [string:5] | | [float:2.45] | [boolean:true] | [nil:] | [nil:] |
57
+ | [string:toy] | [string:6] | | [float:2.46] | [boolean:true] | [nil:] | [nil:] |
58
+ When filter "Product" by:
60
59
  | field | value |
61
60
  | name | [string:toy] |
62
61
  | title | [string:story] |
63
62
  | summary | [nil:] |
64
63
  | price | [string:2.45] |
65
64
  | active | [boolean:true] |
66
- | info | [string:a] |
67
65
  | state | [nil:] |
68
66
  Then total records should be "2"
69
67
  And records should have the following attributes:
@@ -1,31 +1,35 @@
1
- Given /^create models:$/ do |table|
2
- table.hashes.each do |hash|
3
- attributes = typecast_attributes(hash[:attributes])
4
- Object.const_get(hash[:model]).create!(attributes)
1
+ Given /^create "([^"]+)" model$/ do |klass|
2
+ klass.constantize.create!
3
+ end
4
+
5
+ Given /^(load and )?(save|create|update(?: all| attributes)?|destroy(?: all)?|delete(?: all)?)(?: for)? "([^"]+)" models? with attributes as "([^"]+)":$/ do |load, action, klass, format, table|
6
+ action = action.gsub(' ', '_')
7
+ klass = klass.constantize
8
+ models = load.present? ? klass.all : [klass]
9
+
10
+ Array.wrap(table.send(format)).each do |hash|
11
+ models.each do |model|
12
+ model.send(action, type_cast_hash(hash))
13
+ end
5
14
  end
6
15
  end
7
16
 
8
- Given /^create model "([^"]+)" with attributes "([^"]+)"$/ do |klass, attributes|
9
- attrs = typecast_attributes(attributes)
10
- @model = Object.const_get(klass).create!(attrs)
17
+ Given /^create "([^"]+)" association for "([^"]+)" with attributes as "([^"]+)":$/ do |association, klass, format, table|
18
+ Array.wrap(table.send(format)).each do |hash|
19
+ klass.constantize.send(association).create(hash)
20
+ end
11
21
  end
12
22
 
13
- Then /^model "([^"]+)" should "(should|should_not)" to "([^"]+)"$/ do |klass, method, attributes|
14
- model = Object.const_get(klass).new
23
+ Then /^model "([^"]+)" (should(?:\snot)?) respond to "([^"]+)"$/ do |klass, method, attributes|
24
+ model = klass.constantize.new
25
+ method = method.gsub(/\s+/, '_')
15
26
  attributes.split.each do |attribute|
16
27
  model.send(method, respond_to(attribute))
17
28
  end
18
29
  end
19
30
 
20
- Then /^it should have typecast attributes "([^"]+)"$/ do |attributes|
21
- @model.reload # ensure that all attributes have correct type
22
- typecast_attributes(attributes).each do |name, value|
23
- @model.send(name).should == value
31
+ Then /^(last|first) created "([^"]+)" (should|should not) have the following attributes:$/ do |method, klass, match, table|
32
+ table.rows_hash.each_with_object(klass.constantize.send(method)) do |(attribute, value), model|
33
+ model.send(attribute).send(match) == type_cast_value(value)
24
34
  end
25
- end
26
-
27
- Then /^model "([^"]+)" should have only the following ((?:hydra )?attributes(?: before type cast)?) "([^"]+)"$/ do |klass, method, attributes|
28
- model = Object.const_get(klass).new
29
- method = method.gsub(/\s+/, '_')
30
- model.send(method).keys.should =~ attributes.split(/\s+/)
31
35
  end
@@ -1,5 +1,5 @@
1
1
  When /^filter "([^"]+)" by:$/ do |klass, table|
2
- condition = table.hashes.each_with_object({}) { |item, hash| hash[item[:field].to_sym] = typecast_value(item[:value]) }
2
+ condition = table.hashes.each_with_object({}) { |item, hash| hash[item[:field].to_sym] = type_cast_value(item[:value]) }
3
3
  @records = Object.const_get(klass).where(condition)
4
4
  end
5
5
 
@@ -9,7 +9,7 @@ When /^filter "([^"]+)" records by "([^"]+)"$/ do |klass, attribute|
9
9
  end
10
10
 
11
11
  When /^filter records by "([^"]+)"$/ do |attribute|
12
- name, value = typecast_attribute(attribute)
12
+ name, value = type_cast_attribute(attribute)
13
13
  @records = @records.where(name => value)
14
14
  end
15
15
 
@@ -39,6 +39,10 @@ When /^(order|reorder) records by "([^"]+)"$/ do |sort_method, attributes|
39
39
  @records = @records.reverse_order if reverse
40
40
  end
41
41
 
42
+ When /^reverse order records$/ do
43
+ @records = @records.reverse_order
44
+ end
45
+
42
46
  When /^"([^"]+)" select only the following columns "([^"]+)"$/ do |klass, columns|
43
47
  @records = Object.const_get(klass).select(columns.split(/\s+/).map(&:to_sym))
44
48
  end
@@ -2,38 +2,51 @@ When /^load all "([^"]+)" records$/ do |klass|
2
2
  @records = Object.const_get(klass).all
3
3
  end
4
4
 
5
- When /^select "(first|last)" "([^"]+)" record$/ do |method, klass|
5
+ When /^select (first|last) "([^"]+)" record$/ do |method, klass|
6
6
  @record = Object.const_get(klass).send(method)
7
7
  end
8
8
 
9
- Then /^record should have the following ((?:hydra )?attributes(?: before type cast)?) "([^"]+)" in attribute hash$/ do |method, attributes|
10
- method = method.gsub(/\s+/, '_')
11
- typecast_attributes(attributes).each do |(name, value)|
12
- @record.send(method)[name.to_s].should == value
9
+ When /^assign attributes as "([^"]+)":$/ do |format, table|
10
+ Array.wrap(table.send(format)).each do |hash|
11
+ @record.assign_attributes(type_cast_hash(hash))
13
12
  end
14
13
  end
15
14
 
15
+ When /^(save|destroy) record$/ do |action|
16
+ @record.send(action)
17
+ end
18
+
19
+ When /^keep "([^"]+)" attribute$/ do |attribute|
20
+ @keep ||= {}
21
+ @keep[attribute] = @record.send(attribute)
22
+ end
23
+
24
+ Then /^attribute "([^"]+)" (should(?:\snot)?) be the same$/ do |attribute, behavior|
25
+ method = behavior.sub(/\s/, '_')
26
+ @keep[attribute].send(method) == @record.send(attribute)
27
+ end
28
+
16
29
  Then /^record (read attribute(?: before type cast)?) "([^"]+)" and value should be "([^"]+)"$/ do |method, attribute, value|
17
30
  method = method.gsub(/\s+/, '_')
18
- @record.send(method, attribute).should == typecast_value(value)
31
+ @record.send(method, attribute).should == type_cast_value(value)
19
32
  end
20
33
 
21
34
  Then /^"(first|last)" record should have "([^"]+)"$/ do |method, attribute|
22
- typecast_attributes(attribute).each do |(name, value)|
35
+ type_cast_attributes(attribute).each do |(name, value)|
23
36
  @records.send(method).send(name).should == value
24
37
  end
25
38
  end
26
39
 
27
40
  Then /^records should have the following attributes:$/ do |table|
28
41
  table.hashes.each do |hash|
29
- record = @records.detect { |r| r.send(hash[:field]) == typecast_value(hash[:value]) }
42
+ record = @records.detect { |r| r.send(hash[:field]) == type_cast_value(hash[:value]) }
30
43
  record.should_not be_nil
31
44
  end
32
45
  end
33
46
 
34
47
  Then /^records should have only the following "([^"]+)" names$/ do |attributes|
35
48
  @records.each do |record|
36
- record.attributes.keys.should == attributes.split(/\s+/)
49
+ record.attributes.keys.should =~ attributes.split(/\s+/)
37
50
  end
38
51
  end
39
52
 
@@ -47,7 +60,12 @@ Then /^records should raise "([^"]+)" when call the following "([^"]+)"$/ do |er
47
60
  end
48
61
 
49
62
  Then /^total records should be "([^"]+)"$/ do |count|
50
- @records.to_a.should have(count.to_i).items
63
+ @records.to_a.should have(count.to_i).records
64
+ end
65
+
66
+ Then /^total "([^"]+)" records should be "([^"]+)"$/ do |klass, count|
67
+ @records = klass.constantize.scoped
68
+ step %Q(total records should be "#{count}")
51
69
  end
52
70
 
53
71
  Then /^records "(should|should_not)" have loaded associations:$/ do |should, table|
@@ -11,15 +11,21 @@ ActiveRecord::Base.extend(HydraAttribute::ActiveRecord)
11
11
  DatabaseCleaner.strategy = :truncation
12
12
 
13
13
  Before do
14
- HydraAttribute::SUPPORT_TYPES.each do |type|
15
- const = HydraAttribute.config.associated_const_name(type)
16
- HydraAttribute.send(:remove_const, const) if HydraAttribute.const_defined?(const)
17
- end
18
- [:Product, :SimpleProduct, :GroupProduct].each do |const|
19
- Object.send(:remove_const, const) if Object.const_defined?(const)
14
+ if Object.const_defined?(:Product)
15
+ HydraAttribute::SUPPORT_TYPES.each do |type|
16
+ assoc_model = HydraAttribute::AssociationBuilder.new(Product, type).model_name
17
+ HydraAttribute.send(:remove_const, assoc_model)
18
+ end
19
+
20
+ Object.send(:remove_const, :Product)
20
21
  end
22
+
21
23
  ActiveSupport::Dependencies::Reference.clear!
22
24
  DatabaseCleaner.start
25
+
26
+ class Product < ActiveRecord::Base
27
+ use_hydra_attributes
28
+ end
23
29
  end
24
30
 
25
31
  After do
@@ -1,51 +1,78 @@
1
1
  ActiveRecord::Schema.define do
2
2
  create_table "products", :force => true do |t|
3
- t.string "type"
4
- t.string "name"
5
- t.string "info"
6
- t.datetime "created_at", :null => false
7
- t.datetime "updated_at", :null => false
3
+ t.string "name"
4
+ t.datetime "created_at", :null => false
5
+ t.datetime "updated_at", :null => false
8
6
  end
9
7
 
10
- create_table "hydra_string_attributes", :force => true do |t|
11
- t.integer "entity_id"
12
- t.string "entity_type"
13
- t.string "name"
14
- t.string "value"
8
+ create_table "hydra_attributes", :force => true do |t|
9
+ t.string "entity_type", :limit => 32, :null => false
10
+ t.string "name", :limit => 32, :null => false
11
+ t.string "backend_type", :limit => 16, :null => false
12
+ t.string "default_value"
13
+ t.datetime "created_at", :null => false
14
+ t.datetime "updated_at", :null => false
15
15
  end
16
16
 
17
- create_table "hydra_float_attributes", :force => true do |t|
18
- t.integer "entity_id"
19
- t.string "entity_type"
20
- t.string "name"
21
- t.float "value"
17
+ add_index "hydra_attributes", ["entity_type", "name"], :name => "hydra_attributes_index", :unique => true
18
+
19
+ create_table "hydra_boolean_products", :force => true do |t|
20
+ t.integer "entity_id", :null => false
21
+ t.integer "hydra_attribute_id", :null => false
22
+ t.boolean "value"
23
+ t.datetime "created_at", :null => false
24
+ t.datetime "updated_at", :null => false
22
25
  end
23
26
 
24
- create_table "hydra_boolean_attributes", :force => true do |t|
25
- t.integer "entity_id"
26
- t.string "entity_type"
27
- t.string "name"
28
- t.boolean "value"
27
+ add_index "hydra_boolean_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_boolean_products_index", :unique => true
28
+
29
+ create_table "hydra_datetime_products", :force => true do |t|
30
+ t.integer "entity_id", :null => false
31
+ t.integer "hydra_attribute_id", :null => false
32
+ t.datetime "value"
33
+ t.datetime "created_at", :null => false
34
+ t.datetime "updated_at", :null => false
29
35
  end
30
36
 
31
- create_table "hydra_integer_attributes", :force => true do |t|
32
- t.integer "entity_id"
33
- t.string "entity_type"
34
- t.string "name"
35
- t.integer "value"
37
+ add_index "hydra_datetime_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_datetime_products_index", :unique => true
38
+
39
+ create_table "hydra_float_products", :force => true do |t|
40
+ t.integer "entity_id", :null => false
41
+ t.integer "hydra_attribute_id", :null => false
42
+ t.float "value"
43
+ t.datetime "created_at", :null => false
44
+ t.datetime "updated_at", :null => false
36
45
  end
37
46
 
38
- create_table "hydra_text_attributes", :force => true do |t|
39
- t.integer "entity_id"
40
- t.string "entity_type"
41
- t.string "name"
42
- t.text "value"
47
+ add_index "hydra_float_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_float_products_index", :unique => true
48
+
49
+ create_table "hydra_integer_products", :force => true do |t|
50
+ t.integer "entity_id", :null => false
51
+ t.integer "hydra_attribute_id", :null => false
52
+ t.integer "value"
53
+ t.datetime "created_at", :null => false
54
+ t.datetime "updated_at", :null => false
43
55
  end
44
56
 
45
- create_table "hydra_datetime_attributes", :force => true do |t|
46
- t.integer "entity_id"
47
- t.string "entity_type"
48
- t.string "name"
49
- t.datetime "value"
57
+ add_index "hydra_integer_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_integer_products_index", :unique => true
58
+
59
+ create_table "hydra_string_products", :force => true do |t|
60
+ t.integer "entity_id", :null => false
61
+ t.integer "hydra_attribute_id", :null => false
62
+ t.string "value"
63
+ t.datetime "created_at", :null => false
64
+ t.datetime "updated_at", :null => false
50
65
  end
66
+
67
+ add_index "hydra_string_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_string_products_index", :unique => true
68
+
69
+ create_table "hydra_text_products", :force => true do |t|
70
+ t.integer "entity_id", :null => false
71
+ t.integer "hydra_attribute_id", :null => false
72
+ t.text "value"
73
+ t.datetime "created_at", :null => false
74
+ t.datetime "updated_at", :null => false
75
+ end
76
+
77
+ add_index "hydra_text_products", ["entity_id", "hydra_attribute_id"], :name => "hydra_text_products_index", :unique => true
51
78
  end
@@ -1,8 +1,11 @@
1
1
  module HydraAttribute
2
2
  module Cucumber
3
3
  module World
4
- def typecast_value(schema)
4
+ def type_cast_value(schema)
5
+ return schema unless schema.is_a?(String)
5
6
  type, value = schema.gsub(/\[|\]/, '').split(':', 2)
7
+ return schema if schema == type && value.nil?
8
+
6
9
  case type
7
10
  when 'integer' then value.to_i
8
11
  when 'float' then value.to_f
@@ -13,17 +16,23 @@ module HydraAttribute
13
16
  end
14
17
  end
15
18
 
16
- def typecast_attribute(attribute)
19
+ def type_cast_attribute(attribute)
17
20
  name, schema = attribute.split('=')
18
- [name.to_sym, typecast_value(schema)]
21
+ [name, type_cast_value(schema)]
19
22
  end
20
23
 
21
- def typecast_attributes(attributes)
24
+ def type_cast_attributes(attributes)
22
25
  attributes.split(/(?<=\])\s+/).flatten.each_with_object({}) do |attribute, hash|
23
- name, value = typecast_attribute(attribute)
26
+ name, value = type_cast_attribute(attribute)
24
27
  hash[name] = value
25
28
  end
26
29
  end
30
+
31
+ def type_cast_hash(hash)
32
+ hash.delete_if{ |_, v| v.blank? }.each do |key, value|
33
+ hash[key] = type_cast_value(value)
34
+ end
35
+ end
27
36
  end
28
37
  end
29
38
  end
@@ -0,0 +1,114 @@
1
+ Feature: update hydra attributes
2
+ When update attribute
3
+ Then entity should be touched
4
+
5
+ Background: create hydra attributes
6
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
7
+ | entity_type | name | backend_type | default_value |
8
+ | Product | code | string | [string:###] |
9
+ | Product | title | string | |
10
+ | Product | total | integer | [integer:1] |
11
+ And create "Product" model
12
+
13
+ Scenario Outline: update attributes
14
+ Given select last "Product" record
15
+ When assign attributes as "rows_hash":
16
+ | code | <set code> |
17
+ | title | <set title> |
18
+ | total | <set total> |
19
+ And save record
20
+ Then last created "Product" should have the following attributes:
21
+ | code | <code> |
22
+ | title | <title> |
23
+ | total | <total> |
24
+
25
+ Scenarios: attributes
26
+ | set code | set title | set total | code | title | total |
27
+ | [string:a] | [string:b] | [integer:2] | [string:a] | [string:b] | [integer:2] |
28
+ | [string:] | [string:] | [nil:] | [string:] | [string:] | [nil:] |
29
+ | | | [string:3] | [string:###] | [nil:] | [integer:3] |
30
+
31
+ # Is a better solution to call several scenarios but don't call hooks and backgrounds before?
32
+ Scenario: update the same model several times
33
+ Given select first "Product" record
34
+ And save record
35
+ Then last created "Product" should have the following attributes:
36
+ | code | [string:###] |
37
+ | title | [nil:] |
38
+ | total | [integer:1] |
39
+
40
+ When assign attributes as "rows_hash":
41
+ | title | [string:] |
42
+ | total | [nil:] |
43
+ And save record
44
+ Then last created "Product" should have the following attributes:
45
+ | code | [string:###] |
46
+ | title | [string:] |
47
+ | total | [nil:] |
48
+
49
+ When assign attributes as "rows_hash":
50
+ | code | [string:a] |
51
+ | total | [string:2] |
52
+ And save record
53
+ Then last created "Product" should have the following attributes:
54
+ | code | [string:a] |
55
+ | title | [string:] |
56
+ | total | [integer:2] |
57
+
58
+ When assign attributes as "rows_hash":
59
+ | title | [string:b] |
60
+ And save record
61
+ Then last created "Product" should have the following attributes:
62
+ | code | [string:a] |
63
+ | title | [string:b] |
64
+ | total | [integer:2] |
65
+
66
+ Scenario: touch entity when attribute is updated
67
+ Given select last "Product" record
68
+ And keep "updated_at" attribute
69
+ And save record
70
+ Then attribute "updated_at" should be the same
71
+
72
+ Given select last "Product" record
73
+ And keep "updated_at" attribute
74
+ When assign attributes as "rows_hash":
75
+ | code | [string:###] |
76
+ | total | [integer:1] |
77
+ And save record
78
+ Then attribute "updated_at" should be the same
79
+
80
+ Given select last "Product" record
81
+ And keep "updated_at" attribute
82
+ When assign attributes as "rows_hash":
83
+ | code | [nil:] |
84
+ And save record
85
+ Then attribute "updated_at" should not be the same
86
+
87
+ Given select last "Product" record
88
+ And keep "updated_at" attribute
89
+ When assign attributes as "rows_hash":
90
+ | code | [nil:] |
91
+ And save record
92
+ Then attribute "updated_at" should be the same
93
+
94
+ Given select last "Product" record
95
+ And keep "updated_at" attribute
96
+ When assign attributes as "rows_hash":
97
+ | total | [nil:] |
98
+ And save record
99
+ Then attribute "updated_at" should not be the same
100
+
101
+ Given select last "Product" record
102
+ And keep "updated_at" attribute
103
+ When assign attributes as "rows_hash":
104
+ | code | [string:] |
105
+ And save record
106
+ Then attribute "updated_at" should not be the same
107
+
108
+ Given select last "Product" record
109
+ And keep "updated_at" attribute
110
+ When assign attributes as "rows_hash":
111
+ | title | [string:] |
112
+ | total | [integer:0] |
113
+ And save record
114
+ Then attribute "updated_at" should not be the same
@@ -1,36 +1,36 @@
1
1
  PATH
2
2
  remote: /Users/kostyantyn/Sites/github/gems/hydra_attribute
3
3
  specs:
4
- hydra_attribute (0.2.0.beta1)
4
+ hydra_attribute (0.3.0.beta2)
5
5
  activerecord (>= 3.1.0)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- activemodel (3.1.5)
11
- activesupport (= 3.1.5)
10
+ activemodel (3.1.6)
11
+ activesupport (= 3.1.6)
12
12
  builder (~> 3.0.0)
13
13
  i18n (~> 0.6)
14
- activerecord (3.1.5)
15
- activemodel (= 3.1.5)
16
- activesupport (= 3.1.5)
14
+ activerecord (3.1.6)
15
+ activemodel (= 3.1.6)
16
+ activesupport (= 3.1.6)
17
17
  arel (~> 2.2.3)
18
18
  tzinfo (~> 0.3.29)
19
- activesupport (3.1.5)
19
+ activesupport (3.1.6)
20
20
  multi_json (>= 1.0, < 1.3)
21
21
  appraisal (0.4.1)
22
22
  bundler
23
23
  rake
24
24
  arel (2.2.3)
25
25
  builder (3.0.0)
26
- cucumber (1.2.0)
26
+ cucumber (1.2.1)
27
27
  builder (>= 2.1.2)
28
28
  diff-lcs (>= 1.1.3)
29
- gherkin (~> 2.10.0)
29
+ gherkin (~> 2.11.0)
30
30
  json (>= 1.4.6)
31
31
  database_cleaner (0.8.0)
32
32
  diff-lcs (1.1.3)
33
- gherkin (2.10.0)
33
+ gherkin (2.11.1)
34
34
  json (>= 1.4.6)
35
35
  i18n (0.6.0)
36
36
  json (1.7.3)
@@ -1,21 +1,21 @@
1
1
  PATH
2
2
  remote: /Users/kostyantyn/Sites/github/gems/hydra_attribute
3
3
  specs:
4
- hydra_attribute (0.2.0.beta1)
4
+ hydra_attribute (0.3.0.beta2)
5
5
  activerecord (>= 3.1.0)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- activemodel (3.2.5)
11
- activesupport (= 3.2.5)
10
+ activemodel (3.2.6)
11
+ activesupport (= 3.2.6)
12
12
  builder (~> 3.0.0)
13
- activerecord (3.2.5)
14
- activemodel (= 3.2.5)
15
- activesupport (= 3.2.5)
13
+ activerecord (3.2.6)
14
+ activemodel (= 3.2.6)
15
+ activesupport (= 3.2.6)
16
16
  arel (~> 3.0.2)
17
17
  tzinfo (~> 0.3.29)
18
- activesupport (3.2.5)
18
+ activesupport (3.2.6)
19
19
  i18n (~> 0.6)
20
20
  multi_json (~> 1.0)
21
21
  appraisal (0.4.1)
@@ -23,14 +23,14 @@ GEM
23
23
  rake
24
24
  arel (3.0.2)
25
25
  builder (3.0.0)
26
- cucumber (1.2.0)
26
+ cucumber (1.2.1)
27
27
  builder (>= 2.1.2)
28
28
  diff-lcs (>= 1.1.3)
29
- gherkin (~> 2.10.0)
29
+ gherkin (~> 2.11.0)
30
30
  json (>= 1.4.6)
31
31
  database_cleaner (0.8.0)
32
32
  diff-lcs (1.1.3)
33
- gherkin (2.10.0)
33
+ gherkin (2.11.1)
34
34
  json (>= 1.4.6)
35
35
  i18n (0.6.0)
36
36
  json (1.7.3)