dbee 2.1.0.pre.alpha → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/dbee.rb CHANGED
@@ -13,11 +13,15 @@ require 'forwardable'
13
13
 
14
14
  require_relative 'dbee/base'
15
15
  require_relative 'dbee/constant_resolver'
16
+ require_relative 'dbee/dsl_schema_builder'
16
17
  require_relative 'dbee/key_chain'
17
18
  require_relative 'dbee/key_path'
18
19
  require_relative 'dbee/model'
19
- require_relative 'dbee/query'
20
20
  require_relative 'dbee/providers'
21
+ require_relative 'dbee/query'
22
+ require_relative 'dbee/schema'
23
+ require_relative 'dbee/schema_creator'
24
+ require_relative 'dbee/schema_from_tree_based_model'
21
25
 
22
26
  # Top-level namespace that provides the main public API.
23
27
  module Dbee
@@ -31,16 +35,11 @@ module Dbee
31
35
  @inflector ||= Dry::Inflector.new
32
36
  end
33
37
 
34
- def sql(model, query, provider)
35
- query = Query.make(query)
36
- model =
37
- if model.is_a?(Hash) || model.is_a?(Model)
38
- Model.make(model)
39
- else
40
- model.to_model(query.key_chain)
41
- end
38
+ def sql(schema_or_model, query_input, provider)
39
+ raise ArgumentError, 'a provider is required' unless provider
42
40
 
43
- provider.sql(model, query)
41
+ schema_compat = SchemaCreator.new(schema_or_model, query_input)
42
+ provider.sql(schema_compat.schema, schema_compat.query)
44
43
  end
45
44
  end
46
45
  end
@@ -11,52 +11,17 @@ require 'spec_helper'
11
11
  require 'fixtures/models'
12
12
 
13
13
  describe Dbee::Base do
14
- describe '#to_model' do
15
- it 'compiles correctly' do
16
- model_name = 'Theaters, Members, and Movies'
17
- expected_config = yaml_fixture('models.yaml')[model_name]
14
+ describe '.to_schema' do
15
+ it 'passes the keychain and model to DslSchemaBuilder' do
16
+ key_chain = Dbee::KeyChain.new
18
17
 
19
- expected_model = Dbee::Model.make(expected_config)
18
+ schema_builder_double = double(Dbee::DslSchemaBuilder)
19
+ expect(Dbee::DslSchemaBuilder).to receive(:new).with(Models::A, key_chain).and_return(
20
+ schema_builder_double
21
+ )
22
+ expect(schema_builder_double).to receive(:to_schema)
20
23
 
21
- key_paths = %w[
22
- members.demos.phone_numbers.a
23
- members.movies.b
24
- members.favorite_comic_movies.c
25
- members.favorite_mystery_movies.d
26
- members.favorite_comedy_movies.e
27
- parent_theater.members.demos.phone_numbers.f
28
- parent_theater.members.movies.g
29
- parent_theater.members.favorite_comic_movies.h
30
- parent_theater.members.favorite_mystery_movies.i
31
- parent_theater.members.favorite_comedy_movies.j
32
- ]
33
-
34
- key_chain = Dbee::KeyChain.new(key_paths)
35
-
36
- actual_model = Models::Theater.to_model(key_chain)
37
-
38
- expect(actual_model).to eq(expected_model)
39
- end
40
-
41
- it 'honors key_chain to flatten cyclic references' do
42
- model_name = 'Cycle Example'
43
- expected_config = yaml_fixture('models.yaml')[model_name]
44
-
45
- expected_model = Dbee::Model.make(expected_config)
46
-
47
- key_paths = %w[
48
- b1.c.a.z
49
- b1.d.a.y
50
- b2.c.a.x
51
- b2.d.a.w
52
- b2.d.a.b1.c.z
53
- ]
54
-
55
- key_chain = Dbee::KeyChain.new(key_paths)
56
-
57
- actual_model = Cycles::A.to_model(key_chain)
58
-
59
- expect(actual_model).to eq(expected_model)
24
+ Models::A.to_schema(key_chain)
60
25
  end
61
26
  end
62
27
 
@@ -72,32 +37,4 @@ describe Dbee::Base do
72
37
  expect(Models::E.inherited_table_name).to eq('table_set_to_e')
73
38
  end
74
39
  end
75
-
76
- describe 'partitioners' do
77
- it 'honors partitioners on a root model' do
78
- model_name = 'Partitioner Example 1'
79
- expected_config = yaml_fixture('models.yaml')[model_name]
80
- expected_model = Dbee::Model.make(expected_config)
81
-
82
- key_paths = %w[id]
83
- key_chain = Dbee::KeyChain.new(key_paths)
84
-
85
- actual_model = PartitionerExamples::Dog.to_model(key_chain)
86
-
87
- expect(actual_model).to eq(expected_model)
88
- end
89
-
90
- it 'honors partitioners on a child model' do
91
- model_name = 'Partitioner Example 2'
92
- expected_config = yaml_fixture('models.yaml')[model_name]
93
- expected_model = Dbee::Model.make(expected_config)
94
-
95
- key_paths = %w[id dogs.id]
96
- key_chain = Dbee::KeyChain.new(key_paths)
97
-
98
- actual_model = PartitionerExamples::Owner.to_model(key_chain)
99
-
100
- expect(actual_model).to eq(expected_model)
101
- end
102
- end
103
40
  end
@@ -9,23 +9,28 @@
9
9
 
10
10
  require 'spec_helper'
11
11
 
12
- describe Dbee::ConstantResolver do
13
- module A
14
- class B; end
15
- class E; end
16
- end
17
-
12
+ # rubocop:disable Lint/EmptyClass
13
+ # These are intentionally empty to keep the tests focused.
14
+ module A
18
15
  class B; end
19
16
 
20
- module C
21
- class D; end
22
- class E; end
17
+ class E; end
18
+ end
19
+
20
+ class B; end
23
21
 
24
- module F
25
- class G; end
26
- end
22
+ module C
23
+ class D; end
24
+
25
+ class E; end
26
+
27
+ module F
28
+ class G; end
27
29
  end
30
+ end
31
+ # rubocop:enable Lint/EmptyClass
28
32
 
33
+ describe Dbee::ConstantResolver do
29
34
  it 'resolves nested constant with the same as an ancestor constants sibling' do
30
35
  expect(subject.constantize('A::B')).to eq(::A::B)
31
36
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+ require 'fixtures/models'
12
+
13
+ describe Dbee::DslSchemaBuilder do
14
+ specify 'theaters example' do
15
+ model_name = 'Theaters, Members, and Movies from DSL'
16
+ expected_config = yaml_fixture('models.yaml')[model_name]
17
+
18
+ expected_schema = Dbee::Schema.new(expected_config)
19
+
20
+ key_paths = %w[
21
+ members.a
22
+ members.demos.phone_numbers.a
23
+ members.movies.b
24
+ members.favorite_comic_movies.c
25
+ members.favorite_mystery_movies.d
26
+ members.favorite_comedy_movies.e
27
+ parent_theater.members.demos.phone_numbers.f
28
+ parent_theater.members.movies.g
29
+ parent_theater.members.favorite_comic_movies.h
30
+ parent_theater.members.favorite_mystery_movies.i
31
+ parent_theater.members.favorite_comedy_movies.j
32
+ ]
33
+
34
+ key_chain = Dbee::KeyChain.new(key_paths)
35
+
36
+ actual_schema = Models::Theater.to_schema(key_chain)
37
+ expect(actual_schema).to eq(expected_schema)
38
+ end
39
+
40
+ it 'honors key_chain to flatten cyclic references' do
41
+ model_name = 'Cycle Example'
42
+ expected_config = yaml_fixture('models.yaml')[model_name]
43
+
44
+ expected_schema = Dbee::Schema.new(expected_config)
45
+
46
+ key_paths = %w[
47
+ b1.c.a.z
48
+ b1.d.a.y
49
+ b2.c.a.x
50
+ b2.d.a.w
51
+ b2.d.a.b1.c.z
52
+ ]
53
+
54
+ key_chain = Dbee::KeyChain.new(key_paths)
55
+
56
+ actual_schema = Cycles::A.to_schema(key_chain)
57
+ expect(actual_schema).to eq(expected_schema)
58
+ end
59
+
60
+ describe 'partitioners' do
61
+ it 'honors partitioners on a root model' do
62
+ model_name = 'Partitioner Example 1'
63
+ expected_config = yaml_fixture('models.yaml')[model_name]
64
+ expected_schema = Dbee::Schema.new(expected_config)
65
+
66
+ key_paths = %w[id]
67
+ key_chain = Dbee::KeyChain.new(key_paths)
68
+
69
+ actual_schema = PartitionerExamples::Dog.to_schema(key_chain)
70
+
71
+ expect(actual_schema).to eq(expected_schema)
72
+ end
73
+
74
+ it 'honors partitioners on a child model' do
75
+ model_name = 'Partitioner Example 2'
76
+ expected_config = yaml_fixture('models.yaml')[model_name]
77
+ expected_schema = Dbee::Schema.new(expected_config)
78
+
79
+ key_paths = %w[id dogs.id]
80
+ key_chain = Dbee::KeyChain.new(key_paths)
81
+
82
+ actual_schema = PartitionerExamples::Owner.to_schema(key_chain)
83
+
84
+ expect(actual_schema).to eq(expected_schema)
85
+ end
86
+ end
87
+
88
+ context 'README examples' do
89
+ specify 'code-first and configuration-first models are equal' do
90
+ config = yaml_fixture('models.yaml')['Readme']
91
+ config_schema = Dbee::Schema.new(config)
92
+
93
+ key_chain = Dbee::KeyChain.new(%w[
94
+ patients.a
95
+ patients.notes.b
96
+ patients.work_phone_number.c
97
+ patients.cell_phone_number.d
98
+ patients.fax_phone_number.e
99
+ ])
100
+
101
+ code_schema = ReadmeDataModels::Practice.to_schema(key_chain)
102
+
103
+ expect(config_schema).to eq(code_schema)
104
+ end
105
+ end
106
+ end
@@ -78,4 +78,28 @@ describe Dbee::KeyChain do
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ describe '#to_unique_ancestors collapses the KeyChain' do
83
+ let(:collapsed_key_chain) do
84
+ described_class.new([
85
+ 'z.b.c.d.any_column',
86
+ 'b.c.any_column',
87
+ 'any_column',
88
+ '44.55.any_column'
89
+ ])
90
+ end
91
+
92
+ specify 'the empty case' do
93
+ expect(described_class.new.to_unique_ancestors).to eq described_class.new
94
+ end
95
+
96
+ specify 'when there are no ancestors, one key path is returned' do
97
+ no_query_depth = described_class.new(%w[column1 column2 column3])
98
+ expect(no_query_depth.to_unique_ancestors).to eq described_class.new(['any_column'])
99
+ end
100
+
101
+ it 'returns a new KeyChain which has one KeyPath per ancestor' do
102
+ expect(subject.to_unique_ancestors).to eq collapsed_key_chain
103
+ end
104
+ end
81
105
  end
@@ -9,14 +9,13 @@
9
9
 
10
10
  require 'spec_helper'
11
11
 
12
- describe Dbee::Model::Constraints do
13
- CONSTRAINT_CONFIG = { name: :a }.freeze
14
-
15
- CONSTRAINT_FACTORIES = {
16
- Dbee::Model::Constraints::Reference => CONSTRAINT_CONFIG.merge(parent: :b, type: :reference),
17
- Dbee::Model::Constraints::Static => CONSTRAINT_CONFIG.merge(value: :b, type: :static)
18
- }.freeze
12
+ CONSTRAINT_CONFIG = { name: :a }.freeze
13
+ CONSTRAINT_FACTORIES = {
14
+ Dbee::Model::Constraints::Reference => CONSTRAINT_CONFIG.merge(parent: :b, type: :reference),
15
+ Dbee::Model::Constraints::Static => CONSTRAINT_CONFIG.merge(value: :b, type: :static)
16
+ }.freeze
19
17
 
18
+ describe Dbee::Model::Constraints do
20
19
  CONSTRAINT_FACTORIES.each_pair do |constant, config|
21
20
  it "should instantiate #{constant} objects" do
22
21
  expect(described_class.make(config)).to be_a(constant)
@@ -55,77 +55,80 @@ describe Dbee::Model do
55
55
  end
56
56
  end
57
57
 
58
- describe '#ancestors' do
59
- let(:yaml_entities) { yaml_fixture('models.yaml') }
60
-
61
- let(:entity_hash) { yaml_entities['Theaters, Members, and Movies'] }
62
-
63
- subject { described_class.make(entity_hash) }
64
-
65
- specify 'returns proper models' do
66
- members = subject.models.first
67
-
68
- expected_plan = {
69
- %w[members] => members
58
+ describe '.make_keyed_by' do
59
+ it 'returns a hash of Models where the keys equal the names of the models' do
60
+ input = {
61
+ model1: nil,
62
+ model2: { table: :model2_table }
70
63
  }
71
-
72
- plan = subject.ancestors!(%w[members])
73
-
74
- expect(plan).to eq(expected_plan)
75
- end
76
-
77
- specify 'returns proper multi-level models' do
78
- members = subject.models.first
79
- demos = members.models.first
80
- phone_numbers = demos.models.first
81
-
82
- expected_plan = {
83
- %w[members] => members,
84
- %w[members demos] => demos,
85
- %w[members demos phone_numbers] => phone_numbers
64
+ expected_result = {
65
+ 'model1' => described_class.new(name: 'model1'),
66
+ 'model2' => described_class.new(name: 'model2', table: 'model2_table')
86
67
  }
87
68
 
88
- plan = subject.ancestors!(%w[members demos phone_numbers])
89
-
90
- expect(plan).to eq(expected_plan)
69
+ expect(described_class.make_keyed_by(:name, input)).to eq expected_result
91
70
  end
92
- end
93
-
94
- describe 'equality' do
95
- let(:config) { yaml_fixture('models.yaml')['Theaters, Members, and Movies'] }
96
71
 
97
- subject { described_class.make(config) }
98
-
99
- specify 'equality compares attributes' do
100
- model1 = described_class.make(config)
101
- model2 = described_class.make(config)
72
+ it 'accepts values of Dbee::Model instances' do
73
+ input = { model1: described_class.new(name: :model1) }
74
+ expected_result = { 'model1' => described_class.new(name: :model1) }
75
+ expect(described_class.make_keyed_by(:name, input)).to eq expected_result
76
+ end
102
77
 
103
- expect(model1).to eq(model2)
104
- expect(model1).to eql(model2)
78
+ it 'accepts values of Dbee::Model instances when the key attribute is a string' do
79
+ input = { 'model1' => described_class.new(name: 'model1') }
80
+ expected_result = { 'model1' => described_class.new(name: 'model1') }
81
+ expect(described_class.make_keyed_by(:name, input)).to eq expected_result
105
82
  end
106
83
 
107
- it 'returns false unless comparing same object types' do
108
- expect(subject).not_to eq(config)
109
- expect(subject).not_to eq(nil)
84
+ it 'raises an error when the input hash key is not equal to the name of the model' do
85
+ input = { model1: described_class.new(name: :bogus) }
86
+ expect do
87
+ described_class.make_keyed_by(:name, input)
88
+ end.to raise_error ArgumentError, "expected a name of 'model1' but got 'bogus'"
110
89
  end
111
90
  end
112
91
 
113
- context 'README examples' do
114
- specify 'code-first and configuration-first models are equal' do
115
- config = yaml_fixture('models.yaml')['Readme']
116
- config_model = described_class.make(config)
117
-
118
- key_chain = Dbee::KeyChain.new(%w[
119
- patients.a
120
- patients.notes.b
121
- patients.work_phone_number.c
122
- patients.cell_phone_number.d
123
- patients.fax_phone_number.e
124
- ])
125
-
126
- code_model = ReadmeDataModels::Practice.to_model(key_chain)
92
+ describe '#to_s' do
93
+ it 'is represented by the model name' do
94
+ expect(described_class.new(name: 'foo').to_s).to eq 'foo'
95
+ end
96
+ end
127
97
 
128
- expect(config_model).to eq(code_model)
98
+ equality_cases = {
99
+ tree_based: yaml_fixture('models.yaml')['Theaters, Members, and Movies Tree Based'],
100
+ graph_based: yaml_fixture('models.yaml')['Theaters, Members, and Movies from DSL']['theater']
101
+ }
102
+ equality_cases[:graph_based].merge!(name: 'theaters')
103
+ equality_cases.each do |test_case, config|
104
+ describe "equality for #{test_case}" do
105
+ let(:model1) { described_class.make(config) }
106
+ let(:model2) { described_class.make(config) }
107
+
108
+ subject { described_class.make(config) }
109
+
110
+ specify 'equality compares attributes' do
111
+ expect(model1).to eq(model2)
112
+ expect(model1).to eql(model2)
113
+ end
114
+
115
+ it 'returns false unless comparing same object types' do
116
+ expect(subject).not_to eq(config)
117
+ expect(subject).not_to eq(nil)
118
+ end
119
+
120
+ describe 'hash codes' do
121
+ specify 'are equal when objects are equal' do
122
+ expect(model1).to eq(model2)
123
+ expect(model1.hash).to eq(model2.hash)
124
+ end
125
+
126
+ specify 'are not equal when objects are not equal' do
127
+ different_model = described_class.new(name: :oddball)
128
+ expect(model1).not_to eq(different_model)
129
+ expect(model1.hash).not_to eq(different_model.hash)
130
+ end
131
+ end
129
132
  end
130
133
  end
131
134
  end
@@ -9,24 +9,23 @@
9
9
 
10
10
  require 'spec_helper'
11
11
 
12
- describe Dbee::Query::Filters do
13
- FILTERS_CONFIG = { key_path: 'a.b.c', value: :d }.freeze
14
-
15
- FILTER_FACTORIES = {
16
- Dbee::Query::Filters::Contains => FILTERS_CONFIG.merge(type: :contains),
17
- Dbee::Query::Filters::Equals => FILTERS_CONFIG.merge(type: :equals),
18
- Dbee::Query::Filters::GreaterThanOrEqualTo => FILTERS_CONFIG.merge(
19
- type: :greater_than_or_equal_to
20
- ),
21
- Dbee::Query::Filters::GreaterThan => FILTERS_CONFIG.merge(type: :greater_than),
22
- Dbee::Query::Filters::LessThanOrEqualTo => FILTERS_CONFIG.merge(type: :less_than_or_equal_to),
23
- Dbee::Query::Filters::LessThan => FILTERS_CONFIG.merge(type: :less_than),
24
- Dbee::Query::Filters::NotContain => FILTERS_CONFIG.merge(type: :not_contain),
25
- Dbee::Query::Filters::NotEquals => FILTERS_CONFIG.merge(type: :not_equals),
26
- Dbee::Query::Filters::NotStartWith => FILTERS_CONFIG.merge(type: :not_start_with),
27
- Dbee::Query::Filters::StartsWith => FILTERS_CONFIG.merge(type: :starts_with)
28
- }.freeze
12
+ FILTERS_CONFIG = { key_path: 'a.b.c', value: :d }.freeze
13
+ FILTER_FACTORIES = {
14
+ Dbee::Query::Filters::Contains => FILTERS_CONFIG.merge(type: :contains),
15
+ Dbee::Query::Filters::Equals => FILTERS_CONFIG.merge(type: :equals),
16
+ Dbee::Query::Filters::GreaterThanOrEqualTo => FILTERS_CONFIG.merge(
17
+ type: :greater_than_or_equal_to
18
+ ),
19
+ Dbee::Query::Filters::GreaterThan => FILTERS_CONFIG.merge(type: :greater_than),
20
+ Dbee::Query::Filters::LessThanOrEqualTo => FILTERS_CONFIG.merge(type: :less_than_or_equal_to),
21
+ Dbee::Query::Filters::LessThan => FILTERS_CONFIG.merge(type: :less_than),
22
+ Dbee::Query::Filters::NotContain => FILTERS_CONFIG.merge(type: :not_contain),
23
+ Dbee::Query::Filters::NotEquals => FILTERS_CONFIG.merge(type: :not_equals),
24
+ Dbee::Query::Filters::NotStartWith => FILTERS_CONFIG.merge(type: :not_start_with),
25
+ Dbee::Query::Filters::StartsWith => FILTERS_CONFIG.merge(type: :starts_with)
26
+ }.freeze
29
27
 
28
+ describe Dbee::Query::Filters do
30
29
  FILTER_FACTORIES.each_pair do |constant, config|
31
30
  it "should instantiate #{constant} objects" do
32
31
  expect(described_class.make(config)).to be_a(constant)
@@ -9,9 +9,64 @@
9
9
 
10
10
  require 'spec_helper'
11
11
 
12
+ README_EXAMPLES = {
13
+ 'Get all practices' => {
14
+ fields: [
15
+ { key_path: 'id' },
16
+ { key_path: 'active' },
17
+ { key_path: 'name' }
18
+ ]
19
+ },
20
+ 'Get practices, limit to 2, offset by 3, and sort by name (descending) then id (ascending)' => {
21
+ fields: [
22
+ { key_path: 'id' },
23
+ { key_path: 'active' },
24
+ { key_path: 'name' }
25
+ ],
26
+ sorters: [
27
+ { key_path: 'name', direction: :descending },
28
+ { key_path: 'id' }
29
+ ],
30
+ limit: 2,
31
+ offset: 3
32
+ },
33
+ "Get top 5 active practices and patient whose name start with 'Sm':" => {
34
+ fields: [
35
+ { key_path: 'name', display: 'Practice Name' },
36
+ { key_path: 'patients.first', display: 'Patient First Name' },
37
+ { key_path: 'patients.middle', display: 'Patient Middle Name' },
38
+ { key_path: 'patients.last', display: 'Patient Last Name' }
39
+ ],
40
+ filters: [
41
+ { type: :equals, key_path: 'active', value: true },
42
+ { type: :starts_with, key_path: 'patients.last', value: 'Sm' }
43
+ ],
44
+ limit: 5
45
+ },
46
+ 'Get practice IDs, patient IDs, names, and cell phone numbers that starts with 555' => {
47
+ fields: [
48
+ { key_path: 'id', display: 'Practice ID #' },
49
+ { key_path: 'patients.id', display: 'Patient ID #' },
50
+ { key_path: 'patients.first', display: 'Patient First Name' },
51
+ { key_path: 'patients.middle', display: 'Patient Middle Name' },
52
+ { key_path: 'patients.last', display: 'Patient Last Name' },
53
+ { key_path: 'patients.cell_phone_numbers.phone_number', display: 'Patient Cell #' }
54
+ ],
55
+ filters: [
56
+ { type: :equals, key_path: 'active', value: true },
57
+ {
58
+ type: :starts_with,
59
+ key_path: 'patients.cell_phone_numbers.phone_number',
60
+ value: '555'
61
+ }
62
+ ]
63
+ }
64
+ }.freeze
65
+
12
66
  describe Dbee::Query do
13
67
  let(:config) do
14
68
  {
69
+ from: 'my_model',
15
70
  fields: [
16
71
  { key_path: 'matt.nick.sam', display: 'some display' },
17
72
  { key_path: 'katie' },
@@ -36,14 +91,6 @@ describe Dbee::Query do
36
91
  end
37
92
 
38
93
  describe '#initialize' do
39
- it 'should raise an ArgumentError if fields keyword is missing' do
40
- expect { described_class.new }.to raise_error(ArgumentError)
41
- end
42
-
43
- it 'should raise a NoFieldsError if no fields were passed in' do
44
- expect { described_class.new(fields: []) }.to raise_error(Dbee::Query::NoFieldsError)
45
- end
46
-
47
94
  it 'should remove duplicate filters (keep first instance)' do
48
95
  query_hash = {
49
96
  fields: [
@@ -124,60 +171,7 @@ describe Dbee::Query do
124
171
  end
125
172
 
126
173
  context 'README examples' do
127
- EXAMPLES = {
128
- 'Get all practices' => {
129
- fields: [
130
- { key_path: 'id' },
131
- { key_path: 'active' },
132
- { key_path: 'name' }
133
- ]
134
- },
135
- 'Get all practices, limit to 10, and sort by name (descending) then id (ascending)' => {
136
- fields: [
137
- { key_path: 'id' },
138
- { key_path: 'active' },
139
- { key_path: 'name' }
140
- ],
141
- sorters: [
142
- { key_path: 'name', direction: :descending },
143
- { key_path: 'id' }
144
- ],
145
- limit: 10
146
- },
147
- "Get top 5 active practices and patient whose name start with 'Sm':" => {
148
- fields: [
149
- { key_path: 'name', display: 'Practice Name' },
150
- { key_path: 'patients.first', display: 'Patient First Name' },
151
- { key_path: 'patients.middle', display: 'Patient Middle Name' },
152
- { key_path: 'patients.last', display: 'Patient Last Name' }
153
- ],
154
- filters: [
155
- { type: :equals, key_path: 'active', value: true },
156
- { type: :starts_with, key_path: 'patients.last', value: 'Sm' }
157
- ],
158
- limit: 5
159
- },
160
- 'Get practice IDs, patient IDs, names, and cell phone numbers that starts with 555' => {
161
- fields: [
162
- { key_path: 'id', display: 'Practice ID #' },
163
- { key_path: 'patients.id', display: 'Patient ID #' },
164
- { key_path: 'patients.first', display: 'Patient First Name' },
165
- { key_path: 'patients.middle', display: 'Patient Middle Name' },
166
- { key_path: 'patients.last', display: 'Patient Last Name' },
167
- { key_path: 'patients.cell_phone_numbers.phone_number', display: 'Patient Cell #' }
168
- ],
169
- filters: [
170
- { type: :equals, key_path: 'active', value: true },
171
- {
172
- type: :starts_with,
173
- key_path: 'patients.cell_phone_numbers.phone_number',
174
- value: '555'
175
- }
176
- ]
177
- }
178
- }.freeze
179
-
180
- EXAMPLES.each_pair do |name, query|
174
+ README_EXAMPLES.each_pair do |name, query|
181
175
  specify name do
182
176
  expect(described_class.make(query)).to be_a(described_class)
183
177
  end