boltless 1.0.0

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 (44) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/Guardfile +44 -0
  4. data/Makefile +138 -0
  5. data/Rakefile +26 -0
  6. data/docker-compose.yml +19 -0
  7. data/lib/boltless/configuration.rb +69 -0
  8. data/lib/boltless/errors/invalid_json_error.rb +9 -0
  9. data/lib/boltless/errors/request_error.rb +24 -0
  10. data/lib/boltless/errors/response_error.rb +30 -0
  11. data/lib/boltless/errors/transaction_begin_error.rb +9 -0
  12. data/lib/boltless/errors/transaction_in_bad_state_error.rb +11 -0
  13. data/lib/boltless/errors/transaction_not_found_error.rb +11 -0
  14. data/lib/boltless/errors/transaction_rollback_error.rb +26 -0
  15. data/lib/boltless/extensions/configuration_handling.rb +37 -0
  16. data/lib/boltless/extensions/connection_pool.rb +127 -0
  17. data/lib/boltless/extensions/operations.rb +175 -0
  18. data/lib/boltless/extensions/transactions.rb +301 -0
  19. data/lib/boltless/extensions/utilities.rb +187 -0
  20. data/lib/boltless/request.rb +386 -0
  21. data/lib/boltless/result.rb +98 -0
  22. data/lib/boltless/result_row.rb +90 -0
  23. data/lib/boltless/statement_collector.rb +40 -0
  24. data/lib/boltless/transaction.rb +234 -0
  25. data/lib/boltless/version.rb +23 -0
  26. data/lib/boltless.rb +36 -0
  27. data/spec/benchmark/transfer.rb +57 -0
  28. data/spec/boltless/extensions/configuration_handling_spec.rb +39 -0
  29. data/spec/boltless/extensions/connection_pool_spec.rb +131 -0
  30. data/spec/boltless/extensions/operations_spec.rb +189 -0
  31. data/spec/boltless/extensions/transactions_spec.rb +418 -0
  32. data/spec/boltless/extensions/utilities_spec.rb +546 -0
  33. data/spec/boltless/request_spec.rb +946 -0
  34. data/spec/boltless/result_row_spec.rb +161 -0
  35. data/spec/boltless/result_spec.rb +127 -0
  36. data/spec/boltless/statement_collector_spec.rb +45 -0
  37. data/spec/boltless/transaction_spec.rb +601 -0
  38. data/spec/boltless_spec.rb +11 -0
  39. data/spec/fixtures/files/raw_result.yml +21 -0
  40. data/spec/fixtures/files/raw_result_with_graph_result.yml +48 -0
  41. data/spec/fixtures/files/raw_result_with_meta.yml +11 -0
  42. data/spec/fixtures/files/raw_result_with_stats.yml +26 -0
  43. data/spec/spec_helper.rb +89 -0
  44. metadata +384 -0
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Boltless::ResultRow do
6
+ let(:instance) { Boltless::Result.from(input).first }
7
+ let(:input) { raw_result_fixture }
8
+
9
+ describe '#[]' do
10
+ it 'allows direct key access to the row data (string key)' do
11
+ expect(instance['active']).to be_eql(true)
12
+ end
13
+
14
+ it 'allows direct key access to the row data (symbol key)' do
15
+ expect(instance[:active]).to be_eql(true)
16
+ end
17
+
18
+ it 'returns the expected value (name)' do
19
+ expect(instance[:name]).to be_eql('Bernd')
20
+ end
21
+
22
+ it 'returns the expected value (birthday)' do
23
+ expect(instance[:birthday]).to be_eql(Date.parse('1971-07-28'))
24
+ end
25
+
26
+ it 'returns the expected value (written_books)' do
27
+ expect(instance[:written_books]).to be_eql(2)
28
+ end
29
+ end
30
+
31
+ describe '#value' do
32
+ it 'returns the first value of the row' do
33
+ expect(instance.value).to be_eql(instance.values.first)
34
+ end
35
+ end
36
+
37
+ describe '#values' do
38
+ it 'returns all row values' do
39
+ expect(instance.values).to \
40
+ match_array(['Bernd', Date.parse('1971-07-28'), 2, true])
41
+ end
42
+ end
43
+
44
+ describe '#to_h' do
45
+ let(:hash) do
46
+ {
47
+ active: true,
48
+ birthday: Date.parse('1971-07-28'),
49
+ name: 'Bernd',
50
+ written_books: 2
51
+ }
52
+ end
53
+
54
+ it 'returns the correct hash representation' do
55
+ expect(instance.to_h).to match(hash)
56
+ end
57
+ end
58
+
59
+ describe '#as_json' do
60
+ let(:hash) do
61
+ {
62
+ 'active' => true,
63
+ 'birthday' => Date.parse('1971-07-28'),
64
+ 'name' => 'Bernd',
65
+ 'written_books' => 2
66
+ }
67
+ end
68
+
69
+ it 'returns the correct hash representation' do
70
+ expect(instance.as_json).to match(hash)
71
+ end
72
+ end
73
+
74
+ describe '#each' do
75
+ let(:simple_instance) do
76
+ Boltless::Result.from(columns: [:key], data: [{ row: ['value'] }]).first
77
+ end
78
+
79
+ it 'yields each cell of the row (count)' do
80
+ expect { |control| instance.each(&control) }.to \
81
+ yield_control.exactly(4).times
82
+ end
83
+
84
+ it 'yields each row (argument)' do
85
+ expect { |control| simple_instance.each(&control) }.to \
86
+ yield_with_args(:key, 'value')
87
+ end
88
+ end
89
+
90
+ describe '#pretty_print' do
91
+ let(:action) { PP.pp(instance, ''.dup) }
92
+ let(:input) { raw_result_fixture(:with_stats) }
93
+
94
+ it 'includes the struct name' do
95
+ expect(action).to include('#<Boltless::ResultRow')
96
+ end
97
+
98
+ it 'includes the columns' do
99
+ expect(action).to include('columns=[:n]')
100
+ end
101
+
102
+ it 'includes the values' do
103
+ expect(action).to include('values=[{:name=>"Klaus"}]')
104
+ end
105
+
106
+ it 'includes the meta' do
107
+ expect(action).to \
108
+ include('meta=[{:id=>146, :type=>"node", :deleted=>false}]')
109
+ end
110
+
111
+ it 'includes the graph' do
112
+ expect(action).to include('graph=nil')
113
+ end
114
+ end
115
+
116
+ describe '#inspect' do
117
+ let(:action) { instance.inspect }
118
+ let(:input) { raw_result_fixture }
119
+
120
+ it 'includes the struct name' do
121
+ expect(action).to include('#<Boltless::ResultRow')
122
+ end
123
+
124
+ it 'includes the columns' do
125
+ expect(action).to \
126
+ include('columns=[:name, :birthday, :written_books, :active]')
127
+ end
128
+
129
+ it 'includes the values' do
130
+ expect(action).to include('values=["Bernd",')
131
+ end
132
+
133
+ it 'includes the meta' do
134
+ expect(action).to \
135
+ include('meta=[nil]')
136
+ end
137
+
138
+ it 'includes the graph' do
139
+ expect(action).to include('graph=nil')
140
+ end
141
+
142
+ context 'with a graph result' do
143
+ let(:input) { raw_result_fixture(:with_graph_result) }
144
+
145
+ it 'includes the graph (key)' do
146
+ expect(action).to include('graph={:nodes=>')
147
+ end
148
+
149
+ it 'includes the graph (nodes)' do
150
+ expect(action).to \
151
+ include('[{:id=>"149", :labels=>["User"], ' \
152
+ ':properties=>{:name=>"Kalle"}}]')
153
+ end
154
+
155
+ it 'includes the graph (relationships)' do
156
+ expect(action).to \
157
+ include(':relationships=>[]')
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Boltless::Result do
6
+ let(:instance) { described_class.from(input) }
7
+ let(:input) { raw_result_fixture }
8
+
9
+ describe '.from' do
10
+ let(:action) { described_class.from(input) }
11
+
12
+ it 'returns a Boltless::Result' do
13
+ expect(action).to be_a(described_class)
14
+ end
15
+
16
+ it 'allows to access the shared result columns' do
17
+ expect(action.columns).to \
18
+ match_array(%i[active birthday name written_books])
19
+ end
20
+
21
+ it 'returns the correct count of rows (via reader)' do
22
+ expect(action.rows.count).to be_eql(2)
23
+ end
24
+
25
+ it 'returns the correct count of rows (directly)' do
26
+ expect(action.count).to be_eql(2)
27
+ end
28
+
29
+ context 'with statistics' do
30
+ let(:input) { raw_result_fixture(:with_stats) }
31
+
32
+ it 'allows to access the result statistics' do
33
+ expect(action.stats).to include(nodes_created: 1)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#each' do
39
+ it 'yields each row (count)' do
40
+ expect { |control| instance.each(&control) }.to yield_control.twice
41
+ end
42
+
43
+ it 'yields each row (argument)' do
44
+ instance.rows.pop
45
+ expect { |control| instance.each(&control) }.to \
46
+ yield_with_args(instance.rows.first)
47
+ end
48
+ end
49
+
50
+ describe '#to_a' do
51
+ it 'returns the rows' do
52
+ expect(instance.to_a).to be(instance.rows)
53
+ end
54
+ end
55
+
56
+ describe '#value' do
57
+ it 'returns the correct value' do
58
+ expect(instance.value).to be_eql('Bernd')
59
+ end
60
+ end
61
+
62
+ describe '#values' do
63
+ let(:mapped) do
64
+ [
65
+ {
66
+ name: 'Bernd',
67
+ birthday: Date.parse('1971-07-28'),
68
+ written_books: 2,
69
+ active: true
70
+ },
71
+ {
72
+ name: 'Klaus',
73
+ birthday: Date.parse('1998-01-03'),
74
+ written_books: 0,
75
+ active: false
76
+ }
77
+ ]
78
+ end
79
+
80
+ it 'returns the correct array' do
81
+ expect(instance.values).to match_array(mapped)
82
+ end
83
+ end
84
+
85
+ describe '#pretty_print' do
86
+ let(:action) { PP.pp(instance, ''.dup) }
87
+ let(:input) { raw_result_fixture(:with_stats) }
88
+
89
+ it 'includes the struct name' do
90
+ expect(action).to include('#<Boltless::Result')
91
+ end
92
+
93
+ it 'includes the columns' do
94
+ expect(action).to include('columns=[:n]')
95
+ end
96
+
97
+ it 'includes the rows' do
98
+ expect(action).to include('rows=[#<Boltless::ResultRow')
99
+ end
100
+
101
+ it 'includes the stats' do
102
+ expect(action).to include('stats={:contains_updates=>true')
103
+ end
104
+ end
105
+
106
+ describe '#inspect' do
107
+ let(:action) { instance.inspect }
108
+ let(:input) { raw_result_fixture }
109
+
110
+ it 'includes the struct name' do
111
+ expect(action).to include('#<Boltless::Result')
112
+ end
113
+
114
+ it 'includes the columns' do
115
+ expect(action).to \
116
+ include('columns=[:name, :birthday, :written_books, :active]')
117
+ end
118
+
119
+ it 'includes the rows' do
120
+ expect(action).to include('rows=[#<Boltless::ResultRow')
121
+ end
122
+
123
+ it 'includes the stats' do
124
+ expect(action).to include('stats=nil')
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Boltless::StatementCollector do
6
+ let(:instance) { described_class.new }
7
+
8
+ describe 'delegations' do
9
+ it 'allows to access the #build_cypher utility' do
10
+ expect(instance.respond_to?(:build_cypher)).to be_eql(true)
11
+ end
12
+ end
13
+
14
+ describe '#add' do
15
+ let(:action) { -> { instance.add('cypher', param_a: 1) } }
16
+
17
+ it 'returns itself for chaining' do
18
+ expect(action.call).to be(instance)
19
+ end
20
+
21
+ it 'collects the given statements' do
22
+ action.call
23
+ action.call
24
+ expect(instance.statements.count).to be_eql(2)
25
+ end
26
+
27
+ it 'calls Request.statement_payload to prepare the statement' do
28
+ expect(Boltless::Request).to \
29
+ receive(:statement_payload).with('cypher', param_a: 1).once
30
+ action.call
31
+ end
32
+ end
33
+
34
+ describe '#statements' do
35
+ let(:action) { instance.statements }
36
+
37
+ before { instance.add('cypher', param_a: 1) }
38
+
39
+ it 'returns the mapped statements' do
40
+ expect(action.first).to \
41
+ match(statement: 'cypher',
42
+ parameters: { param_a: 1 })
43
+ end
44
+ end
45
+ end