rom 0.8.1 → 0.9.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +5 -1
  4. data/lib/rom.rb +35 -16
  5. data/lib/rom/command.rb +1 -9
  6. data/lib/rom/commands/graph/class_interface.rb +2 -2
  7. data/lib/rom/constants.rb +0 -6
  8. data/lib/rom/{env.rb → container.rb} +3 -3
  9. data/lib/rom/environment.rb +238 -0
  10. data/lib/rom/environment_plugin.rb +17 -0
  11. data/lib/rom/environment_plugins/auto_registration.rb +17 -0
  12. data/lib/rom/global.rb +0 -203
  13. data/lib/rom/mapper_registry.rb +2 -0
  14. data/lib/rom/pipeline.rb +2 -0
  15. data/lib/rom/plugin.rb +4 -18
  16. data/lib/rom/plugin_base.rb +31 -0
  17. data/lib/rom/plugin_registry.rb +54 -17
  18. data/lib/rom/relation.rb +54 -11
  19. data/lib/rom/relation/class_interface.rb +14 -21
  20. data/lib/rom/relation/curried.rb +36 -2
  21. data/lib/rom/relation/graph.rb +7 -0
  22. data/lib/rom/relation_registry.rb +4 -0
  23. data/lib/rom/setup.rb +9 -8
  24. data/lib/rom/setup/finalize.rb +5 -5
  25. data/lib/rom/version.rb +1 -1
  26. data/rom.gemspec +2 -0
  27. data/spec/integration/commands/create_spec.rb +1 -1
  28. data/spec/integration/commands/update_spec.rb +1 -1
  29. data/spec/integration/mappers/unwrap_spec.rb +1 -1
  30. data/spec/spec_helper.rb +2 -0
  31. data/spec/unit/rom/{env_spec.rb → container_spec.rb} +5 -5
  32. data/spec/unit/rom/plugin_spec.rb +0 -8
  33. data/spec/unit/rom/relation/composite_spec.rb +2 -2
  34. data/spec/unit/rom/relation/curried_spec.rb +53 -0
  35. data/spec/unit/rom/relation/graph_spec.rb +4 -0
  36. data/spec/unit/rom/relation/lazy/combine_spec.rb +6 -6
  37. data/spec/unit/rom/relation/lazy_spec.rb +4 -8
  38. data/spec/unit/rom/relation_spec.rb +0 -14
  39. data/spec/unit/rom/setup_spec.rb +1 -1
  40. metadata +52 -35
  41. data/lib/rom/header.rb +0 -193
  42. data/lib/rom/header/attribute.rb +0 -184
  43. data/lib/rom/mapper.rb +0 -103
  44. data/lib/rom/mapper/attribute_dsl.rb +0 -477
  45. data/lib/rom/mapper/dsl.rb +0 -119
  46. data/lib/rom/mapper/model_dsl.rb +0 -55
  47. data/lib/rom/model_builder.rb +0 -101
  48. data/lib/rom/processor.rb +0 -28
  49. data/lib/rom/processor/transproc.rb +0 -388
  50. data/lib/rom/relation/lazy.rb +0 -145
  51. data/lib/rom/support/array_dataset.rb +0 -41
  52. data/lib/rom/support/class_builder.rb +0 -44
  53. data/lib/rom/support/class_macros.rb +0 -56
  54. data/lib/rom/support/data_proxy.rb +0 -102
  55. data/lib/rom/support/deprecations.rb +0 -36
  56. data/lib/rom/support/enumerable_dataset.rb +0 -65
  57. data/lib/rom/support/inflector.rb +0 -73
  58. data/lib/rom/support/options.rb +0 -195
  59. data/lib/rom/support/registry.rb +0 -43
  60. data/spec/unit/rom/header_spec.rb +0 -102
  61. data/spec/unit/rom/mapper/dsl_spec.rb +0 -467
  62. data/spec/unit/rom/mapper_spec.rb +0 -84
  63. data/spec/unit/rom/model_builder_spec.rb +0 -46
  64. data/spec/unit/rom/processor/transproc_spec.rb +0 -448
  65. data/spec/unit/rom/support/array_dataset_spec.rb +0 -61
  66. data/spec/unit/rom/support/class_builder_spec.rb +0 -42
  67. data/spec/unit/rom/support/enumerable_dataset_spec.rb +0 -17
  68. data/spec/unit/rom/support/inflector_spec.rb +0 -89
  69. data/spec/unit/rom/support/options_spec.rb +0 -119
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'rom/support/array_dataset'
4
-
5
- describe ROM::ArrayDataset do
6
- let(:klass) do
7
- Class.new do
8
- include ROM::ArrayDataset
9
-
10
- def self.row_proc
11
- T(:symbolize_keys)
12
- end
13
- end
14
- end
15
-
16
- it_behaves_like 'an enumerable dataset' do
17
- describe '#flatten' do
18
- let(:data) { [[{ 'name' => 'Jane' }], [{ 'name' => 'Joe' }]] }
19
-
20
- it 'returns a new dataset with flattened data' do
21
- result = dataset.flatten
22
-
23
- expect(result).to match_array([{ name: 'Jane' }, { name: 'Joe' }])
24
- end
25
- end
26
-
27
- describe '#map!' do
28
- context 'with a block' do
29
- it 'returns a new dataset with mapped data' do
30
- dataset.map! do |row|
31
- row.merge(age: 21)
32
- end
33
-
34
- expect(dataset).to match_array([
35
- { name: 'Jane', age: 21 }, { name: 'Joe', age: 21 }
36
- ])
37
- end
38
- end
39
-
40
- context 'without a block' do
41
- it 'returns an enumerator' do
42
- result = dataset.map!
43
-
44
- expect(result).to be_instance_of(Enumerator)
45
-
46
- expect(result).to match_array([
47
- { name: 'Jane' }, { name: 'Joe' }
48
- ])
49
- end
50
- end
51
- end
52
-
53
- describe '#values_at' do
54
- it 'returns a new dataset with rows at given indices' do
55
- result = dataset.values_at(1)
56
-
57
- expect(result).to match_array([{ name: 'Joe' }])
58
- end
59
- end
60
- end
61
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::ClassBuilder do
4
- subject(:builder) { ROM::ClassBuilder.new(options) }
5
-
6
- let(:klass) { builder.call }
7
-
8
- describe '#call' do
9
- let(:options) do
10
- { name: 'Test', parent: parent }
11
- end
12
-
13
- let(:parent) { Class.new }
14
-
15
- it 'returns a class constant' do
16
- expect(klass).to be_instance_of(Class)
17
- end
18
-
19
- it 'sets class name based on provided :name option' do
20
- expect(klass.name).to eql(options[:name])
21
- end
22
-
23
- it 'uses a parent class provided by :parent option' do
24
- expect(klass).to be < parent
25
- end
26
-
27
- it 'defines to_s and inspect' do
28
- expect(klass.to_s).to eql(options[:name])
29
- expect(klass.inspect).to eql(options[:name])
30
- end
31
-
32
- it 'yields created class' do
33
- klass = builder.call { |yielded_class|
34
- yielded_class.class_eval do
35
- def self.testing; end
36
- end
37
- }
38
-
39
- expect(klass).to respond_to(:testing)
40
- end
41
- end
42
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'rom/support/enumerable_dataset'
4
-
5
- describe ROM::EnumerableDataset do
6
- let(:klass) do
7
- Class.new do
8
- include ROM::EnumerableDataset
9
-
10
- def self.row_proc
11
- T(:symbolize_keys)
12
- end
13
- end
14
- end
15
-
16
- it_behaves_like 'an enumerable dataset'
17
- end
@@ -1,89 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Inflector do
4
- shared_examples 'an inflector' do
5
- it 'singularises' do
6
- expect(api.singularize('tasks')).to eq 'task'
7
- end
8
-
9
- it 'pluralizes' do
10
- expect(api.pluralize('task')).to eq 'tasks'
11
- end
12
-
13
- it 'camelizes' do
14
- expect(api.camelize('task_user')).to eq 'TaskUser'
15
- end
16
-
17
- it 'underscores' do
18
- expect(api.underscore('TaskUser')).to eq 'task_user'
19
- end
20
-
21
- it 'demodulizes' do
22
- expect(api.demodulize('Task::User')).to eq 'User'
23
- end
24
-
25
- it 'constantizes' do
26
- expect(api.constantize('String')).to equal String
27
- end
28
-
29
- it 'classifies' do
30
- expect(api.classify('task_user/name')).to eq 'TaskUser::Name'
31
- end
32
- end
33
-
34
- subject(:api) { ROM::Inflector }
35
-
36
- context 'with detected inflector' do
37
- before do
38
- if api.instance_variables.include?(:@inflector)
39
- api.__send__(:remove_instance_variable, :@inflector)
40
- end
41
- end
42
-
43
- it 'prefers ActiveSupport::Inflector' do
44
- expect(api.inflector == ::ActiveSupport::Inflector).to be true
45
- end
46
- end
47
-
48
- context 'with automatic detection' do
49
- before do
50
- if api.instance_variables.include?(:@inflector)
51
- api.__send__(:remove_instance_variable, :@inflector)
52
- end
53
- end
54
-
55
- it 'automatically selects an inflector backend' do
56
- expect(api.inflector).not_to be nil
57
- end
58
- end
59
-
60
- context 'with ActiveSupport::Inflector' do
61
- before do
62
- api.select_backend(:activesupport)
63
- end
64
-
65
- it 'is ActiveSupport::Inflector' do
66
- expect(api.inflector).to be(::ActiveSupport::Inflector)
67
- end
68
-
69
- it_behaves_like 'an inflector'
70
- end
71
-
72
- context 'with Inflecto' do
73
- before do
74
- api.select_backend(:inflecto)
75
- end
76
-
77
- it 'is Inflecto' do
78
- expect(api.inflector).to be(::Inflecto)
79
- end
80
-
81
- it_behaves_like 'an inflector'
82
- end
83
-
84
- context 'an unrecognized inflector library is selected' do
85
- it 'raises a NameError' do
86
- expect { api.select_backend(:foo) }.to raise_error(NameError)
87
- end
88
- end
89
- end
@@ -1,119 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Options do
4
- let(:klass) do
5
- Class.new do
6
- include ROM::Options
7
-
8
- option :name, type: String, reader: true, allow: %w(foo bar)
9
- option :repo, reader: true
10
- option :other
11
- end
12
- end
13
-
14
- describe '.new' do
15
- it 'works without passing a hash' do
16
- expect { klass.new }.not_to raise_error
17
- end
18
-
19
- it 'sets options hash' do
20
- object = klass.new(name: 'foo')
21
- expect(object.options).to eql(name: 'foo')
22
- end
23
-
24
- it 'allows any value when :allow is not specified' do
25
- repo = double('repo')
26
- object = klass.new(repo: repo)
27
- expect(object.options).to eql(repo: repo)
28
- end
29
-
30
- it 'sets readers for options when specified' do
31
- object = klass.new(name: 'bar', repo: 'default')
32
- expect(object.name).to eql('bar')
33
- expect(object.repo).to eql('default')
34
- expect(object).to_not respond_to(:other)
35
- end
36
-
37
- it 'checks option key' do
38
- expect { klass.new(unexpected: 'foo') }
39
- .to raise_error(ROM::InvalidOptionKeyError, /:unexpected/)
40
- end
41
-
42
- it 'checks option type' do
43
- expect { klass.new(name: :foo) }
44
- .to raise_error(ROM::InvalidOptionValueError, /:foo/)
45
- end
46
-
47
- it 'checks option value' do
48
- expect { klass.new(name: 'invalid') }
49
- .to raise_error(ROM::InvalidOptionValueError, /invalid/)
50
- end
51
-
52
- it 'copies klass options to descendant' do
53
- other = Class.new(klass).new(name: 'foo')
54
- expect(other.options).to eql(name: 'foo')
55
- end
56
-
57
- it 'does not interfere with its parent`s option definitions' do
58
- Class.new(klass) do
59
- option :child, default: :nope
60
- end
61
- object = klass.new
62
- expect(object.options).to eql({})
63
- end
64
-
65
- it 'sets option defaults statically' do
66
- default_value = []
67
- klass.option :args, default: default_value
68
-
69
- object = klass.new
70
-
71
- expect(object.options).to eql(args: default_value)
72
- expect(object.options[:args]).to equal(default_value)
73
- end
74
-
75
- it 'sets option defaults dynamically via proc' do
76
- klass.option :args, default: proc { |*a| a }
77
-
78
- object = klass.new
79
-
80
- expect(object.options).to eql(args: [object])
81
- end
82
-
83
- it 'allow nil as default value' do
84
- klass.option :args, default: nil
85
-
86
- object = klass.new
87
-
88
- expect(object.options).to eql(args: nil)
89
- end
90
-
91
- it 'options are frozen' do
92
- object = klass.new
93
-
94
- expect { object.options[:foo] = :bar }
95
- .to raise_error(RuntimeError, /frozen/)
96
- end
97
-
98
- it 'call parent`s `inherited` hook' do
99
- m = Module.new do
100
- def inherited(_base)
101
- raise "hook called"
102
- end
103
- end
104
- klass.extend m
105
-
106
- expect { Class.new(klass).new }
107
- .to raise_error(/hook called/)
108
- end
109
-
110
- it 'does not modify passed options' do
111
- options = {}
112
- klass.option :foo, default: :bar
113
-
114
- klass.new(options)
115
-
116
- expect(options).to eq({})
117
- end
118
- end
119
- end