retter 0.2.2 → 0.2.3

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 (52) hide show
  1. data/.travis.yml +1 -1
  2. data/ChangeLog.md +10 -0
  3. data/README.md +1 -3
  4. data/bin/retter +8 -4
  5. data/lib/retter/binder.rb +50 -0
  6. data/lib/retter/command.rb +42 -39
  7. data/lib/retter/config.rb +24 -23
  8. data/lib/retter/entries.rb +14 -18
  9. data/lib/retter/entry.rb +52 -29
  10. data/lib/retter/generator/base.rb +6 -7
  11. data/lib/retter/generator/skel/Gemfile +1 -2
  12. data/lib/retter/generator/skel/Retterfile +2 -2
  13. data/lib/retter/generator/skel/layouts/article.html.haml +3 -2
  14. data/lib/retter/generator/skel/layouts/entry.html.haml +3 -2
  15. data/lib/retter/generator/skel/layouts/index.html.haml +4 -2
  16. data/lib/retter/generator.rb +0 -1
  17. data/lib/retter/{renderers.rb → markdown.rb} +22 -1
  18. data/lib/retter/page/article.rb +54 -0
  19. data/lib/retter/page/base.rb +97 -0
  20. data/lib/retter/page/entries.rb +17 -0
  21. data/lib/retter/page/entry.rb +46 -0
  22. data/lib/retter/page/feed.rb +63 -0
  23. data/lib/retter/page/index.rb +17 -0
  24. data/lib/retter/page/profile.rb +17 -0
  25. data/lib/retter/page/view_helper.rb +9 -1
  26. data/lib/retter/page.rb +22 -74
  27. data/lib/retter/preprint.rb +19 -10
  28. data/lib/retter/version.rb +1 -1
  29. data/lib/retter.rb +41 -29
  30. data/retter.gemspec +44 -53
  31. data/spec/command/callback_spec.rb +16 -6
  32. data/spec/command/clean_spec.rb +20 -0
  33. data/spec/command/commit_spec.rb +11 -12
  34. data/spec/command/edit_spec.rb +28 -38
  35. data/spec/command/list_spec.rb +4 -4
  36. data/spec/command/open_spec.rb +2 -2
  37. data/spec/command/preview_spec.rb +7 -12
  38. data/spec/command/rebind_spec.rb +143 -66
  39. data/spec/spec_helper.rb +10 -3
  40. data/spec/support/example_group_helper.rb +55 -15
  41. data/spec/support/matchers.rb +0 -1
  42. metadata +195 -78
  43. data/lib/retter/generator/updator.rb +0 -7
  44. data/lib/retter/pages/article.rb +0 -41
  45. data/lib/retter/pages/entries.rb +0 -15
  46. data/lib/retter/pages/entry.rb +0 -35
  47. data/lib/retter/pages/feed.rb +0 -51
  48. data/lib/retter/pages/index.rb +0 -15
  49. data/lib/retter/pages/profile.rb +0 -15
  50. data/lib/retter/pages.rb +0 -77
  51. data/spec/command/invoke_after_spec.rb +0 -29
  52. data/spec/fixtures/sample.md +0 -295
@@ -4,11 +4,8 @@ require 'spec_helper'
4
4
 
5
5
  describe 'Retter::Command#rebind', clean: :all do
6
6
  context 'first post' do
7
- let(:date_str) { '20110101' }
8
- let(:date) { Date.parse(date_str) }
9
- let(:date_file) { Retter.entries.retter_file(date) }
10
- let(:date_html) { Retter::Pages.entry_file(date) }
11
- let(:article) { <<-EOM }
7
+ let(:date_str) { '2011/01/01' }
8
+ let(:article) { <<-EOM }
12
9
  # 朝11時
13
10
 
14
11
  おはようございます
@@ -19,13 +16,14 @@ describe 'Retter::Command#rebind', clean: :all do
19
16
  EOM
20
17
 
21
18
  before do
22
- stub_time date_str
19
+ time_travel_to date_str
23
20
 
24
- wip_file.open('w') {|f| f.puts article }
21
+ write_to_wip_file article
25
22
 
26
- command.should_receive(:invoke_after).with(:bind)
27
- command.should_receive(:invoke_after).with(:rebind)
28
- command.rebind
23
+ command.should_receive(:after_callback).with(:bind)
24
+ command.should_receive(:after_callback).with(:rebind)
25
+
26
+ invoke_command :rebind
29
27
  end
30
28
 
31
29
  describe 'wip file' do
@@ -35,80 +33,80 @@ describe 'Retter::Command#rebind', clean: :all do
35
33
  end
36
34
 
37
35
  describe 'index.html' do
38
- let(:index_html) { Retter.config.retter_home.join('index.html').read }
36
+ let(:index_html) { generated_file('index.html').read }
39
37
 
40
- it { texts_of(index_html, 'article p').should include('おはようございます') }
38
+ it { texts_of(index_html, 'article p').should include 'おはようございます' }
41
39
  it { texts_of(index_html, 'article h1.date').should == %w(2011-01-01) }
42
- it { texts_of(index_html, 'article h1').should == %w(2011-01-01 朝11時 夜1時) }
40
+ it { texts_of(index_html, 'article h1').should == %w(2011-01-01 朝11時 夜1時) }
43
41
  end
44
42
 
45
43
  describe 'entries.html' do
46
- let(:entries_html) { Retter.config.retter_home.join('entries.html').read }
44
+ let(:entries_html) { generated_file('entries.html').read }
47
45
 
48
46
  it { texts_of(entries_html, 'a.entry').first.should == '01/01' }
49
- it { texts_of(entries_html, 'a.article').should == %w(朝11時 夜1時) }
47
+ it { texts_of(entries_html, 'a.article').should == %w(朝11時 夜1時) }
50
48
  end
51
49
 
52
50
  describe 'entry.html' do
53
- let(:entry_html) { Retter::Pages.entry_file(date).read }
51
+ let(:entry_html) { entry_html_file(date_str).read }
54
52
 
55
- it { texts_of(entry_html, 'article p').should == %w(おはようございます おやすみなさい) }
53
+ it { texts_of(entry_html, 'article p').should == %w(おはようございます おやすみなさい) }
56
54
  it { texts_of(entry_html, 'article h1.date').should == %w(2011-01-01) }
57
- it { texts_of(entry_html, 'article h1').should == %w(2011-01-01 朝11時 夜1時) }
55
+ it { texts_of(entry_html, 'article h1').should == %w(2011-01-01 朝11時 夜1時) }
58
56
  end
59
57
 
60
- describe 'entry part(first)' do
61
- let(:part_html) { Retter::Pages.entry_dir(date).join('a0.html').read }
58
+ describe 'article (first)' do
59
+ let(:article_html) { article_html_file(date_str, 'a0').read }
62
60
 
63
61
  describe 'body' do
64
- subject { texts_of(part_html, 'article p') }
62
+ subject { texts_of(article_html, 'article p') }
65
63
 
66
- it { should include('おはようございます') }
67
- it { should_not include('おやすみなさい') }
64
+ it { should include 'おはようございます' }
65
+ it { should_not include 'おやすみなさい' }
68
66
  end
69
67
 
70
68
  describe 'date' do
71
- subject { texts_of(part_html, 'article h1.date') }
69
+ subject { texts_of(article_html, 'article h1.date') }
72
70
 
73
71
  it { should == %w(2011-01-01) }
74
72
  end
75
73
 
76
74
  describe 'headings' do
77
- subject { texts_of(part_html, 'article h1') }
75
+ subject { texts_of(article_html, 'article h1') }
78
76
 
79
- it { should include('朝11時') }
80
- it { should_not include('夜1時') }
77
+ it { should include '朝11時' }
78
+ it { should_not include '夜1時' }
81
79
  end
82
80
  end
83
81
 
84
- describe 'entry part(last)' do
85
- let(:part_html) { Retter::Pages.entry_dir(date).join('a1.html').read }
82
+ describe 'article (last)' do
83
+ let(:article_html) { article_html_file(date_str, 'a1').read }
86
84
 
87
85
  describe 'body' do
88
- subject { texts_of(part_html, 'article p') }
86
+ subject { texts_of(article_html, 'article p') }
89
87
 
90
- it { should include('おやすみなさい') }
91
- it { should_not include('おはようございます') }
88
+ it { should include 'おやすみなさい' }
89
+ it { should_not include 'おはようございます' }
92
90
  end
93
91
 
94
92
  describe 'date' do
95
- subject { texts_of(part_html, 'article h1.date') }
93
+ subject { texts_of(article_html, 'article h1.date') }
96
94
 
97
95
  it { should == %w(2011-01-01) }
98
96
  end
99
97
 
100
98
  describe 'headings' do
101
- subject { texts_of(part_html, 'article h1') }
99
+ subject { texts_of(article_html, 'article h1') }
102
100
 
103
- it { should include('夜1時') }
104
- it { should_not include('朝11時') }
101
+ it { should include '夜1時' }
102
+ it { should_not include '朝11時' }
105
103
  end
106
104
  end
107
105
  end
108
106
 
109
- context 'includes code block' do
110
- let(:index_html) { Retter.config.retter_home.join('index.html').read }
111
- let(:article) { <<-EOM }
107
+ context 'article includes code block' do
108
+ let(:index_html) { generated_file('index.html').read }
109
+ let(:article) { <<-EOM }
112
110
  # コードを書きました
113
111
 
114
112
  ```ruby
@@ -117,13 +115,14 @@ sleep 1000
117
115
  EOM
118
116
 
119
117
  before do
120
- wip_file.open('w') {|f| f.puts article }
118
+ write_to_wip_file article
121
119
  end
122
120
 
123
121
  context 'use Pygments' do
124
122
  before do
125
- Retter.config.renderer Retter::Renderers::PygmentsRenderer
126
- command.rebind
123
+ Retter::Site.config.renderer Retter::Markdown::PygmentsRenderer
124
+
125
+ invoke_command :rebind
127
126
  end
128
127
 
129
128
  specify 'code should be highlighted' do
@@ -133,8 +132,9 @@ sleep 1000
133
132
 
134
133
  context 'use CodeRay' do
135
134
  before do
136
- Retter.config.renderer Retter::Renderers::CodeRayRenderer
137
- command.rebind
135
+ Retter::Site.config.renderer Retter::Markdown::CodeRayRenderer
136
+
137
+ invoke_command :rebind
138
138
  end
139
139
 
140
140
  specify 'code should be highlighted' do
@@ -143,57 +143,134 @@ sleep 1000
143
143
  end
144
144
  end
145
145
 
146
- context 'with silent option' do
146
+ context 'use custom markup' do
147
+ let(:index_html) { generated_file('index.html').read }
148
+ let(:custom_markup) { Object.new.tap {|o| o.define_singleton_method(:render, &:upcase) } }
149
+
147
150
  before do
148
- wip_file.open('w') {|f| f.puts 'article' }
151
+ Retter::Site.config.markup custom_markup
152
+
153
+ write_to_wip_file 'hi'
154
+
155
+ invoke_command :rebind
156
+ end
157
+
158
+ after do
159
+ Retter::Entries.instance_variable_set :@markup, nil
160
+ end
161
+
162
+ subject { texts_of(index_html, 'article p') }
163
+
164
+ it { should include 'HI' }
165
+ end
149
166
 
150
- command.stub!(:options) { {silent: true} }
167
+ context 'with silent option' do
168
+ before do
169
+ write_to_wip_file 'article'
151
170
  end
152
171
 
153
172
  specify 'rebind callback should not invoked' do
154
- command.should_not_receive(:invoke_after)
173
+ command.should_not_receive(:after_callback)
155
174
 
156
- command.rebind
175
+ invoke_command :rebind, silent: true
157
176
  end
158
177
  end
159
178
 
160
179
  context 'skipping some singleton pages binding' do
161
- let(:retter_home) { Retter.config.retter_home }
162
- let(:index_html) { retter_home.join('index.html') }
163
- let(:profile_html) { retter_home.join('profile.html') }
164
- let(:entries_html) { retter_home.join('entries.html') }
165
- let(:feed_file) { retter_home.join('feed.rss') }
180
+ let(:index_html) { generated_file('index.html') }
181
+ let(:profile_html) { generated_file('profile.html') }
182
+ let(:entries_html) { generated_file('entries.html') }
183
+ let(:feed_file) { generated_file('feed.rss') }
166
184
 
167
185
  before do
168
186
  index_html.unlink
169
187
 
170
- command.edit
188
+ invoke_command :edit
171
189
  end
172
190
 
173
191
  context 'skipping all' do
174
192
  before do
175
- Retter::Pages.allow_binding :none
176
-
177
- command.rebind
193
+ invoke_command :rebind do |config|
194
+ config.allow_binding :none
195
+ end
178
196
  end
179
197
 
180
198
  it { profile_html.should_not be_exist }
181
199
  it { entries_html.should_not be_exist }
182
- it { feed_file.should_not be_exist }
183
- it { index_html.should be_exist }
200
+ it { feed_file.should_not be_exist }
201
+ it { index_html.should be_exist }
184
202
  end
185
203
 
186
204
  context 'skipping only :feed' do
187
205
  before do
188
- Retter::Pages.allow_binding [:profile, :entries]
189
-
190
- command.rebind
206
+ invoke_command :rebind do |config|
207
+ config.allow_binding [:profile, :entries]
208
+ end
191
209
  end
192
210
 
193
- it { profile_html.should be_exist }
194
- it { entries_html.should be_exist }
211
+ it { profile_html.should be_exist }
212
+ it { entries_html.should be_exist }
195
213
  it { feed_file.should_not be_exist }
196
- it { index_html.should be_exist }
214
+ it { index_html.should be_exist }
215
+ end
216
+ end
217
+
218
+ context 'with link or image' do
219
+ let(:index_html) { generated_file('index.html').read }
220
+ let(:elements) { nokogiri(index_html) }
221
+
222
+ before do
223
+ write_to_wip_file article
224
+
225
+ invoke_command :rebind
226
+ end
227
+
228
+ describe 'a href="//example.com/foo/bar"' do
229
+ let(:article) { '[title](//example.com/foo/bar)' }
230
+
231
+ it { elements.search("a[href='//example.com/foo/bar']").should_not be_empty }
232
+ end
233
+
234
+ describe 'img src="//example.com/foo/bar.png"' do
235
+ let(:article) { '![title](//example.com/foo/bar.png)' }
236
+
237
+ it { elements.search("img[src='//example.com/foo/bar.png']").should_not be_empty }
238
+ end
239
+
240
+ describe 'a href="/foo/bar"' do
241
+ let(:article) { '[title](/foo/bar)' }
242
+
243
+ it { elements.search("a[href='./foo/bar']").should_not be_empty }
244
+ end
245
+
246
+ describe 'img src="/foo/bar.png"' do
247
+ let(:article) { '![title](/foo/bar.png)' }
248
+
249
+ it { elements.search("img[src='./foo/bar.png']").should_not be_empty }
250
+ end
251
+
252
+ describe 'a href="./foo/bar"' do
253
+ let(:article) { '[title](./foo/bar)' }
254
+
255
+ it { elements.search("a[href='./foo/bar']").should_not be_empty }
256
+ end
257
+
258
+ describe 'img src="./foo/bar.png"' do
259
+ let(:article) { '![title](./foo/bar.png)' }
260
+
261
+ it { elements.search("img[src='./foo/bar.png']").should_not be_empty }
262
+ end
263
+
264
+ describe 'a href="../foo/bar"' do
265
+ let(:article) { '[title](../foo/bar)' }
266
+
267
+ it { elements.search("a[href='../foo/bar']").should_not be_empty }
268
+ end
269
+
270
+ describe 'img src="../foo/bar.png"' do
271
+ let(:article) { '![title](../foo/bar.png)' }
272
+
273
+ it { elements.search("img[src='../foo/bar.png']").should_not be_empty }
197
274
  end
198
275
  end
199
276
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # coding: utf-8
2
2
 
3
3
  require 'tapp'
4
+ require 'delorean'
4
5
 
5
6
  if ENV['COVERAGE']
6
7
  require 'simplecov'
@@ -26,13 +27,19 @@ RSpec.configure do |config|
26
27
 
27
28
  config.after :each, clean: :all do
28
29
  FileUtils.rm_rf retter_home
29
- Retter.reset!
30
+
31
+ Retter::Site.reset!
30
32
  end
31
33
 
32
- config.before do
34
+ config.before :each do
33
35
  env = {'EDITOR' => fake_editor.to_path, 'RETTER_HOME' => RETTER_ROOT.join('tmp', 'test').to_s}
34
36
 
35
- Retter.load env
37
+ Retter::Site.load env
38
+ end
39
+
40
+ config.include Delorean
41
+ config.after :each do
42
+ back_to_the_present
36
43
  end
37
44
 
38
45
  config.include ExampleGroupHelper
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'time'
4
3
  require 'nokogiri'
4
+ require 'stringio'
5
5
 
6
6
  module ExampleGroupHelper
7
7
  module RetterShortcuts
@@ -9,8 +9,58 @@ module ExampleGroupHelper
9
9
  @command ||= Retter::Command.new
10
10
  end
11
11
 
12
+ def invoke_command(command_name, *args)
13
+ @command ||= Retter::Command.new
14
+
15
+ yield Retter::Site.config if block_given?
16
+
17
+ if args.last.is_a?(Hash)
18
+ options = args.pop
19
+
20
+ @command.stub!(:options) { options }
21
+ end
22
+
23
+ @command.__send__ command_name, *args
24
+ end
25
+
12
26
  def wip_file
13
- Retter.entries.wip_file
27
+ Retter::Site.entries.wip_file
28
+ end
29
+
30
+ def write_to_wip_file(body)
31
+ wip_file.open('w') {|f| f.write body }
32
+ end
33
+
34
+ def generated_file(path)
35
+ Retter::Site.config.retter_home.join(path)
36
+ end
37
+
38
+ def markdown_file(date)
39
+ date = date_wrap(date)
40
+
41
+ Retter::Site.entries.retter_file(date)
42
+ end
43
+
44
+ def find_entry_by_string(str)
45
+ Retter::Site.entries.detect_by_string(str)
46
+ end
47
+
48
+ def entry_html_file(date)
49
+ date = date_wrap(date)
50
+
51
+ Retter::Page.entry_file(date)
52
+ end
53
+
54
+ def article_html_file(date, id)
55
+ date = date_wrap(date)
56
+
57
+ Retter::Page.entry_dir(date).join("#{id}.html")
58
+ end
59
+
60
+ private
61
+
62
+ def date_wrap(str)
63
+ Date.parse(str.to_s)
14
64
  end
15
65
  end
16
66
 
@@ -29,30 +79,20 @@ module ExampleGroupHelper
29
79
  module Stream
30
80
  def capture(stream)
31
81
  begin
32
- stream = stream.to_s
33
82
  eval "$#{stream} = StringIO.new"
83
+
34
84
  yield
85
+
35
86
  result = eval("$#{stream}").string
36
87
  ensure
37
- eval("$#{stream} = #{stream.upcase}")
88
+ eval %($#{stream} = #{stream.upcase})
38
89
  end
39
90
 
40
91
  result
41
92
  end
42
93
  end
43
94
 
44
- module StubTime
45
- def stub_time(time_str)
46
- date = Date.parse(time_str)
47
- time = Time.parse(time_str)
48
-
49
- Date.stub!(:today).and_return(date)
50
- Time.stub!(:now).and_return(time)
51
- end
52
- end
53
-
54
95
  include RetterShortcuts
55
96
  include HTML
56
97
  include Stream
57
- include StubTime
58
98
  end
@@ -5,4 +5,3 @@ RSpec::Matchers.define :written do
5
5
  file.exist? && !file.size.zero?
6
6
  end
7
7
  end
8
-