rom-rails 0.2.1 → 0.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +26 -0
  3. data/CHANGELOG.md +17 -0
  4. data/README.md +4 -0
  5. data/lib/generators/rom/commands/templates/create.rb.erb +10 -0
  6. data/lib/generators/rom/commands/templates/delete.rb.erb +7 -0
  7. data/lib/generators/rom/commands/templates/update.rb.erb +10 -0
  8. data/lib/generators/rom/commands_generator.rb +33 -5
  9. data/lib/generators/rom/form/templates/edit_form.rb.erb +24 -0
  10. data/lib/generators/rom/form/templates/new_form.rb.erb +24 -0
  11. data/lib/generators/rom/form_generator.rb +39 -0
  12. data/lib/generators/rom/mapper/templates/mapper.rb.erb +9 -11
  13. data/lib/generators/rom/mapper_generator.rb +11 -1
  14. data/lib/generators/rom/relation/templates/relation.rb.erb +3 -2
  15. data/lib/generators/rom/relation_generator.rb +16 -1
  16. data/lib/rom-rails.rb +0 -5
  17. data/lib/rom/model.rb +7 -90
  18. data/lib/rom/rails/active_record/configuration.rb +105 -0
  19. data/lib/rom/rails/configuration.rb +4 -27
  20. data/lib/rom/rails/model/form.rb +59 -0
  21. data/lib/rom/rails/model/form/dsl.rb +173 -0
  22. data/lib/rom/rails/model/params.rb +72 -0
  23. data/lib/rom/rails/model/validator.rb +74 -0
  24. data/lib/rom/rails/model/validator/uniqueness_validator.rb +39 -0
  25. data/lib/rom/rails/railtie.rb +65 -29
  26. data/lib/rom/rails/version.rb +1 -1
  27. data/rom-rails.gemspec +3 -1
  28. data/spec/dummy/app/commands/tasks.rb +5 -0
  29. data/spec/dummy/app/commands/users.rb +4 -10
  30. data/spec/dummy/app/controllers/users_controller.rb +30 -0
  31. data/spec/dummy/app/forms/new_user_form.rb +9 -0
  32. data/spec/dummy/app/forms/update_user_form.rb +9 -0
  33. data/spec/dummy/app/forms/user_form.rb +15 -0
  34. data/spec/dummy/app/mappers/users.rb +6 -6
  35. data/spec/dummy/app/relations/tasks.rb +9 -0
  36. data/spec/dummy/app/relations/users.rb +5 -1
  37. data/spec/dummy/app/views/users/edit.html.erb +6 -0
  38. data/spec/dummy/app/views/users/new.html.erb +6 -0
  39. data/spec/dummy/config/routes.rb +5 -1
  40. data/spec/dummy/db/migrate/20141110205016_add_users.rb +2 -0
  41. data/spec/dummy/db/migrate/20150202194440_create_tasks.rb +7 -0
  42. data/spec/dummy/db/schema.rb +8 -8
  43. data/spec/dummy/spec/features/users_spec.rb +30 -0
  44. data/spec/dummy/spec/integration/logger_spec.rb +1 -1
  45. data/spec/dummy/spec/integration/user_commands_spec.rb +2 -18
  46. data/spec/dummy/spec/integration/user_model_mapping_spec.rb +2 -2
  47. data/spec/dummy/spec/integration/user_params_spec.rb +30 -15
  48. data/spec/lib/active_record/configuration_spec.rb +98 -0
  49. data/spec/lib/generators/commands_generator_spec.rb +54 -14
  50. data/spec/lib/generators/form_generator_spec.rb +89 -0
  51. data/spec/lib/generators/mapper_generator_spec.rb +10 -12
  52. data/spec/lib/generators/relation_generator_spec.rb +16 -6
  53. data/spec/spec_helper.rb +1 -1
  54. data/spec/unit/form_spec.rb +297 -0
  55. data/spec/unit/{model_spec.rb → params_spec.rb} +0 -0
  56. data/spec/unit/validator_spec.rb +75 -0
  57. metadata +72 -20
  58. data/lib/generators/rom/commands/templates/commands.rb.erb +0 -15
  59. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  60. data/spec/dummy/app/params/user_params.rb +0 -7
  61. data/spec/dummy/app/validators/user_validator.rb +0 -3
@@ -11,17 +11,17 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20141220203134) do
15
- create_table "cars", force: true do |_t|
16
- end
14
+ ActiveRecord::Schema.define(version: 20150202194440) do
17
15
 
18
- create_table "planes", force: true do |_t|
16
+ create_table "tasks", force: :cascade do |t|
17
+ t.string "title"
19
18
  end
20
19
 
21
- create_table "stuffs", force: true do |_t|
20
+ create_table "users", force: :cascade do |t|
21
+ t.string "name"
22
+ t.string "email"
23
+ t.datetime "created_at"
24
+ t.datetime "updated_at"
22
25
  end
23
26
 
24
- create_table "users", force: true do |t|
25
- t.string "name"
26
- end
27
27
  end
@@ -13,6 +13,36 @@ feature 'Users' do
13
13
  expect(page).to have_content('Joe')
14
14
  end
15
15
 
16
+ scenario 'I save a new user' do
17
+ visit '/users/new'
18
+
19
+ click_on 'Create User'
20
+ expect(page).to have_content("can't be blank")
21
+
22
+ find('#user_email').set('jade@doe.org')
23
+ find('#user_name').set('Jade')
24
+ click_on 'Create User'
25
+
26
+ expect(page).to have_content('Jade')
27
+ expect(page).to have_content('Jane')
28
+ expect(page).to have_content('Joe')
29
+ end
30
+
31
+ scenario 'I edit an existing user' do
32
+ jane = rom.relations.users.by_name('Jane').first
33
+ visit "/users/#{jane[:id]}/edit"
34
+
35
+ click_on 'Update User'
36
+ expect(page).to have_content("can't be blank")
37
+
38
+ find('#user_email').set('jane.doe@example.org')
39
+ find('#user_name').set('Jane Doe')
40
+ click_on 'Update User'
41
+
42
+ expect(page).to have_content('Jane Doe')
43
+ expect(page).to have_content('Joe')
44
+ end
45
+
16
46
  scenario 'I can search users' do
17
47
  visit '/users/search?name=Jane'
18
48
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'ROM logger' do
4
- let(:rom) { Rails.application.config.rom.env }
4
+ let(:rom) { ROM.env }
5
5
 
6
6
  it 'sets up rails logger for all repositories' do
7
7
  pending 'this will be re-enabled once we have feature detection on ' \
@@ -3,26 +3,10 @@ require 'spec_helper'
3
3
  describe 'User commands' do
4
4
  subject(:users) { rom.command(:users) }
5
5
 
6
- describe 'create' do
7
- it 'inserts user with valid params' do
8
- result = users.try { create(name: 'Jade') }
9
-
10
- expect(result.value).to eql(id: result.value[:id], name: 'Jade')
11
- end
12
-
13
- it 'returns error if params are not valid' do
14
- result = users.try { create(name: '') }
15
-
16
- expect(result.value).to be(nil)
17
- expect(result.error).to be_instance_of(ROM::Model::ValidationError)
18
- expect(result.error.messages[:name]).to include("can't be blank")
19
- end
20
- end
21
-
22
6
  describe 'delete' do
23
7
  it 'deletes record' do
24
- users.create.call(name: 'Piotr')
25
- result = users.try { delete(:by_name, 'Piotr') }
8
+ rom.relations.users.insert(name: 'Piotr', email: 'piotr@test.com')
9
+ result = users.try { users.delete.by_name('Piotr') }
26
10
 
27
11
  expect(result.error).to be(nil)
28
12
  end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'User model mapping' do
4
- let(:rom) { Rails.application.config.rom.env }
4
+ let(:rom) { ROM.env }
5
5
 
6
6
  let(:users) { rom.read(:users) }
7
7
 
8
8
  before do
9
- rom.command(:users).try { create(name: 'Piotr') }
9
+ rom.relations.users.insert(name: 'Piotr', email: 'piotr@test.com')
10
10
  end
11
11
 
12
12
  it 'works' do
@@ -5,29 +5,44 @@ describe ROM::Model::Params do
5
5
  Class.new do
6
6
  include ROM::Model::Params
7
7
 
8
- param_key :test
9
8
  attribute :name, String
10
- validates :name, presence: true
11
9
 
12
- def self.name
13
- 'Test'
14
- end
10
+ timestamps
15
11
  end
16
12
  end
17
13
 
18
- describe '#valid?' do
19
- it 'returns true when attributes are valid' do
20
- user_params = params.new(name: 'Jane')
21
- expect(user_params).to be_valid
14
+ describe '.timestamps' do
15
+ it 'provides a way to specify timestamps with default values' do
16
+ expect(params.new.created_at).to be_a(DateTime)
17
+ expect(params.new.updated_at).to be_a(DateTime)
22
18
  end
23
19
 
24
- it 'returns false when attributes are not valid' do
25
- user_params = params.new(name: '')
26
- expect(user_params).not_to be_valid
27
- end
20
+ context 'passing in arbritrary names' do
21
+ it 'excludes :created_at when passing in :updated_at' do
22
+ params = Class.new {
23
+ include ROM::Model::Params
24
+
25
+ timestamps(:updated_at)
26
+ }
27
+
28
+ model = params.new
29
+
30
+ expect(model).not_to respond_to(:created_at)
31
+ expect(model).to respond_to(:updated_at)
32
+ end
33
+
34
+ it 'accepts multiple timestamp attribute names' do
35
+ params = Class.new {
36
+ include ROM::Model::Params
37
+
38
+ timestamps(:published_at, :revised_at)
39
+ }
28
40
 
29
- it 'sets up AM name' do
30
- expect(params.model_name.param_key).to eql('test')
41
+ model = params.new
42
+
43
+ expect(model).to respond_to(:published_at)
44
+ expect(model).to respond_to(:revised_at)
45
+ end
31
46
  end
32
47
  end
33
48
  end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'rom/rails/active_record/configuration'
3
+
4
+ describe ROM::Rails::ActiveRecord::Configuration do
5
+ let(:root) { Pathname.new('/path/to/app') }
6
+
7
+ def uri_for(config)
8
+ result = read(config)
9
+ result.is_a?(Hash) ? result[:uri] : result
10
+ end
11
+
12
+ def read(config)
13
+ described_class.build(config.merge(root: root))
14
+ end
15
+
16
+ def parse(uri)
17
+ URI.parse(uri.gsub(/^jdbc:/, ''))
18
+ end
19
+
20
+ it 'raises an error without specifying a database'
21
+
22
+ context 'with postgresql adapter' do
23
+ it 'rewrites the scheme' do
24
+ uri = uri_for(adapter: 'postgresql', database: 'test')
25
+ expect(parse(uri).scheme).to eql('postgres')
26
+ end
27
+
28
+ it 'does not use jdbc even on jruby' do
29
+ uri = uri_for(adapter: 'postgresql', database: 'test')
30
+ expect(uri).to_not start_with('jdbc:')
31
+ end
32
+
33
+ it 'only includes username if no password is given' do
34
+ uri = uri_for(
35
+ adapter: 'postgresql',
36
+ host: 'example.com',
37
+ database: 'test',
38
+ username: 'user'
39
+ )
40
+
41
+ expect(parse(uri).userinfo).to eql('user')
42
+ end
43
+
44
+ it 'includes username and password if both are given' do
45
+ uri = uri_for(
46
+ adapter: 'postgresql',
47
+ database: 'test',
48
+ username: 'user',
49
+ password: 'password',
50
+ host: 'example.com'
51
+ )
52
+
53
+ expect(parse(uri).userinfo).to eql('user:password')
54
+ end
55
+
56
+ it 'omits userinfo if neither username nor password are given' do
57
+ uri = uri_for(adapter: 'postgresql', database: 'test')
58
+ expect(parse(uri).userinfo).to be_nil
59
+ end
60
+
61
+ it 'properly handles configuration without a host' do
62
+ uri = uri_for(adapter: 'postgresql', database: 'test')
63
+ expect(uri).to eql('postgres:///test')
64
+ end
65
+ end
66
+
67
+ context 'with mysql adapter' do
68
+ it 'sets default password to an empty string' do
69
+ uri = uri_for(adapter: 'mysql', database: 'test', username: 'root', host: 'example.com')
70
+ expect(parse(uri).userinfo).to eql('root:')
71
+ end
72
+
73
+ it 'uses jdbc only on jruby' do
74
+ uri = uri_for(adapter: 'mysql', database: 'test')
75
+ expect(uri.starts_with?('jdbc:')).to be(RUBY_ENGINE == 'jruby')
76
+ end
77
+ end
78
+
79
+ context 'with sqlite3 adapter' do
80
+ let(:database) { Pathname.new('db/development.sqlite3') }
81
+ let(:config) { { adapter: adapter, database: database } }
82
+
83
+ it 'rewrites the scheme' do
84
+ uri = uri_for(adapter: 'sqlite3', database: database)
85
+ expect(parse(uri).scheme).to eql('sqlite')
86
+ end
87
+
88
+ it 'uses jdbc only on jruby' do
89
+ uri = uri_for(adapter: 'sqlite3', database: database)
90
+ expect(uri.starts_with?('jdbc:')).to be(RUBY_ENGINE == 'jruby')
91
+ end
92
+
93
+ it 'expands the path' do
94
+ uri = uri_for(adapter: 'sqlite3', database: database)
95
+ expect(parse(uri).path).to eql(root.join(database).to_s)
96
+ end
97
+ end
98
+ end
@@ -5,36 +5,76 @@ require 'generators/rom/commands_generator'
5
5
  describe ROM::Generators::CommandsGenerator do
6
6
  destination File.expand_path('../../../../tmp', __FILE__)
7
7
 
8
- before(:all) do
8
+ before(:each) do
9
9
  prepare_destination
10
- run_generator ['users']
11
10
  end
12
11
 
13
12
  specify do
13
+ run_generator ['users']
14
+
15
+ default_adapter = ROM.adapters.keys.first
16
+
14
17
  expect(destination_root).to have_structure {
15
18
  directory 'app' do
16
19
  directory 'commands' do
17
- file 'users.rb' do
18
- contains <<-CONTENT.strip_heredoc
19
- ROM.commands(:users) do
20
+ directory 'users' do
21
+ file 'create.rb' do
22
+ contains <<-CONTENT.strip_heredoc
23
+ module UserCommands
24
+ class Create < ROM::Commands::Create[:#{default_adapter}]
25
+ relation :users
26
+ register_as :create
27
+ result :one
20
28
 
21
- define(:create) do
22
- result :one
29
+ # define a validator to use
30
+ # validator UserValidator
31
+ end
23
32
  end
33
+ CONTENT
34
+ end
24
35
 
25
- define(:update) do
26
- result :one
27
- end
36
+ file 'update.rb' do
37
+ contains <<-CONTENT.strip_heredoc
38
+ module UserCommands
39
+ class Update < ROM::Commands::Update[:#{default_adapter}]
40
+ relation :users
41
+ register_as :update
42
+ result :one
28
43
 
29
- define(:delete) do
30
- result :one
44
+ # define a validator to use
45
+ # validator UserValidator
46
+ end
31
47
  end
48
+ CONTENT
49
+ end
32
50
 
33
- end
34
- CONTENT
51
+ file 'delete.rb' do
52
+ contains <<-CONTENT.strip_heredoc
53
+ module UserCommands
54
+ class Delete < ROM::Commands::Delete[:#{default_adapter}]
55
+ relation :users
56
+ register_as :delete
57
+ result :one
58
+ end
59
+ end
60
+ CONTENT
61
+ end
35
62
  end
36
63
  end
37
64
  end
38
65
  }
39
66
  end
67
+
68
+ specify "with given adapter" do
69
+ run_generator ['users', '--adapter=memory']
70
+
71
+ create = File.read(File.join(destination_root, 'app', 'commands', 'users', 'create.rb'))
72
+ expect(create).to include("class Create < ROM::Commands::Create[:memory]")
73
+
74
+ update = File.read(File.join(destination_root, 'app', 'commands', 'users', 'update.rb'))
75
+ expect(update).to include("class Update < ROM::Commands::Update[:memory]")
76
+
77
+ delete = File.read(File.join(destination_root, 'app', 'commands', 'users', 'delete.rb'))
78
+ expect(delete).to include("class Delete < ROM::Commands::Delete[:memory]")
79
+ end
40
80
  end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ require 'generators/rom/form_generator'
4
+
5
+ describe ROM::Generators::FormGenerator do
6
+ destination File.expand_path('../../../../tmp', __FILE__)
7
+
8
+ before(:each) do
9
+ prepare_destination
10
+ end
11
+
12
+ specify "a create form" do
13
+ run_generator ['users', '--command=create']
14
+
15
+ expect(destination_root).to have_structure {
16
+ directory 'app' do
17
+ directory 'forms' do
18
+ file 'new_user_form.rb' do
19
+ contains <<-CONTENT.strip_heredoc
20
+ class NewUserForm < ROM::Model::Form
21
+ commands users: :create
22
+
23
+ input do
24
+ set_model_name 'User'
25
+
26
+ # define form input attributes
27
+ # attribute :name, String
28
+
29
+ timestamps
30
+ end
31
+
32
+ validations do
33
+ relation :users
34
+
35
+ # Add form validations
36
+ # validates :name, presence: true
37
+ end
38
+
39
+ def commit!
40
+ users.try { users.create.call(params) }
41
+ end
42
+
43
+ end
44
+ CONTENT
45
+ end
46
+ end
47
+ end
48
+ }
49
+ end
50
+
51
+ specify "an edit form" do
52
+ run_generator ['users', '--command=update']
53
+
54
+ expect(destination_root).to have_structure {
55
+ directory 'app' do
56
+ directory 'forms' do
57
+ file 'edit_user_form.rb' do
58
+ contains <<-CONTENT.strip_heredoc
59
+ class EditUserForm < ROM::Model::Form
60
+ commands users: :update
61
+
62
+ input do
63
+ set_model_name 'User'
64
+
65
+ # define form input attributes
66
+ # attribute :name, String
67
+
68
+ timestamps :updated_at
69
+ end
70
+
71
+ validations do
72
+ relation :users
73
+
74
+ # Add form validations
75
+ # validates :name, presence: true
76
+ end
77
+
78
+ def commit!
79
+ users.try { users.update.by_id(id).set(params) }
80
+ end
81
+
82
+ end
83
+ CONTENT
84
+ end
85
+ end
86
+ end
87
+ }
88
+ end
89
+ end