synvert-core 1.1.0 → 1.2.1

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.
@@ -1,31 +1,26 @@
1
1
  class Synvert::Core::NodeQuery::Parser
2
2
  options no_result_var
3
- token tNODE_TYPE tATTRIBUTE tKEY tIDENTIFIER tIDENTIFIER_VALUE tINDEX tPSEUDO_CLASS tCOMMA
3
+ token tNODE_TYPE tATTRIBUTE tKEY tIDENTIFIER tIDENTIFIER_VALUE tINDEX tPSEUDO_CLASS
4
4
  tCHILD tSUBSEQUENT_SIBLING tNEXT_SIBLING
5
- tOPEN_ATTRIBUTE tCLOSE_ATTRIBUTE tOPEN_DYNAMIC_ATTRIBUTE tCLOSE_DYNAMIC_ATTRIBUTE tOPEN_ARRAY tCLOSE_ARRAY tOPEN_SELECTOR tCLOSE_SELECTOR
5
+ tOPEN_ATTRIBUTE tCLOSE_ATTRIBUTE tOPEN_DYNAMIC_ATTRIBUTE tCLOSE_DYNAMIC_ATTRIBUTE
6
+ tOPEN_ARRAY tCLOSE_ARRAY tOPEN_SELECTOR tCLOSE_SELECTOR tOPEN_GOTO_SCOPE tCLOSE_GOTO_SCOPE
6
7
  tEQUAL tNOT_EQUAL tMATCH tNOT_MATCH tGREATER_THAN tGREATER_THAN_OR_EQUAL tLESS_THAN tLESS_THAN_OR_EQUAL tIN tNOT_IN tINCLUDES
7
8
  tARRAY_VALUE tDYNAMIC_ATTRIBUTE tBOOLEAN tFLOAT tINTEGER tNIL tREGEXP tSTRING tSYMBOL
8
9
  rule
9
10
  expression
10
- : selector tCHILD expression { Compiler::Expression.new(selector: val[0], rest: val[2], relationship: :child) }
11
- | selector tSUBSEQUENT_SIBLING expression { Compiler::Expression.new(selector: val[0], rest: val[2], relationship: :subsequent_sibling) }
12
- | selector tNEXT_SIBLING expression { Compiler::Expression.new(selector: val[0], rest: val[2], relationship: :next_sibling) }
13
- | selector expression { Compiler::Expression.new(selector: val[0], rest: val[1], relationship: :descendant) }
14
- | selector { Compiler::Expression.new(selector: val[0]) }
15
- | tCHILD expression { Compiler::Expression.new(rest: val[1], relationship: :child) }
11
+ : tCHILD expression { Compiler::Expression.new(rest: val[1], relationship: :child) }
16
12
  | tSUBSEQUENT_SIBLING expression { Compiler::Expression.new(rest: val[1], relationship: :subsequent_sibling) }
17
13
  | tNEXT_SIBLING expression { Compiler::Expression.new(rest: val[1], relationship: :next_sibling) }
14
+ | tOPEN_GOTO_SCOPE tIDENTIFIER tCLOSE_GOTO_SCOPE expression { Compiler::Expression.new(goto_scope: val[1], rest: val[3]) }
15
+ | tPSEUDO_CLASS tOPEN_SELECTOR expression tCLOSE_SELECTOR { Compiler::Expression.new(relationship: val[0].to_sym, rest: val[2]) }
16
+ | selector expression { Compiler::Expression.new(selector: val[0], rest: val[1]) }
17
+ | selector { Compiler::Expression.new(selector: val[0]) }
18
18
 
19
19
  selector
20
20
  : tNODE_TYPE attribute_list tINDEX { Compiler::Selector.new(node_type: val[0], attribute_list: val[1], index: val[2]) }
21
21
  | tNODE_TYPE tINDEX { Compiler::Selector.new(node_type: val[0], index: val[1]) }
22
- | attribute_list tINDEX { Compiler::Selector.new(attribute_list: val[0], index: val[1]) }
23
- | tNODE_TYPE attribute_list tPSEUDO_CLASS tOPEN_SELECTOR expression tCLOSE_SELECTOR { Compiler::Selector.new(node_type: val[0], attribute_list: val[1], pseudo_class: val[2], pseudo_expression: val[4]) }
24
- | tNODE_TYPE tPSEUDO_CLASS tOPEN_SELECTOR expression tCLOSE_SELECTOR { Compiler::Selector.new(node_type: val[0], pseudo_class: val[1], pseudo_expression: val[3]) }
25
- | attribute_list tPSEUDO_CLASS tOPEN_SELECTOR expression tCLOSE_SELECTOR { Compiler::Selector.new(attribute_list: val[0], pseudo_class: val[1], pseudo_expression: val[3]) }
26
22
  | tNODE_TYPE attribute_list { Compiler::Selector.new(node_type: val[0], attribute_list: val[1]) }
27
23
  | tNODE_TYPE { Compiler::Selector.new(node_type: val[0]) }
28
- | attribute_list { Compiler::Selector.new(attribute_list: val[0]) }
29
24
  ;
30
25
 
31
26
  attribute_list
@@ -53,7 +48,7 @@ rule
53
48
  | tKEY tIN tOPEN_ARRAY array_value tCLOSE_ARRAY { Compiler::Attribute.new(key: val[0], value: val[3], operator: :in) }
54
49
 
55
50
  array_value
56
- : value tCOMMA array_value { Compiler::Array.new(value: val[0], rest: val[2]) }
51
+ : value array_value { Compiler::Array.new(value: val[0], rest: val[1]) }
57
52
  | value { Compiler::Array.new(value: val[0]) }
58
53
 
59
54
  value
@@ -5,10 +5,10 @@
5
5
  # It supports the following selectors:
6
6
  #
7
7
  # * AST node type: +.class+, +.send+
8
- # * attribute value: +[receiver = nil]+, +[message = create]+
9
- # * attribute regex: <code>[key=~/\A:([^'"]+)\z/]</code>, <code>[key!~/\A:([^'"]+)\z/]</code>
10
- # * attribute conditions: +[message != nil]+, +[value > 1]+, +[value >= 1]+, +[value < 1]+, +[value <= 1]+
11
- # * nested attribute: +[caller.message = map]+, +[arguments.size = 2]+
8
+ # * attribute value: +.send[receiver = nil]+, +.send[message = create]+
9
+ # * attribute regex: <code>.send[key=~/\A:([^'"]+)\z/]</code>, <code>.send[key!~/\A:([^'"]+)\z/]</code>
10
+ # * attribute conditions: +.send[message != nil]+, +.send[value > 1]+, +.send[value >= 1]+, +.send[value < 1]+, +.send[value <= 1]+
11
+ # * nested attribute: +.send[caller.message = map]+, +.send[arguments.size = 2]+
12
12
  # * first or last child: +.def:first-child+, +.send:last-child+
13
13
  # * nth-child or nth-last-child: +.def:nth-child(2)+, +.send:nth-last-child(2)+
14
14
  # * descendant: +.class .send+
@@ -21,9 +21,9 @@
21
21
  #
22
22
  # * not_has: +.class:not_has(.def)+, it's same as +:not(:has())+ in css, just to make implementation easy.
23
23
  # * nested selector: +.send[arguments = [size = 2][first = .sym][last = .hash]]+
24
- # * array value: +.send[arguments = (a, b)]+
25
- # * IN operator: +.send[message IN (try, try!)]+
26
- # * NOT IN operator: +.send[message NOT IN (create, build)]+
24
+ # * array value: +.send[arguments = (a b)]+
25
+ # * IN operator: +.send[message IN (try try!)]+
26
+ # * NOT IN operator: +.send[message NOT IN (create build)]+
27
27
  # * INCLUDES operator: +.send[arguments INCLUDES &block]+
28
28
  # * dynamic attribute value: +.hash > .pair[key={{value}}]+
29
29
  #
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Synvert
4
4
  module Core
5
- VERSION = '1.1.0'
5
+ VERSION = '1.2.1'
6
6
  end
7
7
  end
@@ -1033,33 +1033,41 @@ describe Parser::AST::Node do
1033
1033
  node = parse(<<~EOS)
1034
1034
  class Synvert
1035
1035
  def foobar(foo, bar)
1036
- foo + bar
1036
+ { foo => bar }
1037
1037
  end
1038
1038
  end
1039
1039
  EOS
1040
- expect(node.to_hash).to eq({
1041
- type: :class,
1042
- parent_class: nil,
1043
- name: {
1044
- type: :const,
1045
- parent_const: nil,
1046
- name: :Synvert
1047
- },
1048
- body: [{
1049
- type: :def,
1050
- name: :foobar,
1051
- arguments: [
1052
- { type: :arg, name: :foo},
1053
- { type: :arg, name: :bar}
1054
- ],
1055
- body: [{
1056
- type: :send,
1057
- receiver: { name: :foo, type: :lvar },
1058
- message: :+,
1059
- arguments: [{ name: :bar, type: :lvar }]
1060
- }]
1061
- }]
1062
- })
1040
+ expect(node.to_hash).to eq(
1041
+ {
1042
+ type: :class,
1043
+ parent_class: nil,
1044
+ name: {
1045
+ type: :const,
1046
+ parent_const: nil,
1047
+ name: :Synvert
1048
+ },
1049
+ body: [
1050
+ {
1051
+ type: :def,
1052
+ name: :foobar,
1053
+ arguments: [
1054
+ { type: :arg, name: :foo },
1055
+ { type: :arg, name: :bar }
1056
+ ],
1057
+ body: [
1058
+ {
1059
+ type: :hash,
1060
+ pairs: {
1061
+ type: :pair,
1062
+ key: { type: :lvar, name: :foo },
1063
+ value: { type: :lvar, name: :bar }
1064
+ }
1065
+ }
1066
+ ]
1067
+ }
1068
+ ]
1069
+ }
1070
+ )
1063
1071
  end
1064
1072
  end
1065
1073
  end
@@ -200,6 +200,45 @@ module Synvert::Core::NodeQuery
200
200
  assert_tokens source, expected_tokens
201
201
  end
202
202
 
203
+ it 'matches :[] message' do
204
+ source = ".send[message=[]]"
205
+ expected_tokens = [
206
+ [:tNODE_TYPE, "send"],
207
+ [:tOPEN_ATTRIBUTE, "["],
208
+ [:tKEY, "message"],
209
+ [:tEQUAL, "="],
210
+ [:tIDENTIFIER_VALUE, "[]"],
211
+ [:tCLOSE_ATTRIBUTE, "]"]
212
+ ]
213
+ assert_tokens source, expected_tokens
214
+ end
215
+
216
+ it 'matches :[] message' do
217
+ source = ".send[message=:[]=]"
218
+ expected_tokens = [
219
+ [:tNODE_TYPE, "send"],
220
+ [:tOPEN_ATTRIBUTE, "["],
221
+ [:tKEY, "message"],
222
+ [:tEQUAL, "="],
223
+ [:tSYMBOL, :[]=],
224
+ [:tCLOSE_ATTRIBUTE, "]"]
225
+ ]
226
+ assert_tokens source, expected_tokens
227
+ end
228
+
229
+ it 'matches nil?' do
230
+ source = ".send[message=nil?]"
231
+ expected_tokens = [
232
+ [:tNODE_TYPE, "send"],
233
+ [:tOPEN_ATTRIBUTE, "["],
234
+ [:tKEY, "message"],
235
+ [:tEQUAL, "="],
236
+ [:tIDENTIFIER_VALUE, "nil?"],
237
+ [:tCLOSE_ATTRIBUTE, "]"]
238
+ ]
239
+ assert_tokens source, expected_tokens
240
+ end
241
+
203
242
  it 'matches attribute value' do
204
243
  source = '.pair[key={{value}}]'
205
244
  expected_tokens = [
@@ -403,7 +442,7 @@ module Synvert::Core::NodeQuery
403
442
  end
404
443
 
405
444
  it 'matches IN' do
406
- source = '.send[message IN (create, build)]'
445
+ source = '.send[message IN (create build)]'
407
446
  expected_tokens = [
408
447
  [:tNODE_TYPE, "send"],
409
448
  [:tOPEN_ATTRIBUTE, "["],
@@ -411,7 +450,6 @@ module Synvert::Core::NodeQuery
411
450
  [:tIN, "IN"],
412
451
  [:tOPEN_ARRAY, "("],
413
452
  [:tIDENTIFIER_VALUE, "create"],
414
- [:tCOMMA, ","],
415
453
  [:tIDENTIFIER_VALUE, "build"],
416
454
  [:tCLOSE_ARRAY, ")"],
417
455
  [:tCLOSE_ATTRIBUTE, "]"]
@@ -420,7 +458,7 @@ module Synvert::Core::NodeQuery
420
458
  end
421
459
 
422
460
  it 'matches NOT IN' do
423
- source = '.send[message NOT IN (create, build)]'
461
+ source = '.send[message NOT IN (create build)]'
424
462
  expected_tokens = [
425
463
  [:tNODE_TYPE, "send"],
426
464
  [:tOPEN_ATTRIBUTE, "["],
@@ -428,7 +466,6 @@ module Synvert::Core::NodeQuery
428
466
  [:tNOT_IN, "NOT IN"],
429
467
  [:tOPEN_ARRAY, "("],
430
468
  [:tIDENTIFIER_VALUE, "create"],
431
- [:tCOMMA, ","],
432
469
  [:tIDENTIFIER_VALUE, "build"],
433
470
  [:tCLOSE_ARRAY, ")"],
434
471
  [:tCLOSE_ATTRIBUTE, "]"]
@@ -584,5 +621,20 @@ module Synvert::Core::NodeQuery
584
621
  assert_tokens source, expected_tokens
585
622
  end
586
623
  end
624
+
625
+ context 'goto_scope' do
626
+ it 'matches' do
627
+ source = '.block <body> > .def'
628
+ expected_tokens = [
629
+ [:tNODE_TYPE, "block"],
630
+ [:tOPEN_GOTO_SCOPE, "<"],
631
+ [:tIDENTIFIER, "body"],
632
+ [:tCLOSE_GOTO_SCOPE, ">"],
633
+ [:tCHILD, ">"],
634
+ [:tNODE_TYPE, "def"]
635
+ ]
636
+ assert_tokens source, expected_tokens
637
+ end
638
+ end
587
639
  end
588
640
  end
@@ -28,6 +28,11 @@ module Synvert::Core::NodeQuery
28
28
  assert_parser(source)
29
29
  end
30
30
 
31
+ it 'parses scope' do
32
+ source = '.block <body> > .send'
33
+ assert_parser(source)
34
+ end
35
+
31
36
  it 'parses :first-child' do
32
37
  source = '.class .def:first-child'
33
38
  assert_parser(source)
@@ -49,12 +54,17 @@ module Synvert::Core::NodeQuery
49
54
  end
50
55
 
51
56
  it 'parses :has selector' do
52
- source = '.class:has(> .def)'
57
+ source = '.class :has(> .def)'
53
58
  assert_parser(source)
54
59
  end
55
60
 
56
61
  it 'parses :not_has selector' do
57
- source = '.class:not_has(> .def)'
62
+ source = '.class :not_has(> .def)'
63
+ assert_parser(source)
64
+ end
65
+
66
+ it 'parses root :has selector' do
67
+ source = ':has(.def)'
58
68
  assert_parser(source)
59
69
  end
60
70
 
@@ -99,12 +109,12 @@ module Synvert::Core::NodeQuery
99
109
  end
100
110
 
101
111
  it 'parses in operator' do
102
- source = '.def[name in (foo, bar)]'
112
+ source = '.def[name in (foo bar)]'
103
113
  assert_parser(source)
104
114
  end
105
115
 
106
116
  it 'parses not_in operator' do
107
- source = '.def[name not in (foo, bar)]'
117
+ source = '.def[name not in (foo bar)]'
108
118
  assert_parser(source)
109
119
  end
110
120
 
@@ -118,6 +128,16 @@ module Synvert::Core::NodeQuery
118
128
  assert_parser(source)
119
129
  end
120
130
 
131
+ it 'parses []=' do
132
+ source = '.send[message=[]=]'
133
+ assert_parser(source)
134
+ end
135
+
136
+ it 'parses :[]' do
137
+ source = '.send[message=:[]]'
138
+ assert_parser(source)
139
+ end
140
+
121
141
  describe '#query_nodes' do
122
142
  let(:node) {
123
143
  parse(<<~EOS)
@@ -132,13 +152,22 @@ module Synvert::Core::NodeQuery
132
152
 
133
153
  def foobar(a, b)
134
154
  { a: a, b: b }
135
- foo.merge(bar)
136
155
  arr[index]
156
+ arr[index] = value
157
+ nil?
158
+ call('')
137
159
  end
138
160
  end
139
161
  EOS
140
162
  }
141
163
 
164
+ let(:test_node) {
165
+ parse(<<~EOS)
166
+ RSpec.describe Synvert do
167
+ end
168
+ EOS
169
+ }
170
+
142
171
  it 'matches class node' do
143
172
  expression = parser.parse('.class[name=Synvert]')
144
173
  expect(expression.query_nodes(node)).to eq [node]
@@ -180,12 +209,12 @@ module Synvert::Core::NodeQuery
180
209
  end
181
210
 
182
211
  it 'matches in' do
183
- expression = parser.parse('.def[name IN (foo, bar)]')
212
+ expression = parser.parse('.def[name IN (foo bar)]')
184
213
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
185
214
  end
186
215
 
187
216
  it 'matches not in' do
188
- expression = parser.parse('.def[name NOT IN (foo, bar)]')
217
+ expression = parser.parse('.def[name NOT IN (foo bar)]')
189
218
  expect(expression.query_nodes(node)).to eq [node.body.last]
190
219
  end
191
220
 
@@ -195,34 +224,34 @@ module Synvert::Core::NodeQuery
195
224
  end
196
225
 
197
226
  it 'matches equal array' do
198
- expression = parser.parse('.def[arguments=(a, b)]')
227
+ expression = parser.parse('.def[arguments=(a b)]')
199
228
  expect(expression.query_nodes(node)).to eq [node.body.last]
200
229
 
201
- expression = parser.parse('.def[arguments=(b, a)]')
230
+ expression = parser.parse('.def[arguments=(b a)]')
202
231
  expect(expression.query_nodes(node)).to eq []
203
232
  end
204
233
 
205
234
  it 'matches not equal array' do
206
- expression = parser.parse('.def[arguments!=(a, b)]')
235
+ expression = parser.parse('.def[arguments!=(a b)]')
207
236
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
208
237
 
209
- expression = parser.parse('.def[arguments!=(b, a)]')
238
+ expression = parser.parse('.def[arguments!=(b a)]')
210
239
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second, node.body.last]
211
240
  end
212
241
 
213
242
  it 'matches descendant node' do
214
243
  expression = parser.parse('.class .send[message=:create]')
215
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
244
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
216
245
  end
217
246
 
218
247
  it 'matches three level descendant node' do
219
248
  expression = parser.parse('.class .def .send[message=:create]')
220
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
249
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
221
250
  end
222
251
 
223
252
  it 'matches child node' do
224
253
  expression = parser.parse('.def > .send[message=:create]')
225
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
254
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
226
255
  end
227
256
 
228
257
  it 'matches next sibling node' do
@@ -235,6 +264,19 @@ module Synvert::Core::NodeQuery
235
264
  expect(expression.query_nodes(node)).to eq [node.body.last]
236
265
  end
237
266
 
267
+ it 'matches goto scope' do
268
+ expression = parser.parse('.def <body> > .send[message=:create]')
269
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
270
+
271
+ expression = parser.parse('.def <body> .send[message=:create]')
272
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
273
+ end
274
+
275
+ it 'matches multiple goto scope' do
276
+ expression = parser.parse('.block <caller.arguments> .const[name=Synvert]')
277
+ expect(expression.query_nodes(test_node)).to eq [test_node.caller.arguments.first]
278
+ end
279
+
238
280
  it 'matches has selector' do
239
281
  expression = parser.parse('.def:has(> .send[receiver=FactoryBot])')
240
282
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
@@ -245,18 +287,31 @@ module Synvert::Core::NodeQuery
245
287
  expect(expression.query_nodes(node)).to eq [node.body.last]
246
288
  end
247
289
 
290
+ it 'matches root has selector' do
291
+ expression = parser.parse(':has(.def[name=foobar])')
292
+ expect(expression.query_nodes(node)).to eq [node]
293
+ end
294
+
248
295
  it 'matches arguments.size' do
249
- expression = parser.parse('.send[arguments.size=2]')
250
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
251
- expression = parser.parse('.send[arguments.size>2]')
296
+ expression = parser.parse('.def .send[arguments.size=2]')
297
+ expect(expression.query_nodes(node)).to eq [
298
+ node.body.first.body.last,
299
+ node.body.second.body.last,
300
+ node.body.third.body.third
301
+ ]
302
+ expression = parser.parse('.def .send[arguments.size>2]')
252
303
  expect(expression.query_nodes(node)).to eq []
253
- expression = parser.parse('.send[arguments.size>=2]')
254
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
304
+ expression = parser.parse('.def .send[arguments.size>=2]')
305
+ expect(expression.query_nodes(node)).to eq [
306
+ node.body.first.body.last,
307
+ node.body.second.body.last,
308
+ node.body.third.body.third
309
+ ]
255
310
  end
256
311
 
257
312
  it 'matches arguments' do
258
- expression = parser.parse('.send[arguments=[size=2][first=.sym][last=.hash]]')
259
- expect(expression.query_nodes(node)).to eq [node.body.first.children.last, node.body.second.children.last]
313
+ expression = parser.parse('.send[arguments.size=2][arguments.first=.sym][arguments.last=.hash]')
314
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
260
315
  end
261
316
 
262
317
  it 'matches regexp value' do
@@ -271,15 +326,25 @@ module Synvert::Core::NodeQuery
271
326
  expect(expression.query_nodes(node)).to eq node.body.last.body.first.children
272
327
  end
273
328
 
274
- it 'matches identifier' do
275
- expression = parser.parse('.send[receiver=foo][message=merge]')
329
+ it 'matches []' do
330
+ expression = parser.parse('.send[message=[]]')
276
331
  expect(expression.query_nodes(node)).to eq [node.body.last.body.second]
277
332
  end
278
333
 
279
- it 'matches []' do
280
- expression = parser.parse('.send[message="[]"]')
334
+ it 'matches []=' do
335
+ expression = parser.parse('.send[message=:[]=]')
281
336
  expect(expression.query_nodes(node)).to eq [node.body.last.body.third]
282
337
  end
338
+
339
+ it 'matches nil and nil?' do
340
+ expression = parser.parse('.send[receiver=nil][message=nil?]')
341
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.fourth]
342
+ end
343
+
344
+ it 'matches empty string' do
345
+ expression = parser.parse('.send[message=call][arguments.first=""]')
346
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.last]
347
+ end
283
348
  end
284
349
  end
285
350
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-26 00:00:00.000000000 Z
11
+ date: 2022-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport