rails_omnibar 1.6.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/README.md +33 -9
- data/app/controllers/rails_omnibar/html_controller.rb +1 -1
- data/bin/console +1 -0
- data/javascript/compiled.js +1 -1
- data/javascript/src/app.tsx +9 -2
- data/javascript/src/hooks/index.ts +1 -0
- data/javascript/src/hooks/use_delayed_loading_style.tsx +26 -0
- data/lib/rails_omnibar/command/base.rb +9 -2
- data/lib/rails_omnibar/command/search.rb +2 -1
- data/lib/rails_omnibar/commands.rb +16 -7
- data/lib/rails_omnibar/conditions.rb +27 -0
- data/lib/rails_omnibar/config.rb +29 -19
- data/lib/rails_omnibar/inheritance.rb +9 -0
- data/lib/rails_omnibar/item/base.rb +9 -3
- data/lib/rails_omnibar/items.rb +2 -3
- data/lib/rails_omnibar/rendering.rb +5 -11
- data/lib/rails_omnibar/version.rb +1 -1
- data/package.json +1 -1
- data/spec/benchmarks/benchmark.rb +16 -0
- data/spec/lib/rails_omnibar/config_spec.rb +1 -3
- data/spec/lib/rails_omnibar/inheritance_spec.rb +79 -0
- data/spec/system/rails_omnibar_spec.rb +27 -0
- data/spec/templates/app_template.rb +1 -1
- data/spec/templates/my_omnibar_template.rb +8 -0
- metadata +10 -7
@@ -1,17 +1,15 @@
|
|
1
1
|
class RailsOmnibar
|
2
2
|
def handle(input, controller)
|
3
|
-
handler = commands.find
|
3
|
+
handler = commands.find do |cmd|
|
4
|
+
cmd.handle?(input, controller: controller, omnibar: self)
|
5
|
+
end
|
4
6
|
handler&.call(input, controller: controller, omnibar: self) || []
|
5
7
|
end
|
6
8
|
|
7
|
-
def command_pattern
|
8
|
-
commands.any? ? Regexp.union(commands.map(&:pattern)) : /$NO_COMMANDS/
|
9
|
-
end
|
10
|
-
|
11
9
|
def add_command(command)
|
12
|
-
check_const_and_clear_cache
|
13
10
|
commands << RailsOmnibar.cast_to_command(command)
|
14
|
-
|
11
|
+
clear_command_pattern_cache
|
12
|
+
self.class
|
15
13
|
end
|
16
14
|
|
17
15
|
def self.cast_to_command(arg)
|
@@ -43,6 +41,17 @@ class RailsOmnibar
|
|
43
41
|
|
44
42
|
private
|
45
43
|
|
44
|
+
def command_pattern
|
45
|
+
@command_pattern ||= begin
|
46
|
+
re = commands.any? ? Regexp.union(commands.map(&:pattern)) : /$NO_COMMANDS/
|
47
|
+
JsRegex.new!(re, target: 'ES2018')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def clear_command_pattern_cache
|
52
|
+
@command_pattern = nil
|
53
|
+
end
|
54
|
+
|
46
55
|
def commands
|
47
56
|
@commands ||= []
|
48
57
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class RailsOmnibar
|
2
|
+
def self.cast_to_condition(arg)
|
3
|
+
case arg
|
4
|
+
when nil, true, false then arg
|
5
|
+
else
|
6
|
+
arg.try(:arity) == 0 ? arg : RailsOmnibar.cast_to_proc(arg)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.evaluate_condition(condition, context:, omnibar:)
|
11
|
+
case condition
|
12
|
+
when nil, true then true
|
13
|
+
when false then false
|
14
|
+
else
|
15
|
+
context || raise(<<~EOS)
|
16
|
+
Missing context for condition, please render the omnibar with `.render(self)`
|
17
|
+
EOS
|
18
|
+
if condition.try(:arity) == 0
|
19
|
+
context.instance_exec(&condition)
|
20
|
+
elsif condition.respond_to?(:call)
|
21
|
+
condition.call(context, controller: context, omnibar: omnibar)
|
22
|
+
else
|
23
|
+
raise("unsupported condition type: #{condition.class}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/rails_omnibar/config.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
class RailsOmnibar
|
2
2
|
def configure(&block)
|
3
|
-
check_const_and_clear_cache
|
4
3
|
tap(&block)
|
4
|
+
self.class
|
5
5
|
end
|
6
6
|
|
7
|
-
attr_reader :auth
|
8
7
|
def auth=(arg)
|
9
|
-
|
8
|
+
config[:auth] = arg.try(:arity) == 0 ? arg : RailsOmnibar.cast_to_proc(arg)
|
9
|
+
end
|
10
|
+
def auth
|
11
|
+
config[:auth]
|
10
12
|
end
|
11
13
|
def authorize(controller)
|
12
14
|
if auth.nil?
|
@@ -20,33 +22,39 @@ class RailsOmnibar
|
|
20
22
|
|
21
23
|
def max_results=(arg)
|
22
24
|
arg.is_a?(Integer) && arg > 0 || raise(ArgumentError, 'max_results must be > 0')
|
23
|
-
|
25
|
+
config[:max_results] = arg
|
24
26
|
end
|
25
27
|
def max_results
|
26
|
-
|
28
|
+
config[:max_results] || 10
|
27
29
|
end
|
28
30
|
|
29
|
-
|
31
|
+
def modal=(arg)
|
32
|
+
config[:modal] = arg
|
33
|
+
end
|
30
34
|
def modal?
|
31
|
-
|
35
|
+
config.key?(:modal) ? !!config[:modal] : false
|
32
36
|
end
|
33
37
|
|
34
|
-
|
38
|
+
def calculator=(arg)
|
39
|
+
config[:calculator] = arg
|
40
|
+
end
|
35
41
|
def calculator?
|
36
|
-
|
42
|
+
config.key?(:calculator) ? !!config[:calculator] : true
|
37
43
|
end
|
38
44
|
|
39
|
-
def hotkey
|
40
|
-
@hotkey || 'k'
|
41
|
-
end
|
42
45
|
def hotkey=(arg)
|
43
46
|
arg.to_s.size == 1 || raise(ArgumentError, 'hotkey must have length 1')
|
44
|
-
|
47
|
+
config[:hotkey] = arg.to_s.downcase
|
48
|
+
end
|
49
|
+
def hotkey
|
50
|
+
config[:hotkey] || 'k'
|
45
51
|
end
|
46
52
|
|
47
|
-
|
53
|
+
def placeholder=(arg)
|
54
|
+
config[:placeholder] = arg
|
55
|
+
end
|
48
56
|
def placeholder
|
49
|
-
return
|
57
|
+
return config[:placeholder].presence unless config[:placeholder].nil?
|
50
58
|
|
51
59
|
help_item = items.find { |i| i.type == :help }
|
52
60
|
help_item && "Hint: Type `#{help_item.title}` for help"
|
@@ -54,13 +62,15 @@ class RailsOmnibar
|
|
54
62
|
|
55
63
|
private
|
56
64
|
|
65
|
+
def config
|
66
|
+
@config ||= {}
|
67
|
+
end
|
68
|
+
|
57
69
|
def omnibar_class
|
58
70
|
self.class.name || raise(<<~EOS)
|
59
|
-
RailsOmnibar subclasses must be assigned to constants
|
60
|
-
before configuring or rendering them. E.g.:
|
71
|
+
RailsOmnibar subclasses must be assigned to constants, e.g.:
|
61
72
|
|
62
|
-
Foo = Class.new(RailsOmnibar)
|
63
|
-
Foo.configure { ... }
|
73
|
+
Foo = Class.new(RailsOmnibar).configure { ... }
|
64
74
|
EOS
|
65
75
|
end
|
66
76
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class RailsOmnibar
|
2
2
|
module Item
|
3
3
|
class Base
|
4
|
-
attr_reader :title, :url, :icon, :modal_html, :suggested, :type
|
4
|
+
attr_reader :title, :url, :icon, :modal_html, :suggested, :type, :if
|
5
5
|
|
6
|
-
def initialize(title:, url: nil, icon: nil, modal_html: nil, suggested: false, type: :default)
|
6
|
+
def initialize(title:, url: nil, icon: nil, modal_html: nil, suggested: false, type: :default, if: nil)
|
7
7
|
url.present? && modal_html.present? && raise(ArgumentError, 'use EITHER url: OR modal_html:')
|
8
8
|
|
9
9
|
@title = validate_title(title)
|
@@ -12,10 +12,16 @@ class RailsOmnibar
|
|
12
12
|
@modal_html = modal_html
|
13
13
|
@suggested = !!suggested
|
14
14
|
@type = type
|
15
|
+
@if = RailsOmnibar.cast_to_condition(binding.local_variable_get(:if))
|
15
16
|
end
|
16
17
|
|
17
18
|
def as_json(*)
|
18
|
-
|
19
|
+
@as_json ||=
|
20
|
+
{ title: title, url: url, icon: icon, modalHTML: modal_html, suggested: suggested, type: type }
|
21
|
+
end
|
22
|
+
|
23
|
+
def render?(context:, omnibar:)
|
24
|
+
RailsOmnibar.evaluate_condition(self.if, context: context, omnibar: omnibar)
|
19
25
|
end
|
20
26
|
|
21
27
|
private
|
data/lib/rails_omnibar/items.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
class RailsOmnibar
|
2
2
|
def add_item(item)
|
3
|
-
check_const_and_clear_cache
|
4
3
|
items << RailsOmnibar.cast_to_item(item)
|
5
|
-
self
|
4
|
+
self.class
|
6
5
|
end
|
7
6
|
|
8
7
|
def add_items(*args)
|
9
8
|
args.each { |arg| add_item(arg) }
|
10
|
-
self
|
9
|
+
self.class
|
11
10
|
end
|
12
11
|
|
13
12
|
def self.cast_to_item(arg)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class RailsOmnibar
|
2
|
-
def render
|
3
|
-
@
|
2
|
+
def render(context = nil)
|
3
|
+
@context = context
|
4
|
+
<<~HTML.html_safe
|
4
5
|
<script src='#{urls.js_path}?v=#{RailsOmnibar::VERSION}' type='text/javascript'></script>
|
5
6
|
<div id='mount-rails-omnibar'>
|
6
7
|
<script type="application/json">#{to_json}</script>
|
@@ -17,9 +18,9 @@ class RailsOmnibar
|
|
17
18
|
def as_json(*)
|
18
19
|
{
|
19
20
|
calculator: calculator?,
|
20
|
-
commandPattern:
|
21
|
+
commandPattern: command_pattern,
|
21
22
|
hotkey: hotkey,
|
22
|
-
items: items,
|
23
|
+
items: items.select { |i| i.render?(context: @context, omnibar: self) },
|
23
24
|
maxResults: max_results,
|
24
25
|
modal: modal?,
|
25
26
|
placeholder: placeholder,
|
@@ -30,11 +31,4 @@ class RailsOmnibar
|
|
30
31
|
def urls
|
31
32
|
@urls ||= RailsOmnibar::Engine.routes.url_helpers
|
32
33
|
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def check_const_and_clear_cache
|
37
|
-
omnibar_class # trigger constant assignment check
|
38
|
-
@cached_html = nil
|
39
|
-
end
|
40
34
|
end
|
data/package.json
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../rails_helper'
|
2
|
+
require 'bundler/inline'
|
3
|
+
|
4
|
+
gemfile do
|
5
|
+
source 'https://rubygems.org'
|
6
|
+
gem 'benchmark-ips', require: 'benchmark/ips'
|
7
|
+
end
|
8
|
+
|
9
|
+
BenchmarkBar = Class.new(RailsOmnibar).configure do |c|
|
10
|
+
100.times { c.add_item(title: rand.to_s, url: rand.to_s) }
|
11
|
+
10.times { c.add_command(description: rand.to_s, pattern: /#{rand}/, example: rand.to_s, resolver: ->(_){}) }
|
12
|
+
end
|
13
|
+
|
14
|
+
Benchmark.ips do |x|
|
15
|
+
x.report('render') { BenchmarkBar.render } # ~3k ips
|
16
|
+
end
|
@@ -53,10 +53,8 @@ describe RailsOmnibar do
|
|
53
53
|
expect(subject.placeholder).to eq nil
|
54
54
|
end
|
55
55
|
|
56
|
-
it 'raises when trying to
|
56
|
+
it 'raises when trying to render from an anonymous class' do
|
57
57
|
klass = Class.new(RailsOmnibar)
|
58
|
-
expect { klass.configure {} }.to raise_error(/constant/)
|
59
|
-
expect { klass.add_item(title: 'a', url: 'b') }.to raise_error(/constant/)
|
60
58
|
expect { klass.render }.to raise_error(/constant/)
|
61
59
|
end
|
62
60
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe RailsOmnibar do
|
4
|
+
it 'inherits commands from a parent class' do
|
5
|
+
bar1 = Class.new(RailsOmnibar).configure do |c|
|
6
|
+
c.add_command(pattern: /foo1/, resolver: ->(_){})
|
7
|
+
end
|
8
|
+
bar2 = Class.new(bar1).configure do |c|
|
9
|
+
c.add_command(pattern: /foo2/, resolver: ->(_){})
|
10
|
+
end
|
11
|
+
bar3 = Class.new(bar2).configure do |c|
|
12
|
+
c.add_command(pattern: /foo3/, resolver: ->(_){})
|
13
|
+
end
|
14
|
+
|
15
|
+
commands = ->(bar) do
|
16
|
+
bar.send(:singleton).send(:commands).map { |c| c.pattern.source }
|
17
|
+
end
|
18
|
+
|
19
|
+
expect(commands.call(bar1)).to eq ['foo1']
|
20
|
+
expect(commands.call(bar2)).to eq ['foo1', 'foo2']
|
21
|
+
expect(commands.call(bar3)).to eq ['foo1', 'foo2', 'foo3']
|
22
|
+
|
23
|
+
# later changes to commands should not affect child classes
|
24
|
+
bar1.add_command(pattern: /foo1B/, resolver: ->(_){})
|
25
|
+
expect(commands.call(bar1)).to eq ['foo1', 'foo1B']
|
26
|
+
expect(commands.call(bar2)).to eq ['foo1', 'foo2']
|
27
|
+
expect(commands.call(bar3)).to eq ['foo1', 'foo2', 'foo3']
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'inherits configuration from a parent class' do
|
31
|
+
bar1 = Class.new(RailsOmnibar).configure do |c|
|
32
|
+
c.max_results = 7
|
33
|
+
c.placeholder = 'hi'
|
34
|
+
c.hotkey = 'j'
|
35
|
+
end
|
36
|
+
bar2 = Class.new(bar1).configure do |c|
|
37
|
+
c.max_results = 8
|
38
|
+
end
|
39
|
+
bar3 = Class.new(bar2).configure do |c|
|
40
|
+
c.hotkey = 'k'
|
41
|
+
end
|
42
|
+
|
43
|
+
config = ->(bar) { bar.send(:singleton).send(:config) }
|
44
|
+
|
45
|
+
expect(config.call(bar1)).to eq(max_results: 7, placeholder: 'hi', hotkey: 'j')
|
46
|
+
expect(config.call(bar2)).to eq(max_results: 8, placeholder: 'hi', hotkey: 'j')
|
47
|
+
expect(config.call(bar3)).to eq(max_results: 8, placeholder: 'hi', hotkey: 'k')
|
48
|
+
|
49
|
+
# later changes to config should not affect child classes
|
50
|
+
bar1.placeholder = 'bye'
|
51
|
+
expect(bar1.placeholder).to eq 'bye'
|
52
|
+
expect(bar2.placeholder).to eq 'hi'
|
53
|
+
expect(bar3.placeholder).to eq 'hi'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'inherits items from a parent class' do
|
57
|
+
bar1 = Class.new(RailsOmnibar).configure do |c|
|
58
|
+
c.add_item(title: 'foo1', url: 'bar1')
|
59
|
+
end
|
60
|
+
bar2 = Class.new(bar1).configure do |c|
|
61
|
+
c.add_item(title: 'foo2', url: 'bar2')
|
62
|
+
end
|
63
|
+
bar3 = Class.new(bar2).configure do |c|
|
64
|
+
c.add_item(title: 'foo3', url: 'bar3')
|
65
|
+
end
|
66
|
+
|
67
|
+
items = ->(bar) { bar.send(:singleton).send(:items).map(&:title) }
|
68
|
+
|
69
|
+
expect(items.call(bar1)).to eq ['foo1']
|
70
|
+
expect(items.call(bar2)).to eq ['foo1', 'foo2']
|
71
|
+
expect(items.call(bar3)).to eq ['foo1', 'foo2', 'foo3']
|
72
|
+
|
73
|
+
# later changes to items should not affect child classes
|
74
|
+
bar1.add_item(title: 'foo1B', url: 'bar1B')
|
75
|
+
expect(items.call(bar1)).to eq ['foo1', 'foo1B']
|
76
|
+
expect(items.call(bar2)).to eq ['foo1', 'foo2']
|
77
|
+
expect(items.call(bar3)).to eq ['foo1', 'foo2', 'foo3']
|
78
|
+
end
|
79
|
+
end
|
@@ -119,6 +119,33 @@ describe RailsOmnibar do
|
|
119
119
|
expect(page).not_to have_content 'fake_result_1'
|
120
120
|
end
|
121
121
|
|
122
|
+
it 'can have conditional items and commands' do
|
123
|
+
visit main_app.root_path
|
124
|
+
send_keys([:control, 'm']) # custom hotkey, c.f. my_omnibar_template.rb
|
125
|
+
expect(page).to have_selector 'input'
|
126
|
+
|
127
|
+
type('condi')
|
128
|
+
expect(page).not_to have_content 'conditional item'
|
129
|
+
|
130
|
+
FactoryBot.create(:user)
|
131
|
+
expect { type('DELETE users'); sleep 0.3 }.not_to change { User.count }
|
132
|
+
|
133
|
+
# now again with truthy condition
|
134
|
+
ENV['FAKE_OMNIBAR_IF'] = '1'
|
135
|
+
refresh # reload page
|
136
|
+
|
137
|
+
send_keys([:control, 'm']) # custom hotkey, c.f. my_omnibar_template.rb
|
138
|
+
expect(page).to have_selector 'input'
|
139
|
+
|
140
|
+
type('condi')
|
141
|
+
expect(page).to have_content 'conditional item'
|
142
|
+
|
143
|
+
FactoryBot.create(:user)
|
144
|
+
expect { type('DELETE users'); sleep 0.3 }.to change { User.count }.to(0)
|
145
|
+
ensure
|
146
|
+
ENV['FAKE_OMNIBAR_IF'] = nil
|
147
|
+
end
|
148
|
+
|
122
149
|
def type(str)
|
123
150
|
find('input').set(str)
|
124
151
|
end
|
@@ -29,7 +29,7 @@ file 'app/lib/aa/users.rb', File.read(__dir__ + '/user_resource_template.rb
|
|
29
29
|
|
30
30
|
inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController', <<-RUBY
|
31
31
|
def index
|
32
|
-
render html: (MyOmnibar.render + OtherOmnibar.render)
|
32
|
+
render html: (MyOmnibar.render(self) + OtherOmnibar.render(self))
|
33
33
|
end
|
34
34
|
RUBY
|
35
35
|
|
@@ -3,6 +3,7 @@ MyOmnibar = RailsOmnibar.configure do |c|
|
|
3
3
|
|
4
4
|
c.add_item(title: 'important URL', url: 'https://www.disney.com', suggested: true)
|
5
5
|
c.add_item(title: 'boring URL', url: 'https://www.github.com')
|
6
|
+
c.add_item(title: 'conditional item', url: '#', if: -> { ENV['FAKE_OMNIBAR_IF'] })
|
6
7
|
|
7
8
|
c.add_webadmin_items(prefix: 'Admin:')
|
8
9
|
|
@@ -43,6 +44,13 @@ MyOmnibar = RailsOmnibar.configure do |c|
|
|
43
44
|
end,
|
44
45
|
)
|
45
46
|
|
47
|
+
c.add_command(
|
48
|
+
description: 'Delete users',
|
49
|
+
pattern: /DELETE (.+)/i,
|
50
|
+
resolver: ->(value){ { title: value.classify.constantize.delete_all.to_s } },
|
51
|
+
if: ->{ ENV['FAKE_OMNIBAR_IF'] },
|
52
|
+
)
|
53
|
+
|
46
54
|
c.add_help
|
47
55
|
|
48
56
|
# Use a hotkey that is the same in most keyboard layouts to work around
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_omnibar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janosch Müller
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2024-
|
10
|
+
date: 2024-07-06 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: js_regex
|
@@ -45,7 +44,6 @@ dependencies:
|
|
45
44
|
- !ruby/object:Gem::Version
|
46
45
|
version: '8.0'
|
47
46
|
description: Omnibar for Rails
|
48
|
-
email:
|
49
47
|
executables: []
|
50
48
|
extensions: []
|
51
49
|
extra_rdoc_files: []
|
@@ -67,6 +65,7 @@ files:
|
|
67
65
|
- javascript/compiled.js
|
68
66
|
- javascript/src/app.tsx
|
69
67
|
- javascript/src/hooks/index.ts
|
68
|
+
- javascript/src/hooks/use_delayed_loading_style.tsx
|
70
69
|
- javascript/src/hooks/use_hotkey.ts
|
71
70
|
- javascript/src/hooks/use_item_action.tsx
|
72
71
|
- javascript/src/hooks/use_modal.tsx
|
@@ -79,8 +78,10 @@ files:
|
|
79
78
|
- lib/rails_omnibar/command/base.rb
|
80
79
|
- lib/rails_omnibar/command/search.rb
|
81
80
|
- lib/rails_omnibar/commands.rb
|
81
|
+
- lib/rails_omnibar/conditions.rb
|
82
82
|
- lib/rails_omnibar/config.rb
|
83
83
|
- lib/rails_omnibar/engine.rb
|
84
|
+
- lib/rails_omnibar/inheritance.rb
|
84
85
|
- lib/rails_omnibar/item/base.rb
|
85
86
|
- lib/rails_omnibar/item/help.rb
|
86
87
|
- lib/rails_omnibar/item/webadmin.rb
|
@@ -89,7 +90,9 @@ files:
|
|
89
90
|
- lib/rails_omnibar/version.rb
|
90
91
|
- package.json
|
91
92
|
- rails_omnibar.gemspec
|
93
|
+
- spec/benchmarks/benchmark.rb
|
92
94
|
- spec/lib/rails_omnibar/config_spec.rb
|
95
|
+
- spec/lib/rails_omnibar/inheritance_spec.rb
|
93
96
|
- spec/lib/rails_omnibar/item/base_spec.rb
|
94
97
|
- spec/lib/rails_omnibar/version_spec.rb
|
95
98
|
- spec/rails_helper.rb
|
@@ -105,7 +108,6 @@ homepage: https://github.com/jaynetics/rails_omnibar
|
|
105
108
|
licenses:
|
106
109
|
- MIT
|
107
110
|
metadata: {}
|
108
|
-
post_install_message:
|
109
111
|
rdoc_options: []
|
110
112
|
require_paths:
|
111
113
|
- lib
|
@@ -120,12 +122,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
122
|
- !ruby/object:Gem::Version
|
121
123
|
version: '0'
|
122
124
|
requirements: []
|
123
|
-
rubygems_version: 3.
|
124
|
-
signing_key:
|
125
|
+
rubygems_version: 3.6.0.dev
|
125
126
|
specification_version: 4
|
126
127
|
summary: Omnibar for Rails
|
127
128
|
test_files:
|
129
|
+
- spec/benchmarks/benchmark.rb
|
128
130
|
- spec/lib/rails_omnibar/config_spec.rb
|
131
|
+
- spec/lib/rails_omnibar/inheritance_spec.rb
|
129
132
|
- spec/lib/rails_omnibar/item/base_spec.rb
|
130
133
|
- spec/lib/rails_omnibar/version_spec.rb
|
131
134
|
- spec/rails_helper.rb
|