hydra_attribute 0.2.0 → 0.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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
data/README.md CHANGED
@@ -16,110 +16,116 @@ gem 'hydra_attribute'
16
16
  ```
17
17
  and run `bundle install` from your shell.
18
18
 
19
- After successful installation run rails generator:
19
+ Then we should generate our migration:
20
20
  ```shell
21
- rails generate hydra_attribute:install
22
- ```
23
-
24
- This command generates hydra_attribute initializer:
21
+ rails generate migration create_hydra_attributes
22
+ ```
23
+ The content should be:
25
24
  ```ruby
26
- HydraAttribute.setup do |config|
27
- # Add prefix for all attribute tables
28
- # config.table_prefix = 'hydra_'
29
-
30
- # Add prefix for has_many associations
31
- # config.association_prefix = 'hydra_'
25
+ class CreateHydraAttributeTables < ActiveRecord::Migration
26
+ def up
27
+ create_hydra_entity :products do |t|
28
+ # add here all other columns that should be in the entity table
29
+ t.timestamps
30
+ end
31
+ end
32
32
 
33
- # Wrap all associated models in HydraAttribute module
34
- # config.use_module_for_associated_models = true
33
+ def down
34
+ drop_hydra_entity :products
35
+ end
35
36
  end
36
37
  ```
37
38
 
38
- And the last step is to generate db:migration:
39
- ```shell
40
- rails generate migration create_hydra_attrubute_tables
41
- ```
42
- Migration should look like this:
39
+ ##### or if we have already the entity table
43
40
  ```ruby
44
41
  class CreateHydraAttributeTables < ActiveRecord::Migration
45
42
  def up
46
- HydraAttribute::Migration.new(self).migrate
43
+ migrate_to_hydra_entity :products
47
44
  end
48
45
 
49
46
  def down
50
- HydraAttribute::Migration.new(self).rollback
47
+ rollback_from_hydra_entity :products
51
48
  end
52
49
  end
53
50
  ```
51
+
54
52
  ## Usage
55
53
 
56
- ##### Generate model
54
+ ##### Create model
57
55
  ```shell
58
- rails generate model Product type:string name:string
59
- rails generate model SimpleProduct --migration=false --parent=Product
56
+ rails generate model Product type:string name:string --migration=false
60
57
  rake db:migrate
61
58
  ```
62
59
 
63
- ##### Describe EAV attributes
60
+ ##### Create some hydra attributes from `rails console`
64
61
  ```ruby
65
- class SimpleProduct < Product
66
- attr_accessible :name, :title, :code, :quantity, :price, :active, :description
67
-
68
- define_hydra_attributes do
69
- string :title, :code
70
- integer :quantity
71
- float :price
72
- boolean :active
73
- text :description
74
- end
75
- end
62
+ Product.hydra_attributes.create(name: 'color', backend_type: 'string', default_value: 'green')
63
+ Product.hydra_attributes.create(name: 'title', backend_type: 'string')
64
+ Product.hydra_attributes.create(name: 'total', backend_type: 'integer', default_value: 1)
76
65
  ```
77
66
 
78
- ##### Create some products
79
- ```shell
80
- SimpleProduct.create(name: 'Book', title: 'book', code: '100', quantity: 5, price: 2.75, active: true, description: '...')
81
- SimpleProduct.create(name: 'Book', title: 'book', code: '101', quantity: 5, price: 3.75, active: true, description: '...')
82
- SimpleProduct.create(name: 'Book', title: 'book', code: '102', quantity: 4, price: 4.50, active: false, description: '...')
83
- SimpleProduct.create(name: 'Book', title: nil, code: '103', quantity: 3, price: 4.50, active: true, description: '...')
84
- SimpleProduct.create(name: 'Book', code: '104', quantity: 2, price: 5.00, active: true, description: '...')
85
- ```
67
+ So we created three hydra attributes: **color**, **title** and **total**.
68
+ * `name` is **required** and it is the name of attribute.
69
+ * `backend_type` is **required** and tells us in what table the value for this attribute will be stored.
70
+ The whole list of allowed backend types are: `string`, `text`, `integer`, `float`, `boolean` and `datetime`
71
+ * `default_value` is **optional** and it sets the default value for attribute.
86
72
 
87
- ##### "where"
88
- ```shell
89
- SimpleProduct.where(name: 'Book', quantity: 5, price: 2.75).first.attributes
90
- => {"id"=>1, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:13:21 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:13:21 UTC +00:00, "title"=>"book", "code"=>"100", "quantity"=>5, "price"=>2.75, "active"=>true, "description"=>"..."}
91
-
92
- SimpleProduct.where(title: 'book', active: false).first.attributes
93
- => {"id"=>3, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:13:50 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:13:50 UTC +00:00, "title"=>"book", "code"=>"102", "quantity"=>4, "price"=>4.5, "active"=>false, "description"=>"..."}
73
+ ##### Create several objects
94
74
 
95
- SimpleProduct.where(title: nil).first.attributes
96
- => {"id"=>4, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:13:50 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:13:50 UTC +00:00, "title"=>nil, "code"=>"103", "quantity"=>3, "price"=>4.5, "active"=>true, "description"=>"..."}
75
+ ```ruby
76
+ Product.create.attributes
77
+ # {"id"=>1, created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>nil, "total"=>1}
78
+ Product.create(color: 'red', title: 'toy').attributes
79
+ # {"id"=>1, "created_at"=>..., "updated_at"=>..., "color"=>"red", "title"=>"toy", "total"=>1}
80
+ Product.create(title: 'book', total: 2).attributes
81
+ # {"id"=>1, "created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>"book", "total"=>2}
82
+ ```
97
83
 
98
- SimpleProduct.where(title: nil).last.attributes
99
- => {"id"=>5, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:13:51 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:13:51 UTC +00:00, "title"=>nil, "code"=>"104", "quantity"=>2, "price"=>5.0, "active"=>true, "description"=>"..."}
84
+ ##### Add the new attribute in runtime
85
+ ```ruby
86
+ Product.hydra_attributes.create(name: 'price', backend_type: 'float', default_value: 0.0)
87
+ Product.create(title: 'car', price: 2.50).attributes
88
+ # {"id"=>4, "created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>"car", "price"=>2.5, "total"=>1}
100
89
  ```
101
90
 
102
- ##### "order" and "reverse_order"
103
- ```shell
104
- SimpleProduct.order(:code).first.attributes
105
- => {"id"=>1, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:30:48 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:30:49 UTC +00:00, "title"=>"book", "code"=>"100", "quantity"=>5, "price"=>2.75, "active"=>true, "description"=>"..."}
91
+ ##### Obtain data
92
+ ```ruby
93
+ Product.where(color: 'red').map(&:attributes)
94
+ # [{"id"=>2, "created_at"=>..., "updated_at"=>..., "color"=>"red", "title"=>"toy", "price"=>0.0, "total"=>1}]
95
+ Product.where(color: 'green', price: nil).map(&:attributes)
96
+ # [{"id"=>1, "created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>nil, "price"=>0.0, "total"=>1},
97
+ # {"id"=>3, "created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>"book", "price"=>0.0, "total"=>2}]
98
+ ```
99
+ **Notice**: the attribute `price` was added in runtime and records that were created before have not this attribute
100
+ so they matched this condition `where(price: nil)`
106
101
 
107
- SimpleProduct.order(:code).reverse_order.first.attributes
108
- => {"id"=>5, "type"=>"SimpleProduct", "name"=>"Book", "created_at"=>Tue, 05 Jun 2012 23:30:51 UTC +00:00, "updated_at"=>Tue, 05 Jun 2012 23:30:51 UTC +00:00, "title"=>nil, "code"=>"104", "quantity"=>2, "price"=>5.0, "active"=>true, "description"=>"..."}
102
+ ##### Order data
103
+ ```ruby
104
+ Product.order(:color).first.attributes
105
+ # {"id"=>1, "created_at"=>..., "updated_at"=>..., "color"=>"green", "title"=>nil, "price"=>0.0, "total"=>1}
106
+ Product.order(:color).reverse_order.first.attributes
107
+ # {"id"=>2, "created_at"=>..., "updated_at"=>..., "color"=>"red", "title"=>"toy", "price"=>0.0, "total"=>1}
109
108
  ```
110
109
 
111
- ##### "select"
112
- ```shell
113
- SimpleProduct.select([:code, :price]).map(&:attributes)
114
- => [{"code"=>"100", "price"=>2.75}, {"code"=>"101", "price"=>3.75}, {"code"=>"102", "price"=>4.5}, {"code"=>"103", "price"=>4.5}, {"code"=>"104", "price"=>5.0}]
110
+ ##### Select concrete attributes
111
+ ```ruby
112
+ Product.select([:color, :title]).map(&:attributes)
113
+ # [{"id"=>1, "color"=>"green", "title"=>nil}, {"id"=>2, "color"=>"red", "title"=>"toy"},
114
+ # {"id"=>3, "color"=>"green", "title"=>"book"}, {"id"=>4, "color"=>"green", "title"=>"car"}]
115
115
  ```
116
+ **Notice**: `id` attribute will be added if we want to select hydra attribute
116
117
 
117
- ##### "group"
118
- ```shell
119
- SimpleProduct.group(:name, :price).count
120
- => {["Book", 2.75]=>1, ["Book", 3.75]=>1, ["Book", 4.5]=>2, ["Book", 5.0]=>1}
118
+ ##### Group by attribute
119
+ ```ruby
120
+ Product.group(:color).count
121
+ # {"green"=>3, "red"=>1}
121
122
  ```
122
123
 
124
+ ## Notice
125
+
126
+ The each new minor version doesn't guarantee back compatibility with previous one
127
+ until the first major version will be released.
128
+
123
129
  ## Contributing
124
130
 
125
131
  1. Fork it
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: -r features
@@ -0,0 +1,22 @@
1
+ Feature: create hydra attributes
2
+ When new hydra attribute is created
3
+ Then entity should respond to it
4
+
5
+ Background: create hydra attributes
6
+ Given create "HydraAttribute::HydraAttribute" model with attributes as "hashes":
7
+ | entity_type | name | backend_type |
8
+ | Product | price | float |
9
+
10
+ Scenario: create hydra attribute in runtime
11
+ # Important: when respond_to? is called the hydra attributes are being loaded for entity class
12
+ Then model "Product" should respond to "price"
13
+ Given create "HydraAttribute::HydraAttribute" model with attributes as "hashes":
14
+ | entity_type | name | backend_type |
15
+ | Product | title | string |
16
+ Then model "Product" should respond to "title"
17
+
18
+ Scenario: create hydra attribute from entity class
19
+ Given create "hydra_attributes" association for "Product" with attributes as "hashes":
20
+ | name | backend_type |
21
+ | code | integer |
22
+ Then model "Product" should respond to "code"
@@ -0,0 +1,18 @@
1
+ Feature: destroy hydra attributes
2
+ When destroy hydra attribute
3
+ Then model should not respond to this attribute any more
4
+ And all values for this attribute should be removed
5
+
6
+ Background: create hydra attributes
7
+ Given create "HydraAttribute::HydraAttribute" model with attributes as "hashes":
8
+ | entity_type | name | backend_type |
9
+ | Product | price | float |
10
+
11
+ Scenario: destroy hydra attribute in runtime
12
+ Given create "Product" model with attributes as "rows_hash":
13
+ | price | 10 |
14
+ When destroy all "HydraAttribute::HydraAttribute" models with attributes as "hashes":
15
+ | entity_type | name |
16
+ | Product | price |
17
+ Then model "Product" should not respond to "price"
18
+ And total "HydraAttribute::HydraFloatProduct" records should be "0"
@@ -0,0 +1,19 @@
1
+ Feature: update hydra attribute
2
+ When update hydra attribute data
3
+ Then model should be notified about this
4
+
5
+ Background: create hydra attributes
6
+ Given create "HydraAttribute::HydraAttribute" model with attributes as "hashes":
7
+ | entity_type | name | backend_type | default_value |
8
+ | Product | code | integer | 1 |
9
+
10
+ Scenario: update default value in runtime
11
+ Given create "Product" model
12
+ And load and update attributes for "HydraAttribute::HydraAttribute" models with attributes as "rows_hash":
13
+ | default_value | 2 |
14
+ And create "Product" model
15
+ Then first created "Product" should have the following attributes:
16
+ | code | [integer:1] |
17
+ And last created "Product" should have the following attributes:
18
+ | code | [integer:2] |
19
+
@@ -0,0 +1,47 @@
1
+ Feature: create models with hydra attributes
2
+ When create model with hydra attributes
3
+ Then hydra attributes should be saved with default values
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 | [nil:] |
9
+ | Product | price | float | [string:0] |
10
+ | Product | active | boolean | [string:0] |
11
+ | Product | info | text | [string:] |
12
+ | Product | started | datetime | [string:2012-01-01] |
13
+
14
+ Scenario: create model without hydra attributes
15
+ Given create "Product" model
16
+ Then last created "Product" should have the following attributes:
17
+ | code | [nil:] |
18
+ | price | [float:0] |
19
+ | active | [boolean:false] |
20
+ | info | [string:] |
21
+ | started | [datetime:2012-01-01] |
22
+
23
+ Scenario: create model with several hydra attributes
24
+ Given create "Product" model with attributes as "rows_hash":
25
+ | code | [string:a] |
26
+ | price | [nil:] |
27
+ Then last created "Product" should have the following attributes:
28
+ | code | [string:a] |
29
+ | price | [nil:] |
30
+ | active | [boolean:false] |
31
+ | info | [string:] |
32
+ | started | [datetime:2012-01-01] |
33
+
34
+ Scenario: create model hydra attributes
35
+ Given create "Product" model with attributes as "rows_hash":
36
+ | code | [string:a] |
37
+ | price | [string:2] |
38
+ | active | [boolean:true] |
39
+ | info | [string:b] |
40
+ | started | [datetime:2012-05-05] |
41
+
42
+ Then last created "Product" should have the following attributes:
43
+ | code | [string:a] |
44
+ | price | [float:2] |
45
+ | active | [boolean:true] |
46
+ | info | [string:b] |
47
+ | started | [datetime:2012-05-05] |
@@ -0,0 +1,33 @@
1
+ Feature: define hydra attributes
2
+ When use_hydra_attributes was called in model class
3
+ Then entity should respond to attributes which are saved in hydra_attributes table
4
+
5
+ Background: create hydra attributes
6
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
7
+ | entity_type | name | backend_type |
8
+ | Product | code | string |
9
+ | Product | price | float |
10
+
11
+ Scenario Outline: models should respond to hydra attributes
12
+ Then model "<model>" <action> respond to "<attributes>"
13
+
14
+ Scenarios: hydra attributes
15
+ | model | action | attributes |
16
+ | Product | should | code |
17
+ | Product | should | code= |
18
+ | Product | should | code? |
19
+ | Product | should | code_before_type_cast |
20
+ | Product | should | code_changed? |
21
+ | Product | should | code_change |
22
+ | Product | should | code_will_change! |
23
+ | Product | should | code_was |
24
+ | Product | should | reset_code! |
25
+ | Product | should | price |
26
+ | Product | should | price= |
27
+ | Product | should | price? |
28
+ | Product | should | price_before_type_cast |
29
+ | Product | should | price_changed? |
30
+ | Product | should | price_change |
31
+ | Product | should | price_will_change! |
32
+ | Product | should | price_was |
33
+ | Product | should | reset_price! |
@@ -3,21 +3,20 @@ Feature: group conditions by hydra attributes
3
3
  Then correct table should be joined and group condition should be added
4
4
 
5
5
  Background: create models and describe hydra attributes
6
- Given create model class "Product"
7
- And create model class "SimpleProduct" as "Product" with hydra attributes:
8
- | type | name |
9
- | integer | code |
10
- | string | title |
11
- | integer | total |
12
- And create models:
13
- | model | attributes |
14
- | SimpleProduct | name=[string:a] code=[integer:1] title=[string:q] total=[integer:5] |
15
- | SimpleProduct | name=[string:b] code=[integer:2] title=[string:w] total=[integer:5] |
16
- | SimpleProduct | name=[string:b] code=[integer:3] title=[string:w] total=[nil:] |
17
- | SimpleProduct | name=[string:c] code=[integer:4] title=[string:e] |
6
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
7
+ | entity_type | name | backend_type |
8
+ | Product | code | integer |
9
+ | Product | title | string |
10
+ | Product | total | integer |
11
+ Given create "Product" model with attributes as "hashes":
12
+ | name | code | title | total |
13
+ | [string:a] | [integer:1] | [string:q] | [integer:5] |
14
+ | [string:b] | [integer:2] | [string:w] | [integer:5] |
15
+ | [string:b] | [integer:3] | [string:w] | [nil:] |
16
+ | [string:c] | [integer:4] | [string:e] | |
18
17
 
19
18
  Scenario Outline: group by attributes
20
- When group "SimpleProduct" by "<group by>"
19
+ When group "Product" by "<group by>"
21
20
  Then total records should be "<total>"
22
21
  And "first" record should have "<first attribute>"
23
22
  And "last" record should have "<last attribute>"
@@ -29,7 +28,7 @@ Feature: group conditions by hydra attributes
29
28
  | name title | 3 | name=[string:a] code=[integer:1] | name=[string:c] code=[integer:4] |
30
29
 
31
30
  Scenario Outline: group by attributes with filter
32
- When group "SimpleProduct" by "<group by>"
31
+ When group "Product" by "<group by>"
33
32
  And filter records by "<filter>"
34
33
  Then total records should be "<total>"
35
34
  And "first" record should have "<first attribute>"
@@ -11,78 +11,89 @@ Feature: order conditions by hydra attributes
11
11
  When reorder by attributes
12
12
  Then old hydra attributes should be removed and new should be added
13
13
 
14
- Background: create models and describe hydra attributes
15
- Given create model class "Product"
16
- And create model class "SimpleProduct" as "Product" with hydra attributes:
17
- | type | name |
18
- | integer | code |
19
- | integer | state |
20
- | string | title |
14
+ Background: create hydra attributes
15
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
16
+ | entity_type | name | backend_type |
17
+ | Product | code | integer |
18
+ | Product | state | integer |
19
+ | Product | title | string |
21
20
 
22
21
  Scenario Outline: order by one field
23
- Given create models:
24
- | model | attributes |
25
- | SimpleProduct | name=[string:c] code=[integer:1] state=[integer:1] |
26
- | SimpleProduct | name=[string:b] code=[integer:2] state=[integer:2] |
27
- | SimpleProduct | name=[string:a] code=[integer:3] state=[integer:3] |
28
- When order "SimpleProduct" records by "<attributes>"
29
- Then "first" record should have "<first>"
30
- And "last" record should have "<last>"
22
+ Given create "Product" model with attributes as "hashes":
23
+ | name | code | state |
24
+ | [string:c] | [integer:1] | [integer:1] |
25
+ | [string:b] | [integer:2] | [integer:2] |
26
+ | [string:a] | [integer:3] | [integer:3] |
27
+ When order "Product" records by "<attributes>"
28
+ Then "first" record should have "<first identifier>"
29
+ And "last" record should have "<last identifier>"
31
30
 
32
31
  Scenarios: order conditions
33
- | attributes | first | last |
32
+ | attributes | first identifier | last identifier |
34
33
  | state=asc | code=[integer:1] | code=[integer:3] |
35
34
  | state=desc | code=[integer:3] | code=[integer:1] |
36
35
  | name=asc | code=[integer:3] | code=[integer:1] |
37
36
  | name=desc | code=[integer:1] | code=[integer:3] |
38
37
 
39
- Scenario Outline: order by several fields
40
- Given create models:
41
- | model | attributes |
42
- | SimpleProduct | name=[string:c] code=[integer:1] state=[integer:1] title=[string:b] |
43
- | SimpleProduct | name=[string:b] code=[integer:2] state=[integer:2] title=[string:a] |
44
- | SimpleProduct | name=[string:a] code=[integer:3] state=[integer:3] title=[string:c] |
45
- When order "SimpleProduct" records by "<attributes>"
46
- Then "first" record should have "<first>"
47
- And "last" record should have "<last>"
38
+ Scenario Outline: order by several attributes
39
+ Given create "Product" model with attributes as "hashes":
40
+ | name | code | state | title |
41
+ | [string:c] | [integer:1] | [integer:1] | [string:b] |
42
+ | [string:b] | [integer:2] | [integer:2] | [string:a] |
43
+ | [string:a] | [integer:3] | [integer:3] | [string:c] |
44
+ When order "Product" records by "<attributes>"
45
+ Then "first" record should have "<first identifier>"
46
+ And "last" record should have "<last identifier>"
48
47
 
49
48
  Scenarios: order conditions
50
- | attributes | first | last |
49
+ | attributes | first identifier | last identifier |
51
50
  | name state | code=[integer:3] | code=[integer:1] |
52
51
  | state title | code=[integer:1] | code=[integer:3] |
53
52
  | title state | code=[integer:2] | code=[integer:3] |
54
53
 
55
- Scenario Outline: order by already joined field
56
- Given create models:
57
- | model | attributes |
58
- | SimpleProduct | code=[integer:1] state=[integer:1] |
59
- | SimpleProduct | code=[integer:2] title=[nil:] |
60
- | SimpleProduct | code=[integer:3] state=[integer:1] title=[string:a] |
61
- When filter "SimpleProduct" records by "<filter>"
62
- And order records by "<order>"
54
+ Scenario Outline: order by filtered attribute
55
+ Given create "Product" model with attributes as "hashes":
56
+ | code | state | title |
57
+ | [integer:1] | [integer:1] | |
58
+ | [integer:2] | | [nil:] |
59
+ | [integer:3] | [integer:1] | [string:a] |
60
+ When filter "Product" records by "<filter attribute>"
61
+ And order records by "<order attributes>"
63
62
  Then total records should be "<count>"
64
- And "first" record should have "<first>"
65
- And "last" record should have "<last>"
63
+ And "first" record should have "<first identifier>"
64
+ And "last" record should have "<last identifier>"
66
65
 
67
- Scenarios:
68
- | filter | order | count | first | last |
69
- | state=[integer:1] | state code | 2 | code=[integer:1] | code=[integer:3] |
70
- | state=[nil:] | state code | 1 | code=[integer:2] | code=[integer:2] |
71
- | title=[nil:] | title code | 2 | code=[integer:1] | code=[integer:2] |
66
+ Scenarios: order conditions
67
+ | filter attribute | order attributes | count | first identifier | last identifier |
68
+ | state=[integer:1] | state code | 2 | code=[integer:1] | code=[integer:3] |
69
+ | state=[nil:] | state code | 1 | code=[integer:2] | code=[integer:2] |
70
+ | title=[nil:] | title code | 2 | code=[integer:1] | code=[integer:2] |
72
71
 
73
- Scenario Outline: reorder by hydra attributes
74
- Given create models:
75
- | model | attributes |
76
- | SimpleProduct | code=[integer:1] name=[string:a] title=[string:c] |
77
- | SimpleProduct | code=[integer:2] name=[string:b] title=[string:b] |
78
- | SimpleProduct | code=[integer:3] name=[string:c] title=[string:a] |
79
- When order "SimpleProduct" records by "<order>"
72
+ Scenario Outline: reorder
73
+ Given create "Product" model with attributes as "hashes":
74
+ | code | name | title |
75
+ | [integer:1] | [string:a] | [string:c] |
76
+ | [integer:2] | [string:b] | [string:b] |
77
+ | [integer:3] | [string:c] | [string:a] |
78
+ When order "Product" records by "<order>"
80
79
  And reorder records by "<reorder>"
81
80
  Then total records should be "<count>"
82
- And "first" record should have "<first>"
83
- And "last" record should have "<last>"
81
+ And "first" record should have "<first identifier>"
82
+ And "last" record should have "<last identifier>"
84
83
 
85
- Scenarios:
86
- | order | reorder | count | first | last |
84
+ Scenarios: order conditions
85
+ | order | reorder | count | first identifier | last identifier |
87
86
  | title | name title | 3 | code=[integer:1] | code=[integer:3] |
88
87
  | name | title name | 3 | code=[integer:3] | code=[integer:1] |
88
+
89
+ Scenario: reverse order
90
+ Given create "Product" model with attributes as "hashes":
91
+ | code | title |
92
+ | [integer:1] | [string:a] |
93
+ | [integer:2] | [string:b] |
94
+ | [integer:3] | [string:c] |
95
+ When order "Product" records by "title"
96
+ And reverse order records
97
+ Then total records should be "3"
98
+ And "first" record should have "code=[integer:3]"
99
+ And "last" record should have "code=[integer:1]"
@@ -1,51 +1,50 @@
1
1
  Feature: select concrete attributes
2
- When select hydra attribute
3
- Then hydra attribute table should be joined and concrete attribute should be selected
2
+ When select concrete attribute
3
+ Then model should response only to these attributes
4
4
 
5
- Background: create models and describe hydra attributes
6
- Given create model class "Product"
7
- And create model class "SimpleProduct" as "Product" with hydra attributes:
8
- | type | name |
9
- | integer | code |
10
- | float | price |
11
- | string | title |
12
- | text | note |
13
- | boolean | active |
14
- | datetime | schedule |
15
- And create models:
16
- | model | attributes |
17
- | SimpleProduct | name=[string:a] code=[integer:1] price=[float:4] title=[string:q] note=[string:z] active=[boolean:true] schedule=[datetime:2012-06-01] |
18
- | SimpleProduct | name=[string:b] code=[integer:2] price=[float:5] title=[string:w] note=[string:x] active=[boolean:false] schedule=[datetime:2012-06-02] |
19
- | SimpleProduct | name=[string:c] code=[integer:3] price=[float:6] note=[string:c] active=[boolean:true] schedule=[datetime:2012-06-03] |
20
- | SimpleProduct | name=[string:d] code=[nil:] price=[float:7] note=[string:v] active=[boolean:false] schedule=[datetime:2012-06-04] |
5
+ Background: create hydra attributes
6
+ Given create "HydraAttribute::HydraAttribute" models with attributes as "hashes":
7
+ | entity_type | name | backend_type |
8
+ | Product | code | integer |
9
+ | Product | price | float |
10
+ | Product | title | string |
11
+ | Product | note | text |
12
+ | Product | active | boolean |
13
+ | Product | schedule | datetime |
14
+ And create "Product" model with attributes as "hashes":
15
+ | name | code | price | title | note | active | schedule |
16
+ | [string:a] | [integer:1] | [float:4] | [string:q] | [string:z] | [boolean:true] | [datetime:2012-06-01] |
17
+ | [string:b] | [integer:2] | [float:5] | [string:w] | [string:x] | [boolean:false] | [datetime:2012-06-02] |
18
+ | [string:c] | [integer:3] | [float:6] | | [string:c] | [boolean:true] | [datetime:2012-06-03] |
19
+ | [string:d] | [nil:] | [float:7] | | [string:v] | [boolean:false] | [datetime:2012-06-04] |
21
20
 
22
21
  Scenario Outline: select concrete attributes
23
- When "SimpleProduct" select only the following columns "<columns>"
24
- Then records should have only the following "<columns>" names
22
+ When "Product" select only the following columns "<selected columns>"
23
+ Then records should have only the following "<expected columns>" names
25
24
  And records should raise "ActiveModel::MissingAttributeError" when call the following "<methods>"
26
25
  And total records should be "4"
27
26
 
28
- Scenarios: select attributes
29
- | columns | methods |
30
- | name | code price title note active schedule |
31
- | name code | price title note active schedule |
32
- | name code price | title note active schedule |
33
- | code price title | name note active schedule |
34
- | title note active | name code price schedule |
35
- | schedule | name code price title note active |
36
- | id schedule | name code price title note active |
27
+ Scenarios: select attributes
28
+ | selected columns | expected columns | methods |
29
+ | name | name | code price title note active schedule |
30
+ | name code | id name code | price title note active schedule |
31
+ | name code price | id name code price | title note active schedule |
32
+ | code price title | id code price title | name note active schedule |
33
+ | title note active | id title note active | name code price schedule |
34
+ | schedule | id schedule | name code price title note active |
35
+ | id schedule | id schedule | name code price title note active |
37
36
 
38
37
  Scenario Outline: filter collection and select concrete attributes
39
- When "SimpleProduct" select only the following columns "<columns>"
38
+ When "Product" select only the following columns "<selected columns>"
40
39
  And filter records by "<filter attributes>"
41
- Then records should have only the following "<columns>" names
40
+ Then records should have only the following "<expected columns>" names
42
41
  And records should raise "ActiveModel::MissingAttributeError" when call the following "<methods>"
43
42
  And total records should be "<total>"
44
43
 
45
44
  Scenarios: filter and select attributes
46
- | columns | filter attributes | methods | total |
47
- | name code | name=[string:a] | price title note active schedule | 1 |
48
- | code | code=[integer:1] | name price title note active schedule | 1 |
49
- | name code | code=[integer:1] | price title note active schedule | 1 |
50
- | code title | title=[nil:] | name price note active schedule | 2 |
51
- | code note | title=[nil:] | name price title active schedule | 2 |
45
+ | selected columns | expected columns | filter attributes | methods | total |
46
+ | name code | id name code | name=[string:a] | price title note active schedule | 1 |
47
+ | code | id code | code=[integer:1] | name price title note active schedule | 1 |
48
+ | name code | id name code | code=[integer:1] | price title note active schedule | 1 |
49
+ | code title | id code title | title=[nil:] | name price note active schedule | 2 |
50
+ | code note | id code note | title=[nil:] | name price title active schedule | 2 |