grumlin 0.23.0 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -9
  3. data/Gemfile.lock +1 -1
  4. data/README.md +94 -141
  5. data/Rakefile +1 -1
  6. data/bin/console +18 -3
  7. data/doc/middlewares.md +49 -10
  8. data/lib/async/channel.rb +54 -56
  9. data/lib/grumlin/benchmark/repository.rb +10 -14
  10. data/lib/grumlin/client.rb +93 -95
  11. data/lib/grumlin/config.rb +33 -33
  12. data/lib/grumlin/dummy_transaction.rb +13 -15
  13. data/lib/grumlin/edge.rb +18 -20
  14. data/lib/grumlin/expressions/cardinality.rb +5 -9
  15. data/lib/grumlin/expressions/column.rb +5 -9
  16. data/lib/grumlin/expressions/expression.rb +7 -11
  17. data/lib/grumlin/expressions/operator.rb +5 -9
  18. data/lib/grumlin/expressions/order.rb +5 -9
  19. data/lib/grumlin/expressions/p.rb +27 -31
  20. data/lib/grumlin/expressions/pop.rb +5 -9
  21. data/lib/grumlin/expressions/scope.rb +5 -9
  22. data/lib/grumlin/expressions/t.rb +5 -9
  23. data/lib/grumlin/expressions/text_p.rb +5 -9
  24. data/lib/grumlin/expressions/with_options.rb +17 -21
  25. data/lib/grumlin/features/feature_list.rb +8 -12
  26. data/lib/grumlin/features/neptune_features.rb +5 -9
  27. data/lib/grumlin/features/tinkergraph_features.rb +5 -9
  28. data/lib/grumlin/features.rb +8 -10
  29. data/lib/grumlin/middlewares/apply_shortcuts.rb +4 -8
  30. data/lib/grumlin/middlewares/build_query.rb +16 -20
  31. data/lib/grumlin/middlewares/builder.rb +15 -0
  32. data/lib/grumlin/middlewares/cast_results.rb +3 -7
  33. data/lib/grumlin/middlewares/find_blocklisted_steps.rb +14 -0
  34. data/lib/grumlin/middlewares/find_mutating_steps.rb +9 -0
  35. data/lib/grumlin/middlewares/middleware.rb +6 -10
  36. data/lib/grumlin/middlewares/run_query.rb +3 -7
  37. data/lib/grumlin/middlewares/serialize_to_bytecode.rb +5 -9
  38. data/lib/grumlin/middlewares/serialize_to_steps.rb +4 -8
  39. data/lib/grumlin/path.rb +11 -13
  40. data/lib/grumlin/property.rb +14 -16
  41. data/lib/grumlin/query_validators/blocklisted_steps_validator.rb +22 -0
  42. data/lib/grumlin/query_validators/validator.rb +36 -0
  43. data/lib/grumlin/repository/error_handling_strategy.rb +36 -40
  44. data/lib/grumlin/repository/instance_methods.rb +115 -118
  45. data/lib/grumlin/repository.rb +82 -58
  46. data/lib/grumlin/request_dispatcher.rb +55 -57
  47. data/lib/grumlin/request_error_factory.rb +53 -55
  48. data/lib/grumlin/shortcut.rb +19 -21
  49. data/lib/grumlin/shortcuts/properties.rb +12 -16
  50. data/lib/grumlin/shortcuts/storage.rb +67 -74
  51. data/lib/grumlin/shortcuts/upserts.rb +18 -22
  52. data/lib/grumlin/shortcuts.rb +23 -25
  53. data/lib/grumlin/shortcuts_applyer.rb +27 -29
  54. data/lib/grumlin/step.rb +88 -90
  55. data/lib/grumlin/step_data.rb +12 -14
  56. data/lib/grumlin/steppable.rb +23 -25
  57. data/lib/grumlin/steps.rb +52 -54
  58. data/lib/grumlin/steps_serializers/bytecode.rb +53 -56
  59. data/lib/grumlin/steps_serializers/human_readable_bytecode.rb +17 -21
  60. data/lib/grumlin/steps_serializers/serializer.rb +7 -11
  61. data/lib/grumlin/steps_serializers/string.rb +26 -30
  62. data/lib/grumlin/test/rspec/db_cleaner_context.rb +8 -12
  63. data/lib/grumlin/test/rspec/gremlin_context.rb +18 -16
  64. data/lib/grumlin/test/rspec.rb +1 -5
  65. data/lib/grumlin/transaction.rb +34 -36
  66. data/lib/grumlin/transport.rb +71 -73
  67. data/lib/grumlin/traversal_start.rb +31 -33
  68. data/lib/grumlin/traversal_strategies/options_strategy.rb +3 -7
  69. data/lib/grumlin/traverser.rb +5 -7
  70. data/lib/grumlin/typed_value.rb +11 -13
  71. data/lib/grumlin/typing.rb +70 -72
  72. data/lib/grumlin/version.rb +1 -1
  73. data/lib/grumlin/vertex.rb +14 -16
  74. data/lib/grumlin/vertex_property.rb +14 -16
  75. data/lib/grumlin/with_extension.rb +17 -19
  76. metadata +9 -6
  77. data/lib/grumlin/middlewares/frozen_builder.rb +0 -18
  78. data/lib/grumlin/sugar.rb +0 -15
@@ -1,125 +1,123 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Client
5
- class PoolResource < Async::Pool::Resource
6
- attr_reader :client
7
-
8
- def self.call
9
- config = Grumlin.config
10
- new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
11
- end
12
-
13
- def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
14
- super(concurrency)
15
- @client = client_factory.call(url, parent).tap(&:connect)
16
- @parent = parent
17
- end
3
+ class Grumlin::Client
4
+ class PoolResource < Async::Pool::Resource
5
+ attr_reader :client
18
6
 
19
- def closed?
20
- !@client.connected?
21
- end
7
+ def self.call
8
+ config = Grumlin.config
9
+ new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
10
+ end
22
11
 
23
- def close
24
- @client.close
25
- end
12
+ def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
13
+ super(concurrency)
14
+ @client = client_factory.call(url, parent).tap(&:connect)
15
+ @parent = parent
16
+ end
26
17
 
27
- def write(query)
28
- @client.write(query)
29
- ensure
30
- @count += 1
31
- end
18
+ def closed?
19
+ !@client.connected?
20
+ end
32
21
 
33
- def viable?
34
- !closed?
35
- end
22
+ def close
23
+ @client.close
24
+ end
36
25
 
37
- def reusable?
38
- !closed?
39
- end
26
+ def write(query)
27
+ @client.write(query)
28
+ ensure
29
+ @count += 1
40
30
  end
41
31
 
42
- include Console
32
+ def viable?
33
+ !closed?
34
+ end
43
35
 
44
- # Client is not reusable. Once closed should be recreated.
45
- def initialize(url, parent: Async::Task.current, **client_options)
46
- @url = url
47
- @client_options = client_options
48
- @parent = parent
49
- @request_dispatcher = nil
50
- @transport = nil
36
+ def reusable?
37
+ !closed?
51
38
  end
39
+ end
52
40
 
53
- def connect
54
- raise ClientClosedError if @closed
55
-
56
- @transport = build_transport
57
- response_channel = @transport.connect
58
- @request_dispatcher = RequestDispatcher.new
59
- @response_task = @parent.async do
60
- response_channel.each do |response|
61
- @request_dispatcher.add_response(response)
62
- end
63
- rescue Async::Stop, Async::TimeoutError, StandardError
64
- close(check_requests: false)
41
+ include Console
42
+
43
+ # Client is not reusable. Once closed should be recreated.
44
+ def initialize(url, parent: Async::Task.current, **client_options)
45
+ @url = url
46
+ @client_options = client_options
47
+ @parent = parent
48
+ @request_dispatcher = nil
49
+ @transport = nil
50
+ end
51
+
52
+ def connect
53
+ raise ClientClosedError if @closed
54
+
55
+ @transport = build_transport
56
+ response_channel = @transport.connect
57
+ @request_dispatcher = Grumlin::RequestDispatcher.new
58
+ @response_task = @parent.async do
59
+ response_channel.each do |response|
60
+ @request_dispatcher.add_response(response)
65
61
  end
66
- logger.debug(self, "Connected")
62
+ rescue Async::Stop, Async::TimeoutError, StandardError
63
+ close(check_requests: false)
67
64
  end
65
+ logger.debug(self, "Connected")
66
+ end
68
67
 
69
- # Before calling close the user must ensure that:
70
- # 1) There are no ongoing requests
71
- # 2) There will be no new writes after
72
- def close(check_requests: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
73
- return if @closed
68
+ # Before calling close the user must ensure that:
69
+ # 1) There are no ongoing requests
70
+ # 2) There will be no new writes after
71
+ def close(check_requests: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
72
+ return if @closed
74
73
 
75
- @closed = true
74
+ @closed = true
76
75
 
77
- @transport&.close
78
- @transport&.wait
76
+ @transport&.close
77
+ @transport&.wait
79
78
 
80
- @response_task&.stop
81
- @response_task&.wait
79
+ @response_task&.stop
80
+ @response_task&.wait
82
81
 
83
- return if @request_dispatcher&.requests&.empty?
82
+ return if @request_dispatcher&.requests&.empty?
84
83
 
85
- @request_dispatcher.clear unless check_requests
84
+ @request_dispatcher.clear unless check_requests
86
85
 
87
- raise ResourceLeakError, "Request list is not empty: #{@request_dispatcher.requests}" if check_requests
88
- ensure
89
- logger.debug(self, "Closed")
90
- end
86
+ raise ResourceLeakError, "Request list is not empty: #{@request_dispatcher.requests}" if check_requests
87
+ ensure
88
+ logger.debug(self, "Closed")
89
+ end
91
90
 
92
- def connected?
93
- @transport&.connected? || false
94
- end
91
+ def connected?
92
+ @transport&.connected? || false
93
+ end
95
94
 
96
- # TODO: support yielding
97
- def write(query)
98
- raise NotConnectedError unless connected?
99
-
100
- channel = @request_dispatcher.add_request(query)
101
- begin
102
- @transport.write(query)
103
- channel.dequeue
104
- rescue Async::Stop, Async::TimeoutError
105
- close(check_requests: false)
106
- raise
107
- end
95
+ # TODO: support yielding
96
+ def write(query)
97
+ raise NotConnectedError unless connected?
98
+
99
+ channel = @request_dispatcher.add_request(query)
100
+ begin
101
+ @transport.write(query)
102
+ channel.dequeue
103
+ rescue Async::Stop, Async::TimeoutError
104
+ close(check_requests: false)
105
+ raise
108
106
  end
107
+ end
109
108
 
110
- def inspect
111
- "<#{self.class} url=#{@url} connected=#{connected?}>"
112
- end
109
+ def inspect
110
+ "<#{self.class} url=#{@url} connected=#{connected?}>"
111
+ end
113
112
 
114
- def to_s
115
- inspect
116
- end
113
+ def to_s
114
+ inspect
115
+ end
117
116
 
118
- private
117
+ private
119
118
 
120
- # This might be overridden in successors
121
- def build_transport
122
- Transport.new(@url, parent: @parent, **@client_options)
123
- end
119
+ # This might be overridden in successors
120
+ def build_transport
121
+ Grumlin::Transport.new(@url, parent: @parent, **@client_options)
124
122
  end
125
123
  end
@@ -1,41 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Config
5
- attr_accessor :url, :pool_size, :client_concurrency, :client_factory, :provider
6
-
7
- SUPPORTED_PROVIDERS = %i[neptune tinkergraph].freeze
8
-
9
- DEFAULT_MIDDLEWARES = Middleware::Builder.new do |b|
10
- b.use Middlewares::SerializeToSteps
11
- b.use Middlewares::ApplyShortcuts
12
- b.use Middlewares::SerializeToBytecode
13
- b.use Middlewares::BuildQuery
14
- b.use Middlewares::CastResults
15
- b.use Middlewares::RunQuery
16
- end.freeze
17
-
18
- class ConfigurationError < Grumlin::Error; end
19
-
20
- class UnknownProviderError < ConfigurationError; end
21
-
22
- def initialize
23
- @pool_size = 10
24
- @client_concurrency = 5
25
- @provider = :tinkergraph
26
- @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
27
- end
3
+ class Grumlin::Config
4
+ attr_accessor :url, :pool_size, :client_concurrency, :client_factory, :provider
5
+
6
+ SUPPORTED_PROVIDERS = [:neptune, :tinkergraph].freeze
7
+
8
+ DEFAULT_MIDDLEWARES = Grumlin::Middlewares::Builder.new do |b|
9
+ b.use Grumlin::Middlewares::SerializeToSteps
10
+ b.use Grumlin::Middlewares::ApplyShortcuts
11
+ b.use Grumlin::Middlewares::SerializeToBytecode
12
+ b.use Grumlin::Middlewares::BuildQuery
13
+ b.use Grumlin::Middlewares::CastResults
14
+ b.use Grumlin::Middlewares::RunQuery
15
+ end
28
16
 
29
- def middlewares
30
- @middlewares ||= Middleware::Builder.new do |b|
31
- b.use DEFAULT_MIDDLEWARES
32
- end
33
- end
17
+ class ConfigurationError < Grumlin::Error; end
18
+
19
+ class UnknownProviderError < ConfigurationError; end
34
20
 
35
- def validate!
36
- return if SUPPORTED_PROVIDERS.include?(provider.to_sym)
21
+ def initialize
22
+ @pool_size = 10
23
+ @client_concurrency = 5
24
+ @provider = :tinkergraph
25
+ @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
26
+ end
37
27
 
38
- raise UnknownProviderError, "provider '#{provider}' is unknown. Supported providers: #{SUPPORTED_PROVIDERS}"
28
+ def middlewares
29
+ @middlewares ||= Grumlin::Middlewares::Builder.new do |b|
30
+ b.use DEFAULT_MIDDLEWARES
39
31
  end
32
+ yield(@middlewares) if block_given?
33
+ @middlewares
34
+ end
35
+
36
+ def validate!
37
+ return if SUPPORTED_PROVIDERS.include?(provider.to_sym)
38
+
39
+ raise UnknownProviderError, "provider '#{provider}' is unknown. Supported providers: #{SUPPORTED_PROVIDERS}"
40
40
  end
41
41
  end
@@ -1,25 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class DummyTransaction < Transaction
5
- attr_reader :uuid
3
+ class Grumlin::DummyTransaction < Grumlin::Transaction
4
+ attr_reader :uuid
6
5
 
7
- include Console
6
+ include Console
8
7
 
9
- def initialize(traversal_start_class, middlewares:, pool: nil) # rubocop:disable Lint/MissingSuper, Lint/UnusedMethodArgument
10
- @traversal_start_class = traversal_start_class
8
+ def initialize(traversal_start_class, middlewares:, pool: nil) # rubocop:disable Lint/MissingSuper, Lint/UnusedMethodArgument
9
+ @traversal_start_class = traversal_start_class
11
10
 
12
- logger.info(self) do
13
- "#{Grumlin.config.provider} does not support transactions. commit and rollback are ignored, data will be saved"
14
- end
11
+ logger.info(self) do
12
+ "#{Grumlin.config.provider} does not support transactions. commit and rollback are ignored, data will be saved"
15
13
  end
14
+ end
16
15
 
17
- def commit
18
- nil
19
- end
16
+ def commit
17
+ nil
18
+ end
20
19
 
21
- def rollback
22
- nil
23
- end
20
+ def rollback
21
+ nil
24
22
  end
25
23
  end
data/lib/grumlin/edge.rb CHANGED
@@ -1,28 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Edge
5
- attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
3
+ class Grumlin::Edge
4
+ attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
6
5
 
7
- def initialize(label:, id:, inVLabel:, outVLabel:, inV:, outV:)
8
- @label = label
9
- @id = Typing.cast(id)
10
- @inVLabel = inVLabel
11
- @outVLabel = outVLabel
12
- @inV = Typing.cast(inV)
13
- @outV = Typing.cast(outV)
14
- end
6
+ def initialize(label:, id:, inVLabel:, outVLabel:, inV:, outV:)
7
+ @label = label
8
+ @id = Grumlin::Typing.cast(id)
9
+ @inVLabel = inVLabel
10
+ @outVLabel = outVLabel
11
+ @inV = Grumlin::Typing.cast(inV)
12
+ @outV = Grumlin::Typing.cast(outV)
13
+ end
15
14
 
16
- def ==(other)
17
- self.class == other.class && @label == other.label && @id == other.id
18
- end
15
+ def ==(other)
16
+ self.class == other.class && @label == other.label && @id == other.id
17
+ end
19
18
 
20
- def inspect
21
- "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
22
- end
19
+ def inspect
20
+ "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
21
+ end
23
22
 
24
- def to_s
25
- inspect
26
- end
23
+ def to_s
24
+ inspect
27
25
  end
28
26
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Cardinality
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Cardinality
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Cardinality")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Cardinality")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Column
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Column
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Column")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Column")
14
10
  end
15
11
  end
@@ -1,17 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Expression
6
- def define_steps(steps, tool_name)
7
- steps.each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
3
+ module Grumlin::Expressions::Expression
4
+ def define_steps(steps, tool_name)
5
+ steps.each do |step|
6
+ define_method step do
7
+ name = "@#{step}"
8
+ return instance_variable_get(name) if instance_variable_defined?(name)
11
9
 
12
- instance_variable_set(name, TypedValue.new(type: tool_name, value: step))
13
- end
14
- end
10
+ instance_variable_set(name, Grumlin::TypedValue.new(type: tool_name, value: step))
15
11
  end
16
12
  end
17
13
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Operator
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Operator
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Operator")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Operator")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Order
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Order
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Order")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Order")
14
10
  end
15
11
  end
@@ -1,39 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- class P
6
- class Predicate
7
- attr_reader :namespace, :name, :value, :type
3
+ class Grumlin::Expressions::P
4
+ class Predicate
5
+ attr_reader :namespace, :name, :value, :type
8
6
 
9
- def initialize(namespace, name, value:, type: nil)
10
- @namespace = namespace
11
- @name = name
12
- @value = value
13
- @type = type
14
- end
15
- end
7
+ def initialize(namespace, name, value:, type: nil)
8
+ @namespace = namespace
9
+ @name = name
10
+ @value = value
11
+ @type = type
12
+ end
13
+ end
16
14
 
17
- class << self
18
- # TODO: support more predicates
19
- %i[eq gt lt neq].each do |predicate|
20
- define_method predicate do |*args|
21
- Predicate.new("P", predicate, value: args[0])
22
- end
23
- end
15
+ class << self
16
+ # TODO: support more predicates
17
+ [:eq, :gt, :lt, :neq].each do |predicate|
18
+ define_method predicate do |*args|
19
+ Predicate.new("P", predicate, value: args[0])
20
+ end
21
+ end
24
22
 
25
- %i[within without].each do |predicate|
26
- define_method predicate do |*args|
27
- args = if args.count == 1 && args[0].is_a?(Array)
28
- args[0]
29
- elsif args.count == 1 && args[0].is_a?(Set)
30
- args[0].to_a
31
- else
32
- args.to_a
33
- end
34
- Predicate.new("P", predicate, value: args, type: "List")
35
- end
36
- end
23
+ [:within, :without].each do |predicate|
24
+ define_method predicate do |*args|
25
+ args = if args.count == 1 && args[0].is_a?(Array)
26
+ args[0]
27
+ elsif args.count == 1 && args[0].is_a?(Set)
28
+ args[0].to_a
29
+ else
30
+ args.to_a
31
+ end
32
+ Predicate.new("P", predicate, value: args, type: "List")
37
33
  end
38
34
  end
39
35
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Pop
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Pop
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Pop")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Pop")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module Scope
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::Scope
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "Scope")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "Scope")
14
10
  end
15
11
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- module T
6
- SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
3
+ module Grumlin::Expressions::T
4
+ SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
7
5
 
8
- class << self
9
- extend Expression
6
+ class << self
7
+ extend Grumlin::Expressions::Expression
10
8
 
11
- define_steps(SUPPORTED_STEPS, "T")
12
- end
13
- end
9
+ define_steps(SUPPORTED_STEPS, "T")
14
10
  end
15
11
  end
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Expressions
5
- class TextP < P
6
- class << self
7
- %i[containing endingWith notContaining notEndingWith notStartingWith startingWith].each do |predicate|
8
- define_method predicate do |*args|
9
- P::Predicate.new("TextP", predicate, value: args[0])
10
- end
11
- end
3
+ class Grumlin::Expressions::TextP < Grumlin::Expressions::P
4
+ class << self
5
+ [:containing, :endingWith, :notContaining, :notEndingWith, :notStartingWith, :startingWith].each do |predicate|
6
+ define_method predicate do |*args|
7
+ P::Predicate.new("TextP", predicate, value: args[0])
12
8
  end
13
9
  end
14
10
  end