netzke-basepack 0.7.4 → 0.7.5

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 (74) hide show
  1. data/.travis.yml +11 -0
  2. data/CHANGELOG.rdoc +10 -0
  3. data/README.md +36 -2
  4. data/Rakefile +1 -3
  5. data/config/ci/before-travis.sh +28 -0
  6. data/lib/netzke/active_record.rb +10 -8
  7. data/lib/netzke/active_record/attributes.rb +28 -17
  8. data/lib/netzke/active_record/relation_extensions.rb +3 -1
  9. data/lib/netzke/basepack.rb +10 -2
  10. data/lib/netzke/basepack/action_column.rb +6 -8
  11. data/lib/netzke/basepack/data_accessor.rb +11 -174
  12. data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +164 -0
  13. data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +279 -0
  14. data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +264 -0
  15. data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +260 -0
  16. data/lib/netzke/basepack/form_panel.rb +3 -3
  17. data/lib/netzke/basepack/form_panel/fields.rb +6 -10
  18. data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +1 -0
  19. data/lib/netzke/basepack/form_panel/services.rb +15 -16
  20. data/lib/netzke/basepack/grid_panel.rb +16 -10
  21. data/lib/netzke/basepack/grid_panel/columns.rb +6 -7
  22. data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +29 -27
  23. data/lib/netzke/basepack/grid_panel/services.rb +13 -90
  24. data/lib/netzke/basepack/paging_form_panel.rb +3 -3
  25. data/lib/netzke/basepack/query_builder.rb +2 -0
  26. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +29 -19
  27. data/lib/netzke/basepack/search_panel.rb +6 -3
  28. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +2 -1
  29. data/lib/netzke/basepack/search_window.rb +2 -1
  30. data/lib/netzke/basepack/version.rb +1 -1
  31. data/lib/netzke/data_mapper.rb +18 -0
  32. data/lib/netzke/data_mapper/attributes.rb +273 -0
  33. data/lib/netzke/data_mapper/combobox_options.rb +11 -0
  34. data/lib/netzke/data_mapper/relation_extensions.rb +38 -0
  35. data/lib/netzke/sequel.rb +18 -0
  36. data/lib/netzke/sequel/attributes.rb +274 -0
  37. data/lib/netzke/sequel/combobox_options.rb +10 -0
  38. data/lib/netzke/sequel/relation_extensions.rb +40 -0
  39. data/netzke-basepack.gemspec +24 -13
  40. data/test/basepack_test_app/Gemfile +33 -8
  41. data/test/basepack_test_app/Gemfile.lock +98 -79
  42. data/test/basepack_test_app/Guardfile +46 -0
  43. data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +3 -0
  44. data/test/basepack_test_app/app/components/extras/book_presentation.rb +10 -3
  45. data/test/basepack_test_app/app/models/address.rb +27 -1
  46. data/test/basepack_test_app/app/models/author.rb +28 -0
  47. data/test/basepack_test_app/app/models/book.rb +43 -0
  48. data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +22 -0
  49. data/test/basepack_test_app/app/models/role.rb +21 -0
  50. data/test/basepack_test_app/app/models/user.rb +24 -0
  51. data/test/basepack_test_app/config/database.yml.sample +11 -10
  52. data/test/basepack_test_app/config/database.yml.travis +15 -0
  53. data/test/basepack_test_app/config/initializers/data_mapper_logging.rb +3 -0
  54. data/test/basepack_test_app/config/initializers/sequel.rb +26 -0
  55. data/test/basepack_test_app/db/schema.rb +0 -3
  56. data/test/basepack_test_app/features/grid_panel.feature +28 -8
  57. data/test/basepack_test_app/features/grid_sorting.feature +6 -6
  58. data/test/basepack_test_app/features/paging_form_panel.feature +13 -13
  59. data/test/basepack_test_app/features/search_in_grid.feature +31 -31
  60. data/test/basepack_test_app/features/step_definitions/generic_steps.rb +3 -1
  61. data/test/basepack_test_app/features/support/env.rb +17 -4
  62. data/test/basepack_test_app/lib/tasks/travis.rake +7 -0
  63. data/test/basepack_test_app/spec/components/form_panel_spec.rb +2 -2
  64. data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +68 -0
  65. data/test/basepack_test_app/spec/{active_record → data_adapter}/attributes_spec.rb +12 -4
  66. data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +125 -0
  67. data/test/basepack_test_app/spec/spec_helper.rb +9 -0
  68. data/test/unit/active_record_basepack_test.rb +1 -1
  69. data/test/unit/grid_panel_test.rb +1 -1
  70. metadata +26 -31
  71. data/app/models/netzke_field_list.rb +0 -261
  72. data/app/models/netzke_model_attr_list.rb +0 -21
  73. data/app/models/netzke_persistent_array_auto_model.rb +0 -57
  74. data/test/basepack_test_app/spec/active_record/relation_extensions_spec.rb +0 -44
@@ -0,0 +1,46 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'bundler' do
5
+ watch('Gemfile')
6
+ # Uncomment next line if Gemfile contain `gemspec' command
7
+ # watch(/^.+\.gemspec/)
8
+ end
9
+
10
+ guard 'rails' do
11
+ watch('Gemfile.lock')
12
+ watch(%r{^(config|lib)/.*})
13
+ end
14
+
15
+
16
+ guard 'livereload' do
17
+ watch(%r{app/.+\.(erb|haml)})
18
+ watch(%r{app/helpers/.+\.rb})
19
+ watch(%r{(public/|app/assets).+\.(css|js|html)})
20
+ watch(%r{(app/assets/.+\.css)\.s[ac]ss}) { |m| m[1] }
21
+ watch(%r{(app/assets/.+\.js)\.coffee}) { |m| m[1] }
22
+ watch(%r{config/locales/.+\.yml})
23
+ end
24
+
25
+ guard 'rspec', :version => 2, :cli => '--color' do
26
+ watch(%r{^spec/.+_spec\.rb$})
27
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
28
+ watch('spec/spec_helper.rb') { "spec" }
29
+
30
+ # Rails example
31
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
32
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
33
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
34
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
35
+ watch('config/routes.rb') { "spec/routing" }
36
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
37
+ # Capybara request specs
38
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
39
+ end
40
+
41
+
42
+ guard 'cucumber' do
43
+ watch(%r{^features/.+\.feature$})
44
+ watch(%r{^features/support/.+$}) { 'features' }
45
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
46
+ end
@@ -1,4 +1,7 @@
1
1
  class BookGridWithPersistence < BookGrid
2
+
3
+ override_column :author__name, :included => false
4
+
2
5
  def default_config
3
6
  super.merge :persistence => true
4
7
  end
@@ -3,10 +3,17 @@ module Extras
3
3
  # A setter that creates an author on the fly
4
4
  def author_first_name_setter
5
5
  lambda do |r,v|
6
+
7
+ data_adapter = Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(Author).new(Author)
8
+ # cast v to integer, if possible
9
+ v = v.to_i if v.kind_of?(String) && v.match(/[[:digit:]]+/)
6
10
  if v.is_a?(Integer)
7
- r.author = Author.find(v)
11
+ r.author = data_adapter.find_record(v)
8
12
  else
9
- r.author = Author.create(:first_name => v)
13
+ author = data_adapter.new_record(:first_name => v)
14
+ # Sequel doesn't know of save!
15
+ author.respond_to?(:save!) ? author.save! : author.save(:raise_on_save_failure => true)
16
+ r.author = author
10
17
  end
11
18
  end
12
19
  end
@@ -17,4 +24,4 @@ module Extras
17
24
  end
18
25
 
19
26
  end
20
- end
27
+ end
@@ -1,3 +1,29 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class Address
4
+ include DataMapper::Resource
5
+ property :id, Serial
6
+ belongs_to :user
7
+ property :street, String
8
+ property :city, String
9
+ property :postcode, String
10
+ property :created_at, DateTime
11
+ property :updated_at, DateTime
12
+ end
13
+
14
+ elsif defined? Sequel::Model
15
+
16
+ class Address < Sequel::Model
17
+ # although this is one_to_one, according to Sequel docs,
18
+ # the model containing the foreign key should have many_to_one
19
+ # and the other model should have one_to_one
20
+ many_to_one :user
21
+ end
22
+
23
+ else
24
+
1
25
  class Address < ActiveRecord::Base
2
26
  belongs_to :user
3
- end
27
+ end
28
+
29
+ end
@@ -1,5 +1,32 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class Author
4
+ include DataMapper::Resource
5
+ property :id, Serial
6
+ property :first_name, String
7
+ property :last_name, String
8
+ property :created_at, DateTime
9
+ property :updated_at, DateTime
10
+ has n, :books
11
+ end
12
+
13
+
14
+ elsif defined? Sequel::Model
15
+
16
+ class Author < Sequel::Model
17
+ one_to_many :books
18
+ end
19
+
20
+ else
21
+
1
22
  class Author < ActiveRecord::Base
2
23
  has_many :books
24
+ end
25
+
26
+ end
27
+
28
+ # ORM-agnostic bits
29
+ class Author
3
30
 
4
31
  # virtual attribute
5
32
  def name
@@ -7,4 +34,5 @@ class Author < ActiveRecord::Base
7
34
  end
8
35
 
9
36
  netzke_attribute :name
37
+
10
38
  end
@@ -1,6 +1,49 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class Book
4
+ include DataMapper::Resource
5
+ property :id, Serial
6
+ belongs_to :author, :required => false
7
+ validates_presence_of :title, :message => "Title can't be blank"
8
+ property :title, String
9
+ property :exemplars, Integer
10
+ property :digitized, Boolean
11
+ property :notes, Text
12
+ property :tags, String
13
+ property :rating, Integer
14
+ property :created_at, DateTime
15
+ property :updated_at, DateTime
16
+ property :last_read_at, DateTime
17
+ property :published_on, Date
18
+
19
+ def self.sorted_by_author_name dir
20
+ all :order => [ author.last_name.send(dir), author.first_name.send(dir) ], :links => [ relationships[:author].inverse ]
21
+ end
22
+
23
+ end
24
+
25
+ elsif defined? Sequel::Model
26
+
27
+ class Book < Sequel::Model
28
+ many_to_one :author
29
+
30
+ def_dataset_method(:sorted_by_author_name) do |dir|
31
+ eager_graph(:author).order_append(:author__last_name.send(dir), :author__first_name.send(dir))
32
+ end
33
+
34
+ def validate
35
+ validates_presence :title, :message => "can't be blank"
36
+ end
37
+
38
+ end
39
+
40
+ else
41
+
1
42
  class Book < ActiveRecord::Base
2
43
  belongs_to :author
3
44
  validates_presence_of :title
4
45
 
5
46
  scope :sorted_by_author_name, lambda { |dir| joins(:author).order("authors.last_name #{dir}, authors.first_name #{dir}") }
6
47
  end
48
+
49
+ end
@@ -1,4 +1,26 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class BookWithCustomPrimaryKey
4
+ include DataMapper::Resource
5
+ property :uid, Serial
6
+ belongs_to :author
7
+ property :title, String
8
+ property :created_at, DateTime
9
+ property :updated_at, DateTime
10
+ end
11
+
12
+ elsif defined? Sequel::Model
13
+
14
+ class BookWithCustomPrimaryKey < Sequel::Model
15
+ set_primary_key :uid
16
+ many_to_one :author
17
+ end
18
+
19
+ else
20
+
1
21
  class BookWithCustomPrimaryKey < ActiveRecord::Base
2
22
  set_primary_key 'uid'
3
23
  belongs_to :author
4
24
  end
25
+
26
+ end
@@ -1,3 +1,24 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class Role
4
+ include DataMapper::Resource
5
+ property :id, Serial
6
+ property :name, String
7
+ has n, :users
8
+ property :created_at, DateTime
9
+ property :updated_at, DateTime
10
+ end
11
+
12
+ elsif defined? Sequel::Model
13
+
14
+ class Role < Sequel::Model
15
+ one_to_many :users
16
+ end
17
+
18
+ else
19
+
1
20
  class Role < ActiveRecord::Base
2
21
  has_many :users
3
22
  end
23
+
24
+ end
@@ -1,5 +1,29 @@
1
+ if defined? DataMapper::Resource
2
+
3
+ class User
4
+ include DataMapper::Resource
5
+ property :id, Serial
6
+ property :first_name, String
7
+ property :last_name, String
8
+ belongs_to :role, :required => false
9
+ has 1, :address
10
+ property :created_at, DateTime
11
+ property :updated_at, DateTime
12
+ end
13
+
14
+ elsif defined? Sequel::Model
15
+
16
+ class User < Sequel::Model
17
+ many_to_one :role
18
+ one_to_one :address
19
+ end
20
+
21
+ else
22
+
1
23
  class User < ActiveRecord::Base
2
24
  # scope :latest, lambda {|param| where(:created_at.gt => param)}
3
25
  belongs_to :role
4
26
  has_one :address
5
27
  end
28
+
29
+ end
@@ -1,4 +1,4 @@
1
- development:
1
+ development: &development
2
2
  adapter: mysql2
3
3
  encoding: utf8
4
4
  reconnect: false
@@ -6,16 +6,13 @@ development:
6
6
  pool: 5
7
7
  username: root
8
8
  password:
9
- socket: /tmp/mysql.sock
9
+ socket: <%= ["/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysqld.sock", "/tmp/mysql.sock", "/var/run/mysqld/mysqld.sock", "/var/lib/mysql/mysql.sock"].detect{ |socket| File.exist?(socket) } %>
10
+ # DM
11
+ uri: mysql://localhost/nbt_development?user=root&encoding=UTF-8
10
12
 
11
13
  # Warning: The database defined as "test" will be erased and
12
14
  # re-generated from your development database when you run "rake".
13
15
  # Do not set this db to the same as development or production.
14
- # test:
15
- # adapter: sqlite3
16
- # database: db/test.sqlite3
17
- # pool: 5
18
- # timeout: 5000
19
16
  test: &test
20
17
  adapter: mysql2
21
18
  encoding: utf8
@@ -24,7 +21,9 @@ test: &test
24
21
  pool: 5
25
22
  username: root
26
23
  password:
27
- socket: /tmp/mysql.sock
24
+ socket: <%= ["/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysqld.sock", "/tmp/mysql.sock", "/var/run/mysqld/mysqld.sock", "/var/lib/mysql/mysql.sock"].detect{ |socket| File.exist?(socket) } %>
25
+ # DM
26
+ uri: mysql://localhost/nbt_test?user=root&encoding=UTF-8
28
27
 
29
28
  production:
30
29
  adapter: mysql2
@@ -34,7 +33,9 @@ production:
34
33
  pool: 5
35
34
  username: root
36
35
  password:
37
- socket: /tmp/mysql.sock
36
+ socket: <%= ["/opt/local/var/run/mysql5/mysqld.sock", "/tmp/mysqld.sock", "/tmp/mysql.sock", "/var/run/mysqld/mysqld.sock", "/var/lib/mysql/mysql.sock"].detect{ |socket| File.exist?(socket) } %>
37
+ # DM
38
+ uri: mysql://localhost/nbt_production?user=root&encoding=UTF-8
38
39
 
39
40
  cucumber:
40
- <<: *test
41
+ <<: *test
@@ -0,0 +1,15 @@
1
+ # Warning: The database defined as "test" will be erased and
2
+ # re-generated from your development database when you run "rake".
3
+ # Do not set this db to the same as development or production.
4
+ test: &test
5
+ adapter: mysql2
6
+ encoding: utf8
7
+ reconnect: false
8
+ database: nbt_test
9
+ pool: 5
10
+ username:
11
+ # DM
12
+ uri: mysql://127.0.0.1/nbt_test?user=&encoding=UTF-8
13
+
14
+ cucumber:
15
+ <<: *test
@@ -0,0 +1,3 @@
1
+ if defined?(DataMapper) && Rails.env.development?
2
+ DataMapper::Logger.new($stdout, :debug)
3
+ end
@@ -0,0 +1,26 @@
1
+ if defined? Sequel
2
+ Sequel::Model.plugin :active_model
3
+ Sequel::Model.plugin :validation_helpers
4
+ db = Sequel.connect(YAML.load(ERB.new(File.read(File.join(Rails.root,'config','database.yml'))).result)[Rails.env])
5
+ db.logger = Logger.new $stdout if Rails.env.development?
6
+
7
+ Sequel::Model.class_eval do
8
+ # Emulate ARs timestamp behavior
9
+ def before_create
10
+ self.created_at ||= Time.now
11
+ self.updated_at ||= Time.now
12
+ end
13
+
14
+ def before_update
15
+ self.updated_at ||= Time.now
16
+ end
17
+
18
+ # enable mass-assignment of pk, so that pickle scenarios can work properly when id is specified
19
+ unrestrict_primary_key
20
+
21
+ # FactoryGirl compatibility fix
22
+ def save!
23
+ save :raise_on_save_failure => true, :validate => false
24
+ end
25
+ end
26
+ end
@@ -64,9 +64,6 @@ ActiveRecord::Schema.define(:version => 20110909071740) do
64
64
  add_index "netzke_component_states", ["role_id"], :name => "index_netzke_component_states_on_role_id"
65
65
  add_index "netzke_component_states", ["user_id"], :name => "index_netzke_component_states_on_user_id"
66
66
 
67
- create_table "netzke_temp_table", :force => true do |t|
68
- end
69
-
70
67
  create_table "roles", :force => true do |t|
71
68
  t.string "name"
72
69
  t.datetime "created_at"
@@ -212,8 +212,9 @@ Scenario: Advanced search window should be hidable after loading grid panel dyna
212
212
  Scenario: Column order should be saved across page reloads
213
213
  Given I am on the BookGridWithPersistence test page
214
214
  When I drag "Digitized" column before "Title"
215
+ And I wait for the response from the server
215
216
  And I go to the BookGridWithPersistence test page
216
- Then I should see columns in order: "Author name", "Digitized", "Title"
217
+ Then I should see columns in order: "Digitized", "Title", "Exemplars"
217
218
 
218
219
  @javascript
219
220
  Scenario: I must see total records value
@@ -248,10 +249,29 @@ Scenario: GridPanel with overridden columns
248
249
  Then the grid's column "In abundance" should not be editable
249
250
 
250
251
  @javascript
251
- Scenario: Delete record via an column action
252
- Given a book exists with title: "Some Title"
253
- When I go to the BookGridWithColumnActions test page
254
- And I click the "Delete row" action icon
255
- And I press "Yes"
256
- Then I should see "Deleted 1 record(s)"
257
- And a book should not exist with title: "Some Title"
252
+ Scenario: Delete record via an column action
253
+ Given a book exists with title: "Some Title"
254
+ When I go to the BookGridWithColumnActions test page
255
+ And I click the "Delete row" action icon
256
+ And I press "Yes"
257
+ Then I should see "Deleted 1 record(s)"
258
+ And a book should not exist with title: "Some Title"
259
+
260
+ @javascript
261
+ Scenario: Pagination in grid panel
262
+ Given the following books exist:
263
+ | title |
264
+ | Journey to Ixtlan |
265
+ | Lolita |
266
+ | Getting Things Done |
267
+ | Magus |
268
+ When I go to the BookGridWithPaging test page
269
+ Then I should see "Journey to Ixtlan"
270
+ And I should see "Lolita"
271
+ But I should not see "Getting Things Done"
272
+ And the grid should show 2 records
273
+
274
+ When I go forward one page
275
+ And I wait for the response from the server
276
+ Then I should see "Getting Things Done"
277
+ And I should see "Magus"