hairballs 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +24 -0
- data/.travis.yml +3 -0
- data/History.md +12 -0
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/lib/hairballs.rb +14 -14
- data/lib/hairballs/configuration.rb +12 -6
- data/lib/hairballs/exceptions.rb +4 -0
- data/lib/hairballs/ext/kernel_vputs.rb +1 -0
- data/lib/hairballs/library_helpers.rb +48 -18
- data/lib/hairballs/plugin.rb +8 -8
- data/lib/hairballs/plugins/colorize_json.rb +4 -2
- data/lib/hairballs/plugins/irb_history.rb +4 -2
- data/lib/hairballs/plugins/tab_completion_for_files.rb +3 -2
- data/lib/hairballs/themes/turboladen.rb +3 -1
- data/lib/hairballs/themes/turboladen_rails.rb +2 -0
- data/lib/hairballs/version.rb +2 -1
- data/spec/hairballs/configuration_spec.rb +24 -8
- data/spec/hairballs/library_helpers_spec.rb +79 -14
- data/spec/hairballs/plugin_spec.rb +5 -5
- data/spec/spec_helper.rb +5 -5
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b451d9dca035b8a31711f51857d34261b6289a1
|
|
4
|
+
data.tar.gz: 7e9a82d17a90212e503183b3218fb7abba4d051c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94b9f0bd9412d2f17f2eb9e138298a9e02538c4c26e250856dc8c4de8a2c93fa7b5837a73d7c24a35cdcc3363d371da7e84f941fdb66ab637b8a37851a5e1ffc
|
|
7
|
+
data.tar.gz: ab973a795b79ab3b37e62fdbd45842a39b1a84754b3922d8c66f9566bba03221c7e7fec7350bad057ee11afa3629c37e673d04cf847783ce4f14a82a9866bbe3
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metrics/MethodLength:
|
|
2
|
+
Max: 20
|
|
3
|
+
|
|
4
|
+
Style/AsciiComments:
|
|
5
|
+
Enabled: false
|
|
6
|
+
|
|
7
|
+
Style/ClassCheck:
|
|
8
|
+
Exclude:
|
|
9
|
+
- lib/hairballs/plugin.rb
|
|
10
|
+
- lib/hairballs/plugins/object_ri.rb
|
|
11
|
+
|
|
12
|
+
Style/Documentation:
|
|
13
|
+
Exclude:
|
|
14
|
+
- lib/hairballs/version.rb
|
|
15
|
+
|
|
16
|
+
Style/DotPosition:
|
|
17
|
+
Enabled: false
|
|
18
|
+
|
|
19
|
+
Style/RescueModifier:
|
|
20
|
+
Exclude:
|
|
21
|
+
- lib/hairballs/plugins/colorize_json.rb
|
|
22
|
+
|
|
23
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
|
24
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/History.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
### 0.1.2 / 2015-04-13
|
|
2
|
+
|
|
3
|
+
* Improvements
|
|
4
|
+
* Used Rubocop for static analysis and clean-up.
|
|
5
|
+
* Started running tests on travis-ci.
|
|
6
|
+
* Bug Fixes
|
|
7
|
+
* [#4](https://github.com/turboladen/hairballs/issues/4) Fixed installing of
|
|
8
|
+
missing plugin/theme dependencies.
|
|
9
|
+
* [#5](https://github.com/turboladen/hairballs/issues/5) Fixed bad use of
|
|
10
|
+
`Hairballs.project_name` everywhere.
|
|
11
|
+
* Fixed bad link to my .irbrc in the README.
|
|
12
|
+
|
|
1
13
|
### 0.1.1 / 2015-04-06
|
|
2
14
|
|
|
3
15
|
* Bug Fixes
|
data/README.md
CHANGED
|
@@ -185,7 +185,7 @@ Check out the Hairballs::Plugin docs and existing plugins under
|
|
|
185
185
|
lib/hairballs/plugins/ for more details and ideas.
|
|
186
186
|
|
|
187
187
|
I've got my `.irbrc` (using Hairballs) stored on the interwebs
|
|
188
|
-
[here](https://github.com/turboladen/config_files/blob/master
|
|
188
|
+
[here](https://github.com/turboladen/config_files/blob/master/ruby/irbrc) if
|
|
189
189
|
that's of any help or interest.
|
|
190
190
|
|
|
191
191
|
But whyyyy?
|
data/Rakefile
CHANGED
data/lib/hairballs.rb
CHANGED
|
@@ -6,28 +6,28 @@ require 'hairballs/configuration'
|
|
|
6
6
|
class Hairballs
|
|
7
7
|
# @return [Hairballs::Configuration]
|
|
8
8
|
def self.config
|
|
9
|
-
|
|
9
|
+
@config ||= Hairballs::Configuration.new
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
class << self
|
|
13
13
|
extend Forwardable
|
|
14
14
|
|
|
15
15
|
def_delegators :config,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
:themes,
|
|
17
|
+
:add_theme,
|
|
18
|
+
:current_theme,
|
|
19
|
+
:use_theme,
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
:plugins,
|
|
22
|
+
:load_plugin,
|
|
23
|
+
:loaded_plugins,
|
|
24
|
+
:add_plugin,
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
:completion_procs,
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
:project_name,
|
|
29
|
+
:project_root,
|
|
30
|
+
:version,
|
|
31
|
+
:rails?
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -8,6 +8,8 @@ require 'hairballs/plugin'
|
|
|
8
8
|
require 'hairballs/version'
|
|
9
9
|
|
|
10
10
|
class Hairballs
|
|
11
|
+
# The base-level +Hairballs+ class maintains an object of this type, which
|
|
12
|
+
# contains the current configuration.
|
|
11
13
|
class Configuration
|
|
12
14
|
# @return [Array<Hairballs::Theme>]
|
|
13
15
|
attr_reader :themes
|
|
@@ -54,14 +56,14 @@ class Hairballs
|
|
|
54
56
|
#
|
|
55
57
|
# @return [Boolean]
|
|
56
58
|
def rails?
|
|
57
|
-
ENV.
|
|
59
|
+
ENV.key?('RAILS_ENV') || Kernel.const_defined?(:Rails)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
# Name of the project, if it can be determined. If not, defaults to "irb".
|
|
61
63
|
#
|
|
62
64
|
# @return [String]
|
|
63
65
|
def project_name
|
|
64
|
-
@project_name ||= project_root ? project_root.basename : nil
|
|
66
|
+
@project_name ||= project_root ? project_root.basename.to_s : nil
|
|
65
67
|
end
|
|
66
68
|
|
|
67
69
|
# @return [Pathname]
|
|
@@ -96,7 +98,7 @@ class Hairballs
|
|
|
96
98
|
# @param [Symbol] theme_name The name of the Theme to use/switch to.
|
|
97
99
|
def use_theme(theme_name)
|
|
98
100
|
switch_to = themes.find { |theme| theme.name == theme_name }
|
|
99
|
-
fail ThemeUseFailure
|
|
101
|
+
fail ThemeUseFailure, theme_name unless switch_to
|
|
100
102
|
vputs "Switched to theme: #{theme_name}"
|
|
101
103
|
|
|
102
104
|
switch_to.use!
|
|
@@ -126,7 +128,7 @@ class Hairballs
|
|
|
126
128
|
# @param plugin_name [Symbol]
|
|
127
129
|
def load_plugin(plugin_name, **options)
|
|
128
130
|
plugin_to_use = plugins.find { |plugin| plugin.name == plugin_name }
|
|
129
|
-
fail PluginNotFound
|
|
131
|
+
fail PluginNotFound, plugin_name unless plugin_to_use
|
|
130
132
|
vputs "Using plugin: #{plugin_name}"
|
|
131
133
|
|
|
132
134
|
plugin_to_use.load!(options)
|
|
@@ -150,7 +152,7 @@ class Hairballs
|
|
|
150
152
|
def root_by_git
|
|
151
153
|
_stdin, stdout, _stderr = Open3.popen3('git rev-parse --show-toplevel')
|
|
152
154
|
result = stdout.gets
|
|
153
|
-
|
|
155
|
+
|
|
154
156
|
result.nil? ? nil : Pathname.new(result.strip)
|
|
155
157
|
end
|
|
156
158
|
|
|
@@ -162,7 +164,11 @@ class Hairballs
|
|
|
162
164
|
cwd.ascend do |dir|
|
|
163
165
|
lib_dir = File.join(dir.to_s, 'lib')
|
|
164
166
|
|
|
165
|
-
|
|
167
|
+
child = dir.children.find do |c|
|
|
168
|
+
c.to_s =~ /#{lib_dir}/ && File.exist?(lib_dir)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
if child
|
|
166
172
|
root = Pathname.new(dir.to_s)
|
|
167
173
|
break
|
|
168
174
|
end
|
data/lib/hairballs/exceptions.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
class Hairballs
|
|
2
|
+
# Used when Hairballs tries to load a plugin, but the plugin cannot be found.
|
|
2
3
|
class PluginNotFound < RuntimeError
|
|
3
4
|
def initialize(plugin_name)
|
|
4
5
|
message = "Plugin not found: :#{plugin_name}."
|
|
@@ -6,6 +7,8 @@ class Hairballs
|
|
|
6
7
|
end
|
|
7
8
|
end
|
|
8
9
|
|
|
10
|
+
# Used when Hairballs tries to load plugin, but the plugin could not be
|
|
11
|
+
# loaded.
|
|
9
12
|
class PluginLoadFailure < RuntimeError
|
|
10
13
|
def initialize(plugin_name)
|
|
11
14
|
message = "Unable to load plugin: :#{plugin_name}."
|
|
@@ -13,6 +16,7 @@ class Hairballs
|
|
|
13
16
|
end
|
|
14
17
|
end
|
|
15
18
|
|
|
19
|
+
# Used when Hairballs tries to load theme, but the theme could not be loaded.
|
|
16
20
|
class ThemeUseFailure < RuntimeError
|
|
17
21
|
def initialize(theme_name)
|
|
18
22
|
message = "Theme not found: :#{theme_name}."
|
|
@@ -8,10 +8,10 @@ class Hairballs
|
|
|
8
8
|
return @libraries if @libraries && libs.nil?
|
|
9
9
|
|
|
10
10
|
@libraries = if libs
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
libs
|
|
12
|
+
else
|
|
13
|
+
yield([])
|
|
14
|
+
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Requires #libraries on load. If they're not installed, install them. If
|
|
@@ -19,25 +19,18 @@ class Hairballs
|
|
|
19
19
|
def require_libraries
|
|
20
20
|
return if @libraries.nil?
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
install_threads = []
|
|
23
|
+
require_threads = []
|
|
24
|
+
require_queue = Queue.new
|
|
24
25
|
|
|
26
|
+
@libraries.each do |lib|
|
|
25
27
|
begin
|
|
26
|
-
next if retry_count == 2
|
|
27
28
|
vputs "Requiring library: #{lib}"
|
|
28
29
|
require lib
|
|
29
30
|
rescue LoadError
|
|
30
31
|
puts "#{lib} not installed; installing now..."
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if Hairballs.rails?
|
|
34
|
-
installed_gem = find_latest_gem(lib)
|
|
35
|
-
$LOAD_PATH.unshift("#{installed_gem}/lib")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
require lib
|
|
39
|
-
retry_count += 1
|
|
40
|
-
retry
|
|
32
|
+
install_threads << start_install_thread(lib, require_queue)
|
|
33
|
+
require_threads << start_require_thread(require_queue)
|
|
41
34
|
end
|
|
42
35
|
end
|
|
43
36
|
end
|
|
@@ -45,7 +38,7 @@ class Hairballs
|
|
|
45
38
|
# Path to the highest version of the gem with the given gem.
|
|
46
39
|
#
|
|
47
40
|
# @param [String] gem_name
|
|
48
|
-
# @return [String]
|
|
41
|
+
# @return [String] The path to the latest install of +gem_name+.
|
|
49
42
|
def find_latest_gem(gem_name)
|
|
50
43
|
the_gem = Dir.glob("#{Gem.dir}/gems/#{gem_name}-*")
|
|
51
44
|
|
|
@@ -84,5 +77,42 @@ class Hairballs
|
|
|
84
77
|
vputs 'Bundler not defined. Skipping.'
|
|
85
78
|
end
|
|
86
79
|
end
|
|
80
|
+
|
|
81
|
+
#--------------------------------------------------------------------------
|
|
82
|
+
# Privates
|
|
83
|
+
#--------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
# @param [String] lib Gem to install.
|
|
88
|
+
# @param [Queue] require_queue Queue to push library names onto so the
|
|
89
|
+
# require thread can do its requiring.
|
|
90
|
+
# @return [Thread]
|
|
91
|
+
def start_install_thread(lib, require_queue)
|
|
92
|
+
Thread.new do
|
|
93
|
+
result = Gem.install(lib)
|
|
94
|
+
|
|
95
|
+
if result.empty?
|
|
96
|
+
puts "Unable to install gem '#{lib}'. Moving on..."
|
|
97
|
+
else
|
|
98
|
+
require_queue << lib
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @param [Queue] require_queue
|
|
104
|
+
# @return [Thread]
|
|
105
|
+
def start_require_thread(require_queue)
|
|
106
|
+
Thread.new do
|
|
107
|
+
lib = require_queue.pop
|
|
108
|
+
|
|
109
|
+
if Hairballs.config.rails?
|
|
110
|
+
installed_gem = find_latest_gem(lib)
|
|
111
|
+
$LOAD_PATH.unshift("#{installed_gem}/lib")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
require lib
|
|
115
|
+
end.join
|
|
116
|
+
end
|
|
87
117
|
end
|
|
88
118
|
end
|
data/lib/hairballs/plugin.rb
CHANGED
|
@@ -7,13 +7,13 @@ class Hairballs
|
|
|
7
7
|
# be.
|
|
8
8
|
#
|
|
9
9
|
# One benefit of making a simple plugin for requiring other deps is
|
|
10
|
-
# Hairballs::LibraryHelpers#require_libraries method.
|
|
11
|
-
# Hairballs::LibraryHelpers#libraries, you don't have to
|
|
12
|
-
# gems before using IRB.
|
|
13
|
-
# manager (RVM, rbenv, etc) and you install a new
|
|
14
|
-
# ahead to install your IRB deps, your IRB session
|
|
15
|
-
# want; well, not until you `exit` and fix the problem.
|
|
16
|
-
# helps alleviate that small headache.
|
|
10
|
+
# Hairballs::LibraryHelpers#require_libraries method. When used in
|
|
11
|
+
# conjunction with Hairballs::LibraryHelpers#libraries, you don't have to
|
|
12
|
+
# worry about installing the gems before using IRB. This is particularly
|
|
13
|
+
# helpful when using a Ruby manager (RVM, rbenv, etc) and you install a new
|
|
14
|
+
# Ruby; if you don't think ahead to install your IRB deps, your IRB session
|
|
15
|
+
# won't behave like you want; well, not until you `exit` and fix the problem.
|
|
16
|
+
# This simple pattern helps alleviate that small headache.
|
|
17
17
|
#
|
|
18
18
|
# Next, Hairballs Plugins are lazily loaded; `require`ing their source files
|
|
19
19
|
# doesn't mean the methods and such that you add there will do anything; it's
|
|
@@ -69,7 +69,7 @@ class Hairballs
|
|
|
69
69
|
if @on_load.kind_of?(Proc)
|
|
70
70
|
@on_load.call
|
|
71
71
|
else
|
|
72
|
-
fail PluginLoadFailure,
|
|
72
|
+
fail PluginLoadFailure, name
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
end
|
|
@@ -19,8 +19,10 @@ Hairballs.add_plugin(:colorize_json, color: :blue) do |plugin|
|
|
|
19
19
|
|
|
20
20
|
if is_json
|
|
21
21
|
vputs "[#{plugin.name}] Return value is JSON-like"
|
|
22
|
-
|
|
23
|
-
JSON.
|
|
22
|
+
the_json = JSON.pretty_generate(
|
|
23
|
+
JSON.parse(@context.last_value)
|
|
24
|
+
).colorize(plugin.color)
|
|
25
|
+
printf @context.return_format, the_json
|
|
24
26
|
else
|
|
25
27
|
old_output_value
|
|
26
28
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
require 'hairballs'
|
|
2
2
|
|
|
3
|
-
Hairballs.add_plugin(:irb_history, save_history: 1000,
|
|
3
|
+
Hairballs.add_plugin(:irb_history, save_history: 1000,
|
|
4
|
+
eval_history: 20,
|
|
5
|
+
global_history_file: true) do |plugin|
|
|
4
6
|
plugin.libraries %w(irb/ext/save-history)
|
|
5
7
|
|
|
6
8
|
plugin.on_load do
|
|
@@ -11,7 +13,7 @@ Hairballs.add_plugin(:irb_history, save_history: 1000, eval_history: 20, global_
|
|
|
11
13
|
IRB.conf[:HISTORY_FILE] = "#{Dir.home}/.irb_history"
|
|
12
14
|
|
|
13
15
|
if Hairballs.project_name
|
|
14
|
-
IRB.conf[:HISTORY_FILE] << Hairballs.project_name
|
|
16
|
+
IRB.conf[:HISTORY_FILE] << Hairballs.project_name
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
@@ -12,7 +12,8 @@ require 'hairballs'
|
|
|
12
12
|
# The +completion_append_character+ is really a Readline option that tells it
|
|
13
13
|
# what to do when you tab-complete a term. It's set to not add anything to the
|
|
14
14
|
# completed term, but you may find it suits you better to append a single space.
|
|
15
|
-
Hairballs.add_plugin(:tab_completion_for_files,
|
|
15
|
+
Hairballs.add_plugin(:tab_completion_for_files,
|
|
16
|
+
completion_append_character: nil) do |plugin|
|
|
16
17
|
plugin.on_load do
|
|
17
18
|
Hairballs.completion_procs << proc do |string|
|
|
18
19
|
Dir[string + '*'].grep(/^#{Regexp.escape(string)}/)
|
|
@@ -22,7 +23,7 @@ Hairballs.add_plugin(:tab_completion_for_files, completion_append_character: nil
|
|
|
22
23
|
Hairballs.completion_procs << ::IRB::InputCompletor::CompletionProc
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
completion_proc =
|
|
26
|
+
completion_proc = proc do |string|
|
|
26
27
|
Hairballs.completion_procs.map do |proc|
|
|
27
28
|
proc.call(string)
|
|
28
29
|
end.flatten.uniq
|
|
@@ -17,12 +17,14 @@ Hairballs.add_theme(:turboladen) do |theme|
|
|
|
17
17
|
else
|
|
18
18
|
[]
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
libs_to_require
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
theme.prompt do |prompt|
|
|
23
25
|
preface = proc do |status = ' '|
|
|
24
26
|
if Hairballs.project_name
|
|
25
|
-
"⟪#{Hairballs.project_name.
|
|
27
|
+
"⟪#{Hairballs.project_name.light_blue}⟫#{status}%03n"
|
|
26
28
|
else
|
|
27
29
|
"❨#{'irb'.light_blue}❩#{status}%03n"
|
|
28
30
|
end
|
data/lib/hairballs/version.rb
CHANGED
|
@@ -97,7 +97,8 @@ RSpec.describe Hairballs::Configuration do
|
|
|
97
97
|
|
|
98
98
|
context 'block given and name param is a Symbol' do
|
|
99
99
|
before do
|
|
100
|
-
expect(Hairballs::Plugin).to receive(:new).with(:test, {}).
|
|
100
|
+
expect(Hairballs::Plugin).to receive(:new).with(:test, {}).
|
|
101
|
+
and_return plugin
|
|
101
102
|
end
|
|
102
103
|
|
|
103
104
|
it 'yields the Plugin' do
|
|
@@ -165,22 +166,37 @@ RSpec.describe Hairballs::Configuration do
|
|
|
165
166
|
end
|
|
166
167
|
|
|
167
168
|
describe '.project_name' do
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
context '#project_root exists' do
|
|
170
|
+
let(:project_root) { Pathname.new('meow') }
|
|
171
|
+
|
|
172
|
+
before do
|
|
173
|
+
expect(subject).to receive(:project_root).and_return(project_root).
|
|
174
|
+
exactly(2).times
|
|
175
|
+
end
|
|
171
176
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
it 'is the name of the project root' do
|
|
178
|
+
expect(config.project_name).to eq 'meow'
|
|
179
|
+
end
|
|
175
180
|
end
|
|
176
181
|
|
|
177
|
-
|
|
182
|
+
context '#project_root does not exist' do
|
|
183
|
+
before { expect(subject).to receive(:project_root).and_return(nil) }
|
|
184
|
+
|
|
185
|
+
it 'is nil' do
|
|
186
|
+
expect(config.project_name).to be_nil
|
|
187
|
+
end
|
|
188
|
+
end
|
|
178
189
|
end
|
|
179
190
|
|
|
180
191
|
describe '.rails?' do
|
|
181
192
|
subject { config.rails? }
|
|
182
193
|
|
|
183
194
|
context 'not using Rails' do
|
|
195
|
+
before do
|
|
196
|
+
ENV.delete('RAILS_ENV')
|
|
197
|
+
Object.send(:remove_const, :Rails) if Kernel.const_defined? :Rails
|
|
198
|
+
end
|
|
199
|
+
|
|
184
200
|
it { is_expected.to eq false }
|
|
185
201
|
end
|
|
186
202
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
+
require 'hairballs'
|
|
2
3
|
require 'hairballs/library_helpers'
|
|
3
4
|
|
|
4
5
|
RSpec.describe Hairballs::LibraryHelpers do
|
|
@@ -11,30 +12,30 @@ RSpec.describe Hairballs::LibraryHelpers do
|
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
it 'allows adding to the yielded array' do
|
|
14
|
-
expect
|
|
15
|
+
expect do
|
|
15
16
|
subject.libraries do |libs|
|
|
16
17
|
libs << 'meow'
|
|
17
18
|
end
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
end.to change { subject.instance_variable_get(:@libraries) }.
|
|
20
|
+
from(nil).to(['meow'])
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
context 'block not given' do
|
|
24
25
|
it 'sets @libraries to the given param' do
|
|
25
|
-
expect
|
|
26
|
+
expect do
|
|
26
27
|
subject.libraries(['meow'])
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
end.to change { subject.instance_variable_get(:@libraries) }.
|
|
29
|
+
from(nil).to(['meow'])
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
context 'block AND param given' do
|
|
33
34
|
it 'sets @libraries to the param value' do
|
|
34
|
-
expect
|
|
35
|
+
expect do
|
|
35
36
|
subject.libraries(['meow'])
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
end.to change { subject.instance_variable_get(:@libraries) }.
|
|
38
|
+
from(nil).to(['meow'])
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
end
|
|
@@ -47,18 +48,21 @@ RSpec.describe Hairballs::LibraryHelpers do
|
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
context '@libraries is not nil' do
|
|
51
|
+
let(:lib_name) { 'asdfqwer' }
|
|
52
|
+
|
|
50
53
|
before do
|
|
51
|
-
subject.instance_variable_set(:@libraries,
|
|
54
|
+
subject.instance_variable_set(:@libraries, [lib_name])
|
|
52
55
|
allow(subject).to receive(:vputs)
|
|
53
|
-
Hairballs.define_singleton_method(:rails?) { nil }
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
context 'libraries are not installed' do
|
|
57
59
|
it 'tries two times to require then Gem.install' do
|
|
58
|
-
expect(subject).to receive(:
|
|
59
|
-
|
|
60
|
+
expect(subject).to receive(:start_install_thread).
|
|
61
|
+
with(lib_name, instance_of(Queue))
|
|
62
|
+
expect(subject).to receive(:start_require_thread).
|
|
63
|
+
with(instance_of(Queue))
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
subject.require_libraries
|
|
62
66
|
end
|
|
63
67
|
end
|
|
64
68
|
end
|
|
@@ -69,4 +73,65 @@ RSpec.describe Hairballs::LibraryHelpers do
|
|
|
69
73
|
expect(subject.find_latest_gem('rake')).to match %r{gems/rake}
|
|
70
74
|
end
|
|
71
75
|
end
|
|
76
|
+
|
|
77
|
+
describe '#start_install_thread' do
|
|
78
|
+
before { allow(Thread).to receive(:new).and_yield }
|
|
79
|
+
let(:require_queue) { instance_double 'Queue' }
|
|
80
|
+
let(:lib_name) { 'some lib' }
|
|
81
|
+
|
|
82
|
+
context 'gem exists' do
|
|
83
|
+
let(:gem) { double 'Gem::Specification' }
|
|
84
|
+
|
|
85
|
+
it 'puts the library name on the require_queue' do
|
|
86
|
+
expect(Gem).to receive(:install).with(lib_name).and_return([gem])
|
|
87
|
+
expect(require_queue).to receive(:<<).with(lib_name)
|
|
88
|
+
|
|
89
|
+
subject.send(:start_install_thread, lib_name, require_queue)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'gem does not exist' do
|
|
94
|
+
it 'does not put the library name on the require_queue' do
|
|
95
|
+
expect(Gem).to receive(:install).with(lib_name).and_return([])
|
|
96
|
+
expect(require_queue).to_not receive(:<<)
|
|
97
|
+
|
|
98
|
+
subject.send(:start_install_thread, lib_name, require_queue)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe '#start_require_thread' do
|
|
104
|
+
let(:require_queue) { instance_double 'Queue' }
|
|
105
|
+
let(:lib_name) { 'test name' }
|
|
106
|
+
let(:thread) { instance_double('Thread', join: nil) }
|
|
107
|
+
before { allow(Thread).to receive(:new).and_yield.and_return(thread) }
|
|
108
|
+
|
|
109
|
+
context 'rails' do
|
|
110
|
+
before { expect(Hairballs.config).to receive(:rails?).and_return(true) }
|
|
111
|
+
|
|
112
|
+
it 'finds the latest gem and adds it to the load path' do
|
|
113
|
+
lib_path = 'path to lib'
|
|
114
|
+
expect(require_queue).to receive(:pop).and_return(lib_name)
|
|
115
|
+
expect(subject).to receive(:find_latest_gem).with(lib_name).
|
|
116
|
+
and_return(lib_path)
|
|
117
|
+
expect($LOAD_PATH).to receive(:unshift).with('path to lib/lib')
|
|
118
|
+
expect(subject).to receive(:require).with(lib_name)
|
|
119
|
+
|
|
120
|
+
subject.send(:start_require_thread, require_queue)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'not rails' do
|
|
125
|
+
before { expect(Hairballs.config).to receive(:rails?).and_return(false) }
|
|
126
|
+
|
|
127
|
+
it 'does not find the latest gem and add it to the load path' do
|
|
128
|
+
expect(require_queue).to receive(:pop).and_return(lib_name)
|
|
129
|
+
expect(subject).to_not receive(:find_latest_gem)
|
|
130
|
+
expect($LOAD_PATH).to_not receive(:unshift)
|
|
131
|
+
expect(subject).to receive(:require).with(lib_name)
|
|
132
|
+
|
|
133
|
+
subject.send(:start_require_thread, require_queue)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
72
137
|
end
|
|
@@ -22,10 +22,10 @@ RSpec.describe Hairballs::Plugin do
|
|
|
22
22
|
let(:the_block) { proc { puts 'hi' } }
|
|
23
23
|
|
|
24
24
|
it 'stores the given block' do
|
|
25
|
-
expect
|
|
25
|
+
expect do
|
|
26
26
|
subject.on_load(&the_block)
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
end.to change { subject.instance_variable_get(:@on_load) }.
|
|
28
|
+
from(nil).to(the_block)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -51,7 +51,7 @@ RSpec.describe Hairballs::Plugin do
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
context 'with @on_load set to a Proc' do
|
|
54
|
-
let(:on_load) { double 'Proc',
|
|
54
|
+
let(:on_load) { double 'Proc', kind_of?: true }
|
|
55
55
|
before { subject.instance_variable_set(:@on_load, on_load) }
|
|
56
56
|
|
|
57
57
|
it 'calls the on_load Proc' do
|
|
@@ -61,7 +61,7 @@ RSpec.describe Hairballs::Plugin do
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
context 'with @on_load set to not a Proc' do
|
|
64
|
-
let(:on_load) { double 'Proc',
|
|
64
|
+
let(:on_load) { double 'Proc', kind_of?: false }
|
|
65
65
|
before { subject.instance_variable_set(:@on_load, on_load) }
|
|
66
66
|
|
|
67
67
|
it 'raises a PluginLoadFailure' do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../lib/hairballs', File.dirname(__FILE__)))
|
|
2
2
|
|
|
3
3
|
RSpec.configure do |config|
|
|
4
4
|
config.expect_with :rspec do |expectations|
|
|
@@ -19,8 +19,8 @@ RSpec.configure do |config|
|
|
|
19
19
|
mocks.verify_partial_doubles = true
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# The settings below are suggested to provide a good initial experience
|
|
23
|
-
# with RSpec, but feel free to customize to your heart's content.
|
|
22
|
+
# The settings below are suggested to provide a good initial experience
|
|
23
|
+
# with RSpec, but feel free to customize to your heart's content.
|
|
24
24
|
# These two settings work together to allow you to limit a spec run
|
|
25
25
|
# to individual examples or groups you care about by tagging them with
|
|
26
26
|
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
|
@@ -28,8 +28,8 @@ RSpec.configure do |config|
|
|
|
28
28
|
# config.filter_run :focus
|
|
29
29
|
# config.run_all_when_everything_filtered = true
|
|
30
30
|
|
|
31
|
-
# Limits the available syntax to the non-monkey patched syntax that is
|
|
32
|
-
# For more details, see:
|
|
31
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
|
32
|
+
# recommended. For more details, see:
|
|
33
33
|
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
|
34
34
|
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
35
35
|
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hairballs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Loveless
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-04-
|
|
11
|
+
date: 2015-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -61,6 +61,8 @@ extra_rdoc_files: []
|
|
|
61
61
|
files:
|
|
62
62
|
- ".gitignore"
|
|
63
63
|
- ".rspec"
|
|
64
|
+
- ".rubocop.yml"
|
|
65
|
+
- ".travis.yml"
|
|
64
66
|
- Gemfile
|
|
65
67
|
- History.md
|
|
66
68
|
- LICENSE.txt
|
|
@@ -124,3 +126,4 @@ test_files:
|
|
|
124
126
|
- spec/hairballs/theme_spec.rb
|
|
125
127
|
- spec/hairballs_spec.rb
|
|
126
128
|
- spec/spec_helper.rb
|
|
129
|
+
has_rdoc:
|