hirber 0.8.0 → 0.8.5
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/.gemspec +45 -11
- data/CHANGELOG.rdoc +15 -0
- data/README.md +232 -0
- data/README.rdoc +7 -1
- data/Rakefile +14 -8
- data/lib/hirb/helpers/table.rb +349 -325
- data/lib/hirb/helpers/unicode_table.rb +29 -6
- data/lib/hirb/version.rb +1 -1
- data/lib/hirb/view.rb +50 -11
- data/lib/{hirb.rb → hirber.rb} +0 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/view_spec.rb +288 -0
- data/spec/views_spec.rb +54 -0
- data/test/test_helper.rb +9 -5
- metadata +63 -15
@@ -1,12 +1,35 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class Hirb::Helpers::UnicodeTable < Hirb::Helpers::Table
|
3
3
|
CHARS = {
|
4
|
-
:top => {
|
5
|
-
:
|
6
|
-
|
7
|
-
|
8
|
-
:
|
9
|
-
|
4
|
+
:top => {
|
5
|
+
:left => "┌",
|
6
|
+
:center => "┬",
|
7
|
+
:right => "┐",
|
8
|
+
:horizontal => "─",
|
9
|
+
:vertical => {
|
10
|
+
:outside => "│",
|
11
|
+
:inside => "│",
|
12
|
+
},
|
13
|
+
},
|
14
|
+
|
15
|
+
:middle => {
|
16
|
+
:left => "├",
|
17
|
+
:center => "┼",
|
18
|
+
:right => "┤",
|
19
|
+
:horizontal => "─",
|
20
|
+
},
|
21
|
+
|
22
|
+
:bottom => {
|
23
|
+
:left => "└",
|
24
|
+
:center => "┴",
|
25
|
+
:right => "┘",
|
26
|
+
:horizontal => "─",
|
27
|
+
:vertical => {
|
28
|
+
:outside => "│",
|
29
|
+
:inside => "╎",
|
30
|
+
},
|
31
|
+
},
|
32
|
+
}.freeze
|
10
33
|
|
11
34
|
# Renders a unicode table
|
12
35
|
def self.render(rows, options={})
|
data/lib/hirb/version.rb
CHANGED
data/lib/hirb/view.rb
CHANGED
@@ -108,17 +108,25 @@ module Hirb
|
|
108
108
|
config[:formatter] = !config[:formatter]
|
109
109
|
end
|
110
110
|
|
111
|
-
# Resizes the console width and height for use with the table and pager
|
112
|
-
#
|
113
|
-
#
|
111
|
+
# Resizes the console width and height for use with the table and pager
|
112
|
+
# i.e. after having resized the console window. *nix users should only
|
113
|
+
# have to call this method. Non-*nix users should call this method with
|
114
|
+
# explicit width and height. If you don't know your width and height, in
|
115
|
+
# irb play with "a"* width to find width and puts "a\n" * height to find
|
116
|
+
# height.
|
117
|
+
|
114
118
|
def resize(width=nil, height=nil)
|
115
119
|
config[:width], config[:height] = determine_terminal_size(width, height)
|
116
120
|
pager.resize(config[:width], config[:height])
|
117
121
|
end
|
118
122
|
|
119
|
-
# This is the main method of this class. When view is enabled,
|
120
|
-
#
|
121
|
-
#
|
123
|
+
# This is the main method of this class. When view is enabled,
|
124
|
+
# this method searches for a formatter it can use for the output
|
125
|
+
# and if successful renders it using render_method(). The options
|
126
|
+
# this method takes are helper config hashes as described in
|
127
|
+
# Hirb::Formatter.format_output(). Returns true if successful and false
|
128
|
+
# if no formatting is done or if not enabled.
|
129
|
+
|
122
130
|
def view_output(output, options={})
|
123
131
|
enabled? && config[:formatter] && render_output(output, options)
|
124
132
|
rescue Exception=>e
|
@@ -179,20 +187,51 @@ module Hirb
|
|
179
187
|
if defined?(Ripl) && Ripl.respond_to?(:started?) && Ripl.started?
|
180
188
|
@output_method = true
|
181
189
|
require 'ripl/hirb' unless defined? Ripl::Hirb
|
182
|
-
|
190
|
+
end
|
191
|
+
|
192
|
+
if defined? Pry
|
193
|
+
original_print = Pry.config.print
|
194
|
+
|
195
|
+
Pry.config.print = proc do |output, result, pry_instance|
|
196
|
+
Hirb::View.view_or_page_output(result) ||
|
197
|
+
original_print.call(output, result, pry_instance)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
if defined?(IRB::Irb)
|
183
202
|
@output_method = true
|
203
|
+
|
184
204
|
::IRB::Irb.class_eval do
|
185
205
|
alias_method :non_hirb_view_output, :output_value
|
186
|
-
|
187
|
-
|
206
|
+
|
207
|
+
def output_value(omit = false) #:nodoc:
|
208
|
+
Hirb::View.view_or_page_output(@context.last_value) ||
|
209
|
+
original_output_value(omit)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Do not pass the value if the default is given to keep backwards
|
213
|
+
# compatiblity for Ruby =< 2.7.1
|
214
|
+
|
215
|
+
if !instance_methods(false).include?(:original_output_value)
|
216
|
+
def original_output_value(omit)
|
217
|
+
if omit
|
218
|
+
non_hirb_view_output(omit)
|
219
|
+
else
|
220
|
+
non_hirb_view_output
|
221
|
+
end
|
222
|
+
end
|
188
223
|
end
|
189
224
|
end
|
190
225
|
end
|
191
226
|
end
|
192
227
|
|
193
228
|
def disable_output_method
|
194
|
-
if defined?(IRB::Irb) && !defined?
|
195
|
-
::IRB::Irb.
|
229
|
+
if defined?(IRB::Irb) && !defined?(Ripl)
|
230
|
+
::IRB::Irb.class_eval do
|
231
|
+
undef output_value
|
232
|
+
|
233
|
+
alias_method :output_value, :non_hirb_view_output
|
234
|
+
end
|
196
235
|
end
|
197
236
|
@output_method = nil
|
198
237
|
end
|
data/lib/{hirb.rb → hirber.rb}
RENAMED
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module RSpec::Helpers
|
2
|
+
ENV["LINES"] = ENV["COLUMNS"] = "20"
|
3
|
+
|
4
|
+
def reset_config
|
5
|
+
Hirb::View.instance_eval do
|
6
|
+
@config = nil
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def capture_stderr(&block)
|
11
|
+
original_stderr = $stderr
|
12
|
+
$stderr = fake = StringIO.new
|
13
|
+
begin
|
14
|
+
yield
|
15
|
+
ensure
|
16
|
+
$stderr = original_stderr
|
17
|
+
end
|
18
|
+
fake.string
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset_terminal_size
|
22
|
+
ENV["LINES"] = ENV["COLUMNS"] = "20"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ::IRB
|
27
|
+
class Irb
|
28
|
+
def initialize(context)
|
29
|
+
@context = context
|
30
|
+
end
|
31
|
+
|
32
|
+
def output_value; end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require "pry"
|
37
|
+
|
38
|
+
RSpec.configure do |config|
|
39
|
+
include RSpec::Helpers
|
40
|
+
|
41
|
+
config.expect_with :rspec do |expectations|
|
42
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
43
|
+
end
|
44
|
+
|
45
|
+
config.mock_with :rspec do |mocks|
|
46
|
+
mocks.verify_partial_doubles = true
|
47
|
+
end
|
48
|
+
|
49
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
50
|
+
config.filter_run_when_matching :focus
|
51
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
52
|
+
config.disable_monkey_patching!
|
53
|
+
config.warnings = true
|
54
|
+
|
55
|
+
if config.files_to_run.one?
|
56
|
+
config.default_formatter = "doc"
|
57
|
+
end
|
58
|
+
|
59
|
+
config.profile_examples = 5
|
60
|
+
config.order = :random
|
61
|
+
|
62
|
+
Kernel.srand config.seed
|
63
|
+
end
|
data/spec/view_spec.rb
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
require "hirber"
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
RSpec.describe "Hirb::View" do
|
5
|
+
it "page_output pages when view is enabled" do
|
6
|
+
reset_config
|
7
|
+
|
8
|
+
Hirb.enable
|
9
|
+
|
10
|
+
allow(Hirb::View.pager).to receive_messages(activated_by?: true)
|
11
|
+
expect(Hirb::View.pager).to receive(:page)
|
12
|
+
expect(Hirb::View.page_output("blah")).to be(true)
|
13
|
+
|
14
|
+
Hirb.disable
|
15
|
+
end
|
16
|
+
|
17
|
+
it "page_output doesn't page when view is disabled" do
|
18
|
+
Hirb.enable
|
19
|
+
Hirb.disable
|
20
|
+
|
21
|
+
allow(Hirb::View.pager).to receive_messages(activated_by?: true)
|
22
|
+
|
23
|
+
expect(Hirb::View.pager).not_to receive(:page)
|
24
|
+
expect(Hirb::View.page_output("blah")).to be(false)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "view_output catches unexpected errors and prints them" do
|
28
|
+
reset_config
|
29
|
+
|
30
|
+
Hirb.enable
|
31
|
+
|
32
|
+
allow(::Hirb::View).to receive(:render_output).and_raise("error")
|
33
|
+
|
34
|
+
expect(capture_stderr { Hirb::View.view_output([1,2,3]) })
|
35
|
+
.to match(/Hirb Error: error/)
|
36
|
+
|
37
|
+
Hirb.disable
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "enable" do
|
41
|
+
before { reset_config }
|
42
|
+
|
43
|
+
after { Hirb.disable }
|
44
|
+
|
45
|
+
it "redefines irb output_value" do
|
46
|
+
expect(Hirb::View).to receive(:render_output)
|
47
|
+
|
48
|
+
Hirb.enable
|
49
|
+
|
50
|
+
context_stub = double(last_value: "")
|
51
|
+
|
52
|
+
::IRB::Irb.new(context_stub).output_value
|
53
|
+
end
|
54
|
+
|
55
|
+
it "is enabled?" do
|
56
|
+
reset_config
|
57
|
+
|
58
|
+
Hirb.enable
|
59
|
+
|
60
|
+
expect(Hirb::View).to be_enabled
|
61
|
+
end
|
62
|
+
|
63
|
+
def output_class_config(klass)
|
64
|
+
{ :output=>{klass=>{:class=>:auto_table}} }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets formatter config" do
|
68
|
+
class_hash = {"Something::Base"=>{:class=>"BlahBlah"}}
|
69
|
+
|
70
|
+
Hirb.enable :output => class_hash
|
71
|
+
|
72
|
+
expect(Hirb::View.formatter_config["Something::Base"])
|
73
|
+
.to eq class_hash["Something::Base"]
|
74
|
+
end
|
75
|
+
|
76
|
+
it "when called multiple times merges configs" do
|
77
|
+
Hirb.config = nil
|
78
|
+
# default config + config_file
|
79
|
+
|
80
|
+
allow(Hirb)
|
81
|
+
.to receive_messages(
|
82
|
+
read_config_file: output_class_config("Regexp"),
|
83
|
+
)
|
84
|
+
|
85
|
+
Hirb.enable output_class_config("String")
|
86
|
+
|
87
|
+
# add config file and explicit config
|
88
|
+
[{:config_file=>"ok"}, output_class_config("Struct")].each do |config|
|
89
|
+
expect(Hirb)
|
90
|
+
.to receive(:read_config_file)
|
91
|
+
.and_return(
|
92
|
+
output_class_config('ActiveRecord::Base'),
|
93
|
+
output_class_config('Array'),
|
94
|
+
)
|
95
|
+
|
96
|
+
Hirb.enable config
|
97
|
+
end
|
98
|
+
|
99
|
+
expect(Hirb.config_files.include?("ok")).to eq(true)
|
100
|
+
|
101
|
+
output_keys = %w{ActiveRecord::Base Array Regexp String Struct}
|
102
|
+
|
103
|
+
expect(Hirb::View.config[:output].keys.sort).to eq output_keys
|
104
|
+
end
|
105
|
+
|
106
|
+
xit "when called multiple times without config doesn't affect config" do
|
107
|
+
# FIXME: 2021-02-14 - This flapping, spec is order dependant
|
108
|
+
|
109
|
+
Hirb.enable
|
110
|
+
|
111
|
+
old_config = Hirb::View.config
|
112
|
+
|
113
|
+
expect(Hirb).not_to receive(:read_config_file)
|
114
|
+
expect(Hirb::View).not_to receive(:load_config)
|
115
|
+
|
116
|
+
# Hirb.expects(:read_config_file).never
|
117
|
+
# Hirb::View.expects(:load_config).never
|
118
|
+
|
119
|
+
Hirb.enable
|
120
|
+
|
121
|
+
expect(Hirb::View.config).to eq old_config
|
122
|
+
end
|
123
|
+
|
124
|
+
xit "works without irb" do
|
125
|
+
# FIXME: 2021-02-14 - This flapping, spec is order dependant
|
126
|
+
|
127
|
+
allow(Object)
|
128
|
+
.to receive(:const_defined?)
|
129
|
+
.with(:IRB)
|
130
|
+
.and_return(false)
|
131
|
+
|
132
|
+
Hirb.enable
|
133
|
+
|
134
|
+
expect(Hirb::View.formatter.config.size).to be > 1
|
135
|
+
end
|
136
|
+
|
137
|
+
it "sets up configuration for IRB and Pry if they're both defined" do
|
138
|
+
Hirb.disable
|
139
|
+
expect(Pry.config).to receive(:print=)
|
140
|
+
expect {
|
141
|
+
Hirb.enable
|
142
|
+
}.to change {
|
143
|
+
::IRB::Irb.instance_method(:output_value) == ::IRB::Irb.instance_method(:non_hirb_view_output)
|
144
|
+
}.from(true).to(false)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "with config_file option adds to config_file" do
|
148
|
+
Hirb.enable :config_file => "test_file"
|
149
|
+
|
150
|
+
expect(Hirb.config_files.include?("test_file")).to be(true)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "with ignore_errors enable option" do
|
154
|
+
Hirb.enable :ignore_errors => true
|
155
|
+
|
156
|
+
expect(Hirb::View)
|
157
|
+
.to receive(:render_output)
|
158
|
+
.and_raise(Exception, "Ex mesg")
|
159
|
+
.twice
|
160
|
+
|
161
|
+
capture_stderr do
|
162
|
+
expect(Hirb::View.view_output("")).to eq(false)
|
163
|
+
end
|
164
|
+
|
165
|
+
expect(capture_stderr { Hirb::View.view_output("") })
|
166
|
+
.to match(/Error: Ex mesg/)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "resize" do
|
171
|
+
def pager; Hirb::View.pager; end
|
172
|
+
|
173
|
+
before do
|
174
|
+
Hirb::View.pager = nil
|
175
|
+
reset_config
|
176
|
+
Hirb.enable
|
177
|
+
end
|
178
|
+
|
179
|
+
after { Hirb.disable }
|
180
|
+
|
181
|
+
it "changes width and height with stty" do
|
182
|
+
if RUBY_PLATFORM[/java/]
|
183
|
+
allow(Hirb::Util)
|
184
|
+
.to receive(:command_exists?)
|
185
|
+
.with("tput")
|
186
|
+
.and_returns(false)
|
187
|
+
end
|
188
|
+
|
189
|
+
allow(STDIN)
|
190
|
+
.to receive(:tty?)
|
191
|
+
.and_return(true)
|
192
|
+
|
193
|
+
allow(Hirb::Util)
|
194
|
+
.to receive(:command_exists?)
|
195
|
+
.with("stty")
|
196
|
+
.and_return(true)
|
197
|
+
|
198
|
+
ENV["COLUMNS"] = ENV["LINES"] = nil # bypasses env usage
|
199
|
+
|
200
|
+
capture_stderr { Hirb::View.resize }
|
201
|
+
|
202
|
+
expect(pager.width).not_to eq 10
|
203
|
+
expect(pager.height).not_to eq 10
|
204
|
+
|
205
|
+
reset_terminal_size
|
206
|
+
end
|
207
|
+
|
208
|
+
it "changes width and height with ENV" do
|
209
|
+
ENV["COLUMNS"] = ENV["LINES"] = "10" # simulates resizing
|
210
|
+
|
211
|
+
Hirb::View.resize
|
212
|
+
|
213
|
+
expect(pager.width).to eq 10
|
214
|
+
expect(pager.height).to eq 10
|
215
|
+
end
|
216
|
+
|
217
|
+
it "with no environment or stty still has valid width and height" do
|
218
|
+
Hirb::View.config[:width] = Hirb::View.config[:height] = nil
|
219
|
+
|
220
|
+
unless RUBY_PLATFORM[/java/]
|
221
|
+
allow(Hirb::Util)
|
222
|
+
.to receive(:command_exists?)
|
223
|
+
.with("stty")
|
224
|
+
.and_return(false)
|
225
|
+
end
|
226
|
+
|
227
|
+
ENV["COLUMNS"] = ENV["LINES"] = nil
|
228
|
+
|
229
|
+
Hirb::View.resize
|
230
|
+
|
231
|
+
expect(pager.width.is_a?(Integer)).to eq(true)
|
232
|
+
expect(pager.height.is_a?(Integer)).to eq(true)
|
233
|
+
|
234
|
+
reset_terminal_size
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
it "disable points output_value back to original output_value" do
|
239
|
+
expect(Hirb::View).not_to receive(:render_output)
|
240
|
+
|
241
|
+
Hirb.enable
|
242
|
+
Hirb.disable
|
243
|
+
|
244
|
+
context_stub = double(:last_value=>"")
|
245
|
+
|
246
|
+
::IRB::Irb.new(context_stub).output_value
|
247
|
+
end
|
248
|
+
|
249
|
+
it "disable works without irb defined" do
|
250
|
+
# Object.stubs(:const_defined?).with(:IRB).returns(false)
|
251
|
+
allow(Object).to receive(:const_defined?).with(:IRB).and_return(false)
|
252
|
+
|
253
|
+
Hirb.enable
|
254
|
+
Hirb.disable
|
255
|
+
|
256
|
+
expect(Hirb::View.enabled?).to eq(false)
|
257
|
+
end
|
258
|
+
|
259
|
+
it "capture_and_render" do
|
260
|
+
string = "no waaaay"
|
261
|
+
|
262
|
+
# Hirb::View.render_method.expects(:call).with(string)
|
263
|
+
allow(Hirb::View.render_method).to receive(:call).with(string)
|
264
|
+
Hirb::View.capture_and_render { print string }
|
265
|
+
end
|
266
|
+
|
267
|
+
xit "state is toggled by toggle_pager" do
|
268
|
+
# FIXME: 2021-02-14 - This causes other specs to fail
|
269
|
+
|
270
|
+
previous_state = Hirb::View.config[:pager]
|
271
|
+
|
272
|
+
Hirb::View.toggle_pager
|
273
|
+
|
274
|
+
expect(Hirb::View.config[:pager]).not_to eq(previous_state)
|
275
|
+
end
|
276
|
+
|
277
|
+
xit "state is toggled by toggle_formatter" do
|
278
|
+
# FIXME: 2021-02-14 - This causes other specs to fail
|
279
|
+
|
280
|
+
Hirb.enable
|
281
|
+
|
282
|
+
previous_state = Hirb::View.config[:formatter]
|
283
|
+
|
284
|
+
Hirb::View.toggle_formatter
|
285
|
+
|
286
|
+
expect(Hirb::View.config[:formatter]).not_to eq(previous_state)
|
287
|
+
end
|
288
|
+
end
|
data/spec/views_spec.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "hirber"
|
3
|
+
|
4
|
+
RSpec.describe "activerecord table" do
|
5
|
+
before do
|
6
|
+
Hirb.enable
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
Hirb.disable
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with no select" do
|
14
|
+
let(:pet) do
|
15
|
+
double(
|
16
|
+
name: "rufus",
|
17
|
+
age: 7,
|
18
|
+
attributes: { "name" => "rufus", "age" => 7 },
|
19
|
+
class: double(column_names: %w{age name}),
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "gets default options" do
|
24
|
+
expect(Hirb::Helpers::AutoTable.active_record__base_view(pet))
|
25
|
+
.to eq(fields: [:age, :name])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with select" do
|
30
|
+
let(:pet) do
|
31
|
+
double(
|
32
|
+
name: "rufus",
|
33
|
+
age: 7,
|
34
|
+
attributes: { "name" => "rufus" },
|
35
|
+
class: double(column_names: %w{age name}),
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "gets default options" do
|
40
|
+
expect(Hirb::Helpers::AutoTable.active_record__base_view(pet))
|
41
|
+
.to eq(fields: [:name])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
RSpec.describe "mongoid table" do
|
47
|
+
let(:mongoid_stub) { double(class: double(fields: fields)) }
|
48
|
+
let(:fields) { {"_id" => "x0f0x", "name" => "blah"} }
|
49
|
+
|
50
|
+
it "only has one _id" do
|
51
|
+
expect(Hirb::Helpers::AutoTable.mongoid__document_view(mongoid_stub))
|
52
|
+
.to eq(fields: fields.keys.sort)
|
53
|
+
end
|
54
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "bacon"
|
2
|
+
require "bacon/bits"
|
3
|
+
require "mocha-on-bacon"
|
4
|
+
require "hirber"
|
5
|
+
|
5
6
|
include Hirb
|
6
7
|
|
7
8
|
module TestHelpers
|
8
|
-
# set these to avoid invoking stty multiple times which doubles
|
9
|
+
# set these to avoid invoking stty multiple times which doubles
|
10
|
+
# test suite running time
|
11
|
+
|
9
12
|
ENV["LINES"] = ENV["COLUMNS"] = "20"
|
13
|
+
|
10
14
|
def reset_terminal_size
|
11
15
|
ENV["LINES"] = ENV["COLUMNS"] = "20"
|
12
16
|
end
|