rails6-footnotes 5.0.0

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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +25 -0
  3. data/.gitignore +15 -0
  4. data/.rspec.example +1 -0
  5. data/CHANGELOG +129 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +187 -0
  8. data/MIT-LICENSE +21 -0
  9. data/README.rdoc +188 -0
  10. data/Rakefile +18 -0
  11. data/bin/rake +29 -0
  12. data/bin/rspec +29 -0
  13. data/gemfiles/Gemfile.rails-3.2.22 +5 -0
  14. data/gemfiles/Gemfile.rails-4.0.x +6 -0
  15. data/gemfiles/Gemfile.rails-4.1.x +5 -0
  16. data/gemfiles/Gemfile.rails-4.2.x +5 -0
  17. data/gemfiles/Gemfile.rails-edge +5 -0
  18. data/lib/generators/rails_footnotes/install_generator.rb +14 -0
  19. data/lib/generators/templates/rails_footnotes.rb +26 -0
  20. data/lib/rails-footnotes.rb +68 -0
  21. data/lib/rails-footnotes/abstract_note.rb +178 -0
  22. data/lib/rails-footnotes/each_with_rescue.rb +36 -0
  23. data/lib/rails-footnotes/extension.rb +24 -0
  24. data/lib/rails-footnotes/filter.rb +359 -0
  25. data/lib/rails-footnotes/notes/all.rb +1 -0
  26. data/lib/rails-footnotes/notes/assigns_note.rb +60 -0
  27. data/lib/rails-footnotes/notes/controller_note.rb +55 -0
  28. data/lib/rails-footnotes/notes/cookies_note.rb +17 -0
  29. data/lib/rails-footnotes/notes/env_note.rb +24 -0
  30. data/lib/rails-footnotes/notes/files_note.rb +49 -0
  31. data/lib/rails-footnotes/notes/filters_note.rb +51 -0
  32. data/lib/rails-footnotes/notes/javascripts_note.rb +16 -0
  33. data/lib/rails-footnotes/notes/layout_note.rb +26 -0
  34. data/lib/rails-footnotes/notes/log_note.rb +47 -0
  35. data/lib/rails-footnotes/notes/log_note/note_logger.rb +59 -0
  36. data/lib/rails-footnotes/notes/params_note.rb +21 -0
  37. data/lib/rails-footnotes/notes/partials_note.rb +38 -0
  38. data/lib/rails-footnotes/notes/queries_note.rb +121 -0
  39. data/lib/rails-footnotes/notes/routes_note.rb +60 -0
  40. data/lib/rails-footnotes/notes/session_note.rb +27 -0
  41. data/lib/rails-footnotes/notes/stylesheets_note.rb +16 -0
  42. data/lib/rails-footnotes/notes/view_note.rb +41 -0
  43. data/lib/rails-footnotes/version.rb +3 -0
  44. data/lib/rails6-footnotes.rb +1 -0
  45. data/rails-footnotes.gemspec +22 -0
  46. data/spec/abstract_note_spec.rb +89 -0
  47. data/spec/app/assets/config/manifest.js +2 -0
  48. data/spec/app/assets/javascripts/foobar.js +1 -0
  49. data/spec/app/assets/stylesheets/foobar.css +0 -0
  50. data/spec/app/views/files/index.html.erb +1 -0
  51. data/spec/app/views/layouts/application.html.erb +12 -0
  52. data/spec/app/views/partials/_foo.html.erb +1 -0
  53. data/spec/app/views/partials/index.html.erb +1 -0
  54. data/spec/controllers/files_note_controller_spec.rb +38 -0
  55. data/spec/controllers/footnotes_controller_spec.rb +128 -0
  56. data/spec/controllers/log_note_controller_spec.rb +32 -0
  57. data/spec/controllers/partials_note_controller_spec.rb +28 -0
  58. data/spec/env_note_spec.rb +73 -0
  59. data/spec/fixtures/html_download.html +5 -0
  60. data/spec/footnotes_spec.rb +234 -0
  61. data/spec/notes/assigns_note_spec.rb +50 -0
  62. data/spec/notes/controller_note_spec.rb +12 -0
  63. data/spec/notes/files_note_spec.rb +26 -0
  64. data/spec/notes/javascripts_note_spec.rb +18 -0
  65. data/spec/notes/stylesheets_note_spec.rb +19 -0
  66. data/spec/notes/view_note_spec.rb +12 -0
  67. data/spec/spec_helper.rb +68 -0
  68. metadata +153 -0
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ describe 'log note', type: :controller do
5
+
6
+ class ApplicationController < ActionController::Base
7
+ end
8
+
9
+ controller do
10
+ def index
11
+ Rails.logger.error 'foo'
12
+ Rails.logger.warn 'bar'
13
+ render inline: '<html><head></head><body></body></html>', content_type: 'text/html'
14
+ end
15
+ end
16
+
17
+ before :all do
18
+ Footnotes.enabled = true
19
+ end
20
+
21
+ after :all do
22
+ Footnotes.enabled = false
23
+ end
24
+
25
+ it 'Includes the log in the response' do
26
+ get :index
27
+ log_debug = first('fieldset#log_debug_info div', :visible => false)
28
+ expect(log_debug).to have_content('foo')
29
+ expect(log_debug).to have_content('bar')
30
+ end
31
+
32
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ class PartialsController < ActionController::Base
4
+
5
+ def index
6
+ end
7
+
8
+ end
9
+
10
+ describe PartialsController, type: :controller do
11
+
12
+ render_views
13
+
14
+ before :all do
15
+ Footnotes.enabled = true
16
+ end
17
+
18
+ after :all do
19
+ Footnotes.enabled = false
20
+ end
21
+
22
+ it 'lists the rendered partials' do
23
+ get :index
24
+ expect(response.body).to have_selector('#footnotes_debug #partials_debug_info table tr', :visible => false, :count => 2)
25
+ end
26
+
27
+
28
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'action_controller'
3
+ require 'action_controller/test_case'
4
+
5
+ class FootnotesEnvController < ActionController::Base
6
+ attr_accessor :template, :performed_render
7
+ end
8
+
9
+ describe Footnotes::Notes::EnvNote do
10
+ let(:controller) {
11
+ FootnotesEnvController.new.tap { |c|
12
+ c.template = Object.new
13
+ c.request = ActionDispatch::TestRequest.create
14
+ c.response = ActionDispatch::TestResponse.new
15
+ c.response_body = %Q(<html><body></body></html>)
16
+ c.params = {}
17
+ }
18
+ }
19
+
20
+ subject { described_class.new(controller) }
21
+
22
+ before do
23
+ @notes = Footnotes::Filter.notes
24
+ Footnotes::Filter.notes = [ :env ]
25
+ end
26
+
27
+ after do
28
+ Footnotes::Filter.notes = @notes
29
+ end
30
+
31
+ it '#to_sym is :env' do
32
+ expect(subject.to_sym).to eq(:env)
33
+ end
34
+
35
+ context 'with non-spec env keys' do
36
+ before :each do
37
+ controller.request.env.replace(:non_spec => 'symbol_env')
38
+ end
39
+
40
+ it 'does not raise an exception' do
41
+ expect { subject.content }.not_to raise_error
42
+ end
43
+
44
+ it 'includes the environment row' do
45
+ expect(subject).to receive(:mount_table).
46
+ with([ [ :key, 'value' ], [ 'non_spec', 'symbol_env' ] ])
47
+ subject.content
48
+ end
49
+ end
50
+
51
+ it 'includes values for all of the keys except HTTP_COOKIE' do
52
+ env = controller.request.env.dup
53
+ env.delete('HTTP_COOKIE')
54
+
55
+ env_data = env.map { |k, v| [ k.to_s, subject.escape(v.to_s) ] }.
56
+ sort.
57
+ unshift([ :key, 'value' ])
58
+
59
+ expect(subject).to receive(:mount_table).with(env_data)
60
+ subject.content
61
+ end
62
+
63
+ it 'gets a link for HTTP_COOKIE' do
64
+ controller.request.env.replace('HTTP_COOKIE' => 'foo')
65
+ expect(subject).to receive(:mount_table).
66
+ with([
67
+ [ :key, 'value' ],
68
+ [ 'HTTP_COOKIE',
69
+ '<a href="#" style="color:#009" onclick="Footnotes.hideAllAndToggle(\'cookies_debug_info\');return false;">See cookies on its tab</a>' ]
70
+ ])
71
+ subject.content
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <p>Hello world</p>
4
+ </body>
5
+ </html>
@@ -0,0 +1,234 @@
1
+ # encoding: utf-8
2
+
3
+ require "spec_helper"
4
+ require 'action_controller'
5
+ require 'action_controller/test_case'
6
+ require "tempfile"
7
+
8
+ class FootnotesController < ActionController::Base
9
+ attr_accessor :template, :performed_render
10
+ end
11
+
12
+ module Footnotes::Notes
13
+ class TestNote < AbstractNote
14
+ def self.to_sym; :test; end
15
+ def valid?; true; end
16
+ end
17
+
18
+ class NoteXNote < TestNote; end
19
+ class NoteYNote < TestNote; end
20
+ class NoteZNote < TestNote; end
21
+
22
+ class FileURINote < TestNote
23
+ def link
24
+ "/example/local file path/with-special-chars/öäü/file"
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "Footnotes" do
30
+ before do
31
+ @controller = FootnotesController.new
32
+ @controller.template = Object.new
33
+ @controller.request = ActionDispatch::TestRequest.create
34
+ @controller.response = ActionDispatch::TestResponse.new
35
+ @controller.response_body = HTML_DOCUMENT.dup
36
+ @controller.params = {}
37
+
38
+ Footnotes::Filter.notes = [ :test ]
39
+ Footnotes::Filter.multiple_notes = false
40
+ @footnotes = Footnotes::Filter.new(@controller)
41
+ end
42
+
43
+ it "footnotes_controller" do
44
+ index = @controller.response.body.index(/This is the HTML page/)
45
+ expect(index).to eql 334
46
+ end
47
+
48
+ context "response_body is file" do
49
+ before do
50
+ @file = Tempfile.new("test")
51
+ def @file.body; read; end
52
+ @file.write "foobarbaz"
53
+ @file.rewind
54
+ end
55
+
56
+ after do
57
+ @file.close!
58
+ end
59
+
60
+ it "should not change file position" do
61
+ @controller.response_body = @file
62
+ expect {
63
+ @footnotes = Footnotes::Filter.new(@controller)
64
+ }.not_to change{ @controller.response_body.pos }
65
+ end
66
+ end
67
+
68
+ it "foonotes_included" do
69
+ footnotes_perform!
70
+ expect(@controller.response_body).not_to eq(HTML_DOCUMENT)
71
+ end
72
+
73
+ it "should escape links with special chars" do
74
+ note_with_link = Footnotes::Notes::FileURINote.new
75
+ link = Footnotes::Filter.prefix(note_with_link.link, 1, 1, 1)
76
+ expect(link).to eql "txmt://open?url=file:///example/local%20file%20path/with-special-chars/%C3%B6%C3%A4%C3%BC/file&amp;line=1&amp;column=1"
77
+ end
78
+
79
+ specify "footnotes_not_included_when_request_is_xhr" do
80
+ @controller.request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
81
+ @controller.request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
82
+ footnotes_perform!
83
+ expect(@controller.response.body).to eql HTML_DOCUMENT
84
+ end
85
+
86
+ specify "footnotes_not_included_when_content_type_is_javascript" do
87
+ @controller.response.content_type = 'text/javascript'
88
+ footnotes_perform!
89
+ expect(@controller.response.body).to eql HTML_DOCUMENT
90
+ end
91
+
92
+ specify "footnotes_included_when_content_type_is_html" do
93
+ @controller.response.content_type = 'text/html; charset=utf-8'
94
+ footnotes_perform!
95
+ expect(@controller.response.body).not_to eql HTML_DOCUMENT
96
+ end
97
+
98
+ specify "footnotes_included_when_content_type_is_nil" do
99
+ footnotes_perform!
100
+ expect(@controller.response.body).not_to eql HTML_DOCUMENT
101
+ end
102
+
103
+ specify "not_included_when_body_is_not_a_string" do
104
+ allow(@controller.response).to receive(:body).and_return(Time.now)# = Proc.new { Time.now }
105
+ expect(Footnotes::Filter.new(@controller).send(:valid?)).not_to be
106
+ expect(@controller.response.body).not_to match(/<!-- Footnotes/)
107
+ end
108
+
109
+ specify "notes_are_initialized" do
110
+ footnotes_perform!
111
+ test_note = @footnotes.instance_variable_get('@notes').first
112
+ expect(test_note.class.name).to eql 'Footnotes::Notes::TestNote'
113
+ expect(test_note.to_sym).to eql :test
114
+ end
115
+
116
+ specify "notes_links" do
117
+ note = Footnotes::Notes::TestNote.new
118
+ expect(note).to receive(:row).twice
119
+ @footnotes.instance_variable_set(:@notes, [note])
120
+ footnotes_perform!
121
+ end
122
+
123
+ specify "notes_fieldset" do
124
+ note = Footnotes::Notes::TestNote.new
125
+ expect(note).to receive(:has_fieldset?).exactly(3).times
126
+ @footnotes.instance_variable_set(:@notes, [note])
127
+ footnotes_perform!
128
+ end
129
+
130
+ specify "multiple_notes" do
131
+ Footnotes::Filter.multiple_notes = true
132
+ note = Footnotes::Notes::TestNote.new
133
+ expect(note).to receive(:has_fieldset?).twice
134
+ @footnotes.instance_variable_set(:@notes, [note])
135
+ footnotes_perform!
136
+ end
137
+
138
+ specify "notes_are_reset" do
139
+ note = Footnotes::Notes::TestNote.new
140
+ expect(note.class).to receive(:close!)
141
+ @footnotes.instance_variable_set(:@notes, [note])
142
+ @footnotes.send(:close!, @controller)
143
+ end
144
+
145
+ specify "links_helper" do
146
+ note = Footnotes::Notes::TestNote.new
147
+ expect(@footnotes.send(:link_helper, note)).to eql '<a href="#" onclick="">Test</a>'
148
+
149
+ expect(note).to receive(:link).once.and_return(:link)
150
+ expect(@footnotes.send(:link_helper, note)).to eql '<a href="link" onclick="">Test</a>'
151
+ end
152
+
153
+ specify "links_helper_has_fieldset?" do
154
+ note = Footnotes::Notes::TestNote.new
155
+ expect(note).to receive(:has_fieldset?).once.and_return(true)
156
+ expect(@footnotes.send(:link_helper, note)).to eql '<a href="#" onclick="Footnotes.hideAllAndToggle(\'test_debug_info\');return false;">Test</a>'
157
+ end
158
+
159
+ specify "links_helper_onclick" do
160
+ note = Footnotes::Notes::TestNote.new
161
+ expect(note).to receive(:onclick).twice.and_return(:onclick)
162
+ expect(@footnotes.send(:link_helper, note)).to eql '<a href="#" onclick="onclick">Test</a>'
163
+
164
+ expect(note).to receive(:has_fieldset?).once.and_return(true)
165
+ expect(@footnotes.send(:link_helper, note)).to eql '<a href="#" onclick="onclick">Test</a>'
166
+ end
167
+
168
+ specify "insert_style" do
169
+ @controller.response.body = "<head></head><split><body></body>"
170
+ @footnotes = Footnotes::Filter.new(@controller)
171
+ footnotes_perform!
172
+ expect(@controller.response.body.split('<split>').first.include?('<!-- Footnotes Style -->')).to be
173
+ end
174
+
175
+ specify "insert_footnotes_inside_body" do
176
+ @controller.response.body = "<head></head><split><body></body>"
177
+ @footnotes = Footnotes::Filter.new(@controller)
178
+ footnotes_perform!
179
+ expect(@controller.response.body.split('<split>').last.include?('<!-- End Footnotes -->')).to be
180
+ end
181
+
182
+ specify "insert_footnotes_inside_holder" do
183
+ @controller.response.body = "<head></head><split><div id='footnotes_holder'></div>"
184
+ @footnotes = Footnotes::Filter.new(@controller)
185
+ footnotes_perform!
186
+ expect(@controller.response.body.split('<split>').last.include?('<!-- End Footnotes -->')).to be
187
+ end
188
+
189
+ specify "insert_text" do
190
+ @footnotes.send(:insert_text, :after, /<head>/, "Graffiti")
191
+ after = " <head>Graffiti"
192
+ expect(@controller.response.body.split("\n")[2]).to eql after
193
+
194
+ @footnotes.send(:insert_text, :before, /<\/body>/, "Notes")
195
+ after = " Notes</body>"
196
+ expect(@controller.response.body.split("\n")[12]).to eql after
197
+ end
198
+
199
+ describe 'Hooks' do
200
+ before {Footnotes::Filter.notes = [:note_x, :note_y, :note_z]}
201
+ context 'before' do
202
+ specify do
203
+ Footnotes.setup {|config| config.before {|controller, filter| filter.notes -= [:note_y] }}
204
+ Footnotes::Filter.start!(@controller)
205
+ expect(Footnotes::Filter.notes).to eql [:note_x, :note_z]
206
+ end
207
+ end
208
+ context "after" do
209
+ specify do
210
+ Footnotes.setup {|config| config.after {|controller, filter| filter.notes -= [:note_y] }}
211
+ Footnotes::Filter.start!(@controller)
212
+ expect(Footnotes::Filter.notes).to eql [:note_x, :note_z]
213
+ end
214
+ end
215
+ end
216
+
217
+ protected
218
+ def footnotes_perform!
219
+ template_expects('html')
220
+ @controller.performed_render = true
221
+
222
+ Footnotes::Filter.start!(@controller)
223
+ @footnotes.add_footnotes!
224
+ end
225
+
226
+ def template_expects(format)
227
+ if @controller.template.respond_to?(:template_format)
228
+ allow(@controller.template).to receive(:template_format).and_return(format)
229
+ else
230
+ allow(@controller.template).to receive(:format).and_return(format)
231
+ end
232
+ end
233
+
234
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+ require 'action_controller'
3
+ require "rails-footnotes/notes/assigns_note"
4
+
5
+ describe Footnotes::Notes::AssignsNote do
6
+ let(:note) do
7
+ @controller = double
8
+ allow(@controller).to receive(:instance_variables).and_return([:@action_has_layout, :@status])
9
+ @controller.instance_variable_set(:@action_has_layout, true)
10
+ @controller.instance_variable_set(:@status, 200)
11
+ Footnotes::Notes::AssignsNote.new(@controller)
12
+ end
13
+ subject {note}
14
+
15
+ before(:each) {Footnotes::Notes::AssignsNote.ignored_assigns = []}
16
+
17
+ it {should be_valid}
18
+
19
+ describe '#title' do
20
+ subject { super().title }
21
+ it {should eql 'Assigns (2)'}
22
+ end
23
+
24
+ specify {expect(note.send(:assigns)).to eql [:@action_has_layout, :@status]}
25
+ specify {expect(note.send(:to_table)).to eql [
26
+ ["Name", "Value"],
27
+ ["<strong>@action_has_layout</strong><br /><em>TrueClass</em>", "true"],
28
+ ["<strong>@status</strong><br /><em>Integer</em>", "200"]
29
+ ]}
30
+
31
+ describe "Ignored Assigns" do
32
+ before(:each) {Footnotes::Notes::AssignsNote.ignored_assigns = [:@status]}
33
+ it {expect(note.send(:assigns)).not_to include :@status}
34
+ end
35
+
36
+ describe "Ignored Assigns by regexp" do
37
+ before(:each) {Footnotes::Notes::AssignsNote.ignored_assigns_pattern = /^@status$/}
38
+ it {expect(note.send(:assigns)).not_to include :@status}
39
+ end
40
+
41
+ it "should call #mount_table method with correct params" do
42
+ expect(note).to receive(:mount_table).with(
43
+ [
44
+ ["Name", "Value"],
45
+ ["<strong>@action_has_layout</strong><br /><em>TrueClass</em>", "true"],
46
+ ["<strong>@status</strong><br /><em>Integer</em>", "200"]
47
+ ], {:summary=>"Debug information for Assigns (2)"})
48
+ note.content
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+ require "rails-footnotes/notes/controller_note"
3
+
4
+ describe Footnotes::Notes::ControllerNote do
5
+ # Issue #60
6
+ it "should not be valid if conftroller file not exist" do
7
+ note = Footnotes::Notes::ControllerNote.new(double)
8
+ allow(note).to receive(:controller_filename).and_return(nil)
9
+
10
+ expect(note).not_to be_valid
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'action_controller'
3
+ require "rails-footnotes/notes/files_note"
4
+
5
+ class ConcreteFilesNote < Footnotes::Notes::FilesNote
6
+ def scan_text(text)
7
+ []
8
+ end
9
+ end
10
+
11
+ describe Footnotes::Notes::FilesNote do
12
+
13
+ let(:note) do
14
+ ConcreteFilesNote.new(double('controller', :response => double('', :body => '')))
15
+ end
16
+
17
+ subject { note }
18
+
19
+ it { should be_valid }
20
+
21
+ describe '#row' do
22
+ subject { super().row }
23
+ it { should eql :edit }
24
+ end
25
+
26
+ end