OSDN Git Service

t#29050:fix edit permissin
[pettanr/pettanr.git] / spec / controllers / panels_controller_spec.rb
1 # -*- encoding: utf-8 -*-\r
2 require 'spec_helper'\r
3 #コマ\r
4 describe PanelsController do\r
5   before do\r
6     Factory :admin\r
7     @license = Factory :license\r
8     @user = Factory :user_yas\r
9     @author = @user.author    #ユーザ作成時に連動して作成される\r
10   end\r
11   \r
12   describe '一覧表示に於いて' do\r
13     before do\r
14       @panel = Factory :panel, :author_id => @author.id\r
15       Panel.stub(:list).and_return([@panel, @panel, @panel])\r
16       sign_in @user\r
17     end\r
18     context '事前チェックする' do\r
19       it '与えられたpageがセットされている' do\r
20         get :index, :page => 5\r
21         assigns(:page).should eq 5\r
22       end\r
23       it '省略されると@pageに1値が入る' do\r
24         get :index\r
25         assigns(:page).should eq 1\r
26       end\r
27       it '与えられたpage_sizeがセットされている' do\r
28         get :index, :page_size => 15\r
29         assigns(:page_size).should eq 15\r
30       end\r
31       it '省略されると@page_sizeにデフォルト値が入る' do\r
32         get :index\r
33         assigns(:page_size).should eq Panel.default_page_size\r
34       end\r
35       it '最大を超えると@page_sizeにデフォルト最大値が入る' do\r
36         get :index, :page_size => 1500\r
37         assigns(:page_size).should eq Panel.max_page_size\r
38       end\r
39       it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do\r
40         get :index, :page_size => 0\r
41         assigns(:page_size).should eq Panel.default_page_size\r
42       end\r
43     end\r
44     context 'つつがなく終わるとき' do\r
45       it 'ステータスコード200 OKを返す' do\r
46         get :index\r
47         response.should be_success \r
48       end\r
49       it 'コマモデルに一覧を問い合わせている' do\r
50         Panel.should_receive(:list).exactly(1)\r
51         get :index\r
52       end\r
53       it '@panelsにリストを取得している' do\r
54         get :index\r
55         assigns(:panels).should have_at_least(3).items\r
56       end\r
57       context 'html形式' do\r
58         it 'indexテンプレートを描画する' do\r
59           get :index\r
60           response.should render_template("index")\r
61         end\r
62       end\r
63       context 'json形式' do\r
64         it 'jsonデータを返す' do\r
65           get :index, :format => :json\r
66           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
67         end\r
68         it 'データがリスト構造になっている' do\r
69           get :index, :format => :json\r
70           json = JSON.parse response.body\r
71           json.should have_at_least(3).items\r
72         end\r
73         it 'リストの先頭くらいはコマっぽいものであって欲しい' do\r
74           get :index, :format => :json\r
75           json = JSON.parse response.body\r
76           json.first.has_key?("border").should be_true\r
77         end\r
78       end\r
79     end\r
80     context '作家権限がないとき' do\r
81       before do\r
82         sign_out @user\r
83       end\r
84       context 'html形式' do\r
85         it 'ステータスコード302 Foundを返す' do\r
86           get :index\r
87           response.status.should eq 302\r
88         end\r
89         it 'サインインページへ遷移する' do\r
90           get :index\r
91           response.should redirect_to '/users/sign_in'\r
92         end\r
93       end\r
94       context 'json形式' do\r
95         it 'ステータスコード401 Unauthorizedを返す' do\r
96           get :index, :format => :json\r
97           response.status.should eq 401\r
98         end\r
99         it '応答メッセージにUnauthorizedを返す' do\r
100           get :index, :format => :json\r
101           response.message.should match(/Unauthorized/)\r
102         end\r
103       end\r
104     end\r
105   end\r
106   \r
107   describe '単体表示に於いて' do\r
108     before do\r
109       @panel = Factory :panel, :author_id => @user.author.id\r
110       Panel.stub(:show).and_return(@panel)\r
111       sign_in @user\r
112     end\r
113     context 'つつがなく終わるとき' do\r
114       it 'ステータスコード200 OKを返す' do\r
115         get :show, :id => @panel.id\r
116         response.should be_success\r
117       end\r
118       it 'コマモデルに単体取得を問い合わせている' do\r
119         Panel.should_receive(:show).exactly(1)\r
120         get :show\r
121       end\r
122       it '@panelにアレを取得している' do\r
123         get :show, :id => @panel.id\r
124         assigns(:panel).id.should eq(@panel.id)\r
125       end\r
126       context 'html形式' do\r
127         it 'showテンプレートを描画する' do\r
128           get :show, :id => @panel.id\r
129           response.should render_template("show")\r
130         end\r
131       end\r
132       context 'json形式' do\r
133         it 'jsonデータを返す' do\r
134           get :show, :id => @panel.id, :format => :json\r
135           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
136         end\r
137         it 'データがアレになっている' do\r
138           get :show, :id => @panel.id, :format => :json\r
139           json = JSON.parse response.body\r
140           json["width"].should eq 100\r
141         end\r
142       end\r
143     end\r
144     context '作家権限がないとき' do\r
145       before do\r
146         sign_out @user\r
147       end\r
148       context 'html形式' do\r
149         it 'ステータスコード302 Foundを返す' do\r
150           get :show, :id => @panel.id\r
151           response.status.should eq 302\r
152         end\r
153         it 'サインインページへ遷移する' do\r
154           get :show, :id => @panel.id\r
155           response.body.should redirect_to '/users/sign_in'\r
156         end\r
157       end\r
158       context 'json形式' do\r
159         it 'ステータスコード401 Unauthorizedを返す' do\r
160           get :show, :id => @panel.id, :format => :json\r
161           response.status.should eq 401\r
162         end\r
163         it '応答メッセージにUnauthorizedを返す' do\r
164           get :show, :id => @panel.id, :format => :json\r
165           response.message.should match(/Unauthorized/)\r
166         end\r
167       end\r
168     end\r
169 =begin\r
170     context '対象コマがないとき' do\r
171       context 'html形式' do\r
172         it '例外404 not_foundを返す' do\r
173           lambda{\r
174             get :show, :id => 0\r
175           }.should raise_error(ActiveRecord::RecordNotFound)\r
176         end\r
177       end\r
178       context 'json形式' do\r
179         it '例外404 not_foundを返す' do\r
180           lambda{ \r
181             get :show, :id => 0, :format => :json\r
182           }.should raise_error(ActiveRecord::RecordNotFound)\r
183         end\r
184       end\r
185     end\r
186     context '非公開コマを見ようとしたとき' do\r
187       context 'html形式' do\r
188         it '例外403 forbiddenを返す' do\r
189           Panel.any_instance.stub(:visible?).with(any_args()).and_return(false)\r
190           hidden = Factory :hidden_panel, :author_id => @author.id\r
191           lambda{\r
192             get :show, :id => hidden\r
193           }.should raise_error(ActiveRecord::Forbidden)\r
194         end\r
195       end\r
196       context 'json形式' do\r
197         it '例外403 forbiddenを返す' do\r
198           Panel.any_instance.stub(:visible?).with(any_args()).and_return(false)\r
199           hidden = Factory :hidden_panel, :author_id => @author.id\r
200           lambda{\r
201             get :show, :id => hidden, :format => :json\r
202           }.should raise_error(ActiveRecord::Forbidden)\r
203         end\r
204       end\r
205     end\r
206 =end\r
207   end\r
208   \r
209   describe 'コマ数取得に於いて' do\r
210     before do\r
211       Panel.should_receive(:visible_count).and_return(3)\r
212 #      sign_in @user\r
213     end\r
214     context 'つつがなく終わるとき' do\r
215       it 'ステータスコード200 OKを返す' do\r
216         get :count, :format => :json\r
217         response.should be_success \r
218       end\r
219       context 'json形式' do\r
220         it 'jsonデータを返す' do\r
221           get :count, :format => :json\r
222           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
223         end\r
224         it 'データがHash構造になっていてコマ数が1である' do\r
225           get :count, :format => :json\r
226           json = JSON.parse response.body\r
227           json["count"].should == 3\r
228         end\r
229       end\r
230     end\r
231   end\r
232   \r
233   describe '新規作成フォーム表示に於いて' do\r
234     before do\r
235       sign_in @user\r
236     end\r
237     context 'つつがなく終わるとき' do\r
238       it 'ステータスコード200 OKを返す' do\r
239         get :new\r
240         response.should be_success \r
241       end\r
242       it '@panelに新規データを用意している' do\r
243         get :new\r
244         assigns(:panel).should be_a_new(Panel)\r
245       end\r
246       it 'コマモデルにデフォルト値補充を依頼している' do\r
247         Panel.any_instance.should_receive(:supply_default).exactly(1)\r
248         get :new\r
249       end\r
250       context 'html形式' do\r
251         it 'newテンプレートを描画する' do\r
252           get :new\r
253           response.should render_template("new")\r
254         end\r
255       end\r
256       context 'js形式' do\r
257         it 'new.jsテンプレートを描画する' do\r
258           get :new, :format => :js\r
259           response.should render_template("new")\r
260         end\r
261       end\r
262     end\r
263     context '作家権限がないとき' do\r
264       before do\r
265         sign_out @user\r
266       end\r
267       context 'html形式' do\r
268         it 'ステータスコード302 Foundを返す' do\r
269           get :new\r
270           response.status.should eq 302\r
271         end\r
272         it 'サインインページへ遷移する' do\r
273           get :new\r
274           response.body.should redirect_to '/users/sign_in'\r
275         end\r
276       end\r
277       context 'js形式' do\r
278         it 'ステータスコード401 Unauthorizedを返す' do\r
279           get :new, :format => :js\r
280           response.status.should eq 401\r
281         end\r
282         it '応答メッセージにUnauthorizedを返す' do\r
283           get :new, :format => :js\r
284           response.message.should match(/Unauthorized/)\r
285         end\r
286       end\r
287     end\r
288   end\r
289   \r
290   describe '新規作成に於いて' do\r
291     before do\r
292       @panel = Factory :panel, :author_id => @user.author.id\r
293       @attr = Factory.attributes_for(:panel, :author_id => @author.id)\r
294       sign_in @user\r
295     end\r
296     context '事前チェックする' do\r
297       before do\r
298         controller\r
299         Panel.stub(:count).and_return(10)\r
300       end\r
301       it 'panelがパラメータにあれば、展開する' do\r
302         post :create, :panel => @attr\r
303         assigns(:prm)['border'].to_i.should eq @panel.border\r
304       end\r
305       it 'jsonがパラメータにあれば、展開する' do\r
306         post :create, :json => Factory.attributes_for(:panel, :border => 4).to_json\r
307         assigns(:prm)['border'].to_i.should eq 4\r
308       end\r
309       it 'panel・json両パラメータがあれば、panelを優先して展開する' do\r
310         post :create, {\r
311           :panel => Factory.attributes_for(:panel), \r
312           :json => Factory.attributes_for(:panel, :border => 4).to_json\r
313         }\r
314         assigns(:prm)['border'].to_i.should eq @panel.border\r
315       end\r
316     end\r
317     context 'つつがなく終わるとき' do\r
318       it 'コマモデルにデフォルト値補充を依頼している' do\r
319         Panel.any_instance.should_receive(:supply_default).exactly(1)\r
320         post :create, :panel => @attr\r
321       end\r
322       it 'コマモデルに上書き補充を依頼している' do\r
323         Panel.any_instance.should_receive(:overwrite).exactly(1)\r
324         post :create, :panel => @attr\r
325       end\r
326       it 'モデルに保存依頼する' do\r
327         Panel.any_instance.should_receive(:store).exactly(1)\r
328         post :create, :panel => @attr\r
329       end\r
330       it "@panelに作成されたコマを保持していて、それがDBにある" do\r
331         post :create, :panel => @attr\r
332         assigns(:panel).should be_a(Panel)\r
333         assigns(:panel).should be_persisted\r
334       end\r
335       context 'html形式' do\r
336         it 'ステータスコード302 Foundを返す' do\r
337           Panel.any_instance.stub(:store).and_return(true)\r
338           post :create, :panel => @attr\r
339           response.status.should eq 302\r
340         end\r
341         it '作成されたコマの表示ページへ遷移する' do\r
342 #          Panel.any_instance.stub(:store).and_return(true)\r
343           post :create, :panel => @attr\r
344           response.should redirect_to(Panel.last)\r
345         end\r
346       end\r
347       context 'json形式' do\r
348         it 'ステータスコード200 OKを返す' do\r
349 #          Panel.any_instance.stub(:store).and_return(true)\r
350           post :create, :panel => @attr, :format => :json\r
351           response.should be_success \r
352         end\r
353         it '作成されたコマをjsonデータで返す' do\r
354           post :create, :panel => @attr, :format => :json\r
355           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
356         end\r
357         it 'データがアレになっている' do\r
358           post :create, :panel => @attr, :format => :json\r
359           json = JSON.parse response.body\r
360           json["width"].should eq @panel.width\r
361         end\r
362       end\r
363     end\r
364     context '作家権限がないとき' do\r
365       before do\r
366         sign_out @user\r
367       end\r
368       context 'html形式' do\r
369         it 'ステータスコード302 Foundを返す' do\r
370           post :create, :panel => @attr\r
371           response.status.should eq 302\r
372         end\r
373         it 'サインインページへ遷移する' do\r
374           post :create, :panel => @attr\r
375           response.body.should redirect_to '/users/sign_in'\r
376         end\r
377       end\r
378       context 'json形式' do\r
379         it 'ステータスコード401 Unauthorizedを返す' do\r
380           post :create, :panel => @attr, :format => :json\r
381           response.status.should eq 401\r
382         end\r
383         it '応答メッセージにUnauthorizedを返す' do\r
384           post :create, :panel => @attr, :format => :json\r
385           response.message.should match(/Unauthorized/)\r
386         end\r
387       end\r
388     end\r
389     context '検証、保存に失敗した' do\r
390       before do\r
391         Panel.any_instance.stub(:store).and_return(false)\r
392       end\r
393       it "未保存のコマを保持している" do\r
394         post :create, :panel => @attr\r
395         assigns(:panel).should be_a_new(Panel)\r
396       end\r
397       context 'html形式' do\r
398         it 'ステータスコード200 OKを返す' do\r
399           post :create, :panel => @attr\r
400           response.status.should eq 200\r
401         end\r
402         it '新規ページを描画する' do\r
403           post :create, :panel => @attr\r
404           response.should render_template("new")\r
405         end\r
406       end\r
407       context 'json形式' do\r
408         it 'ステータスコード422 unprocessable_entity を返す' do\r
409           post :create, :panel => @attr, :format => :json\r
410           response.status.should eq 422\r
411         end\r
412         it '応答メッセージUnprocessable Entityを返す' do\r
413           post :create, :panel => @attr, :format => :json\r
414           response.message.should match(/Unprocessable/)\r
415         end\r
416       end\r
417     end\r
418   end\r
419 \r
420   describe '編集フォーム表示に於いて' do\r
421     before do\r
422       @panel = Factory :panel, :author_id => @author.id\r
423       sign_in @user\r
424       Panel.stub(:show).and_return(@panel)\r
425     end\r
426     context 'つつがなく終わるとき' do\r
427       it 'ステータスコード200 OKを返す' do\r
428         get :edit, :id => @panel.id\r
429         response.should be_success \r
430       end\r
431       it 'コマモデルに単体取得を問い合わせている' do\r
432         Panel.should_receive(:show).exactly(1)\r
433         get :edit, :id => @panel.id\r
434       end\r
435       it '@panelにデータを用意している' do\r
436         get :edit, :id => @panel.id\r
437         assigns(:panel).should eq @panel\r
438       end\r
439       context 'html形式' do\r
440         it 'editテンプレートを描画する' do\r
441           get :edit, :id => @panel.id\r
442           response.should render_template("edit")\r
443         end\r
444       end\r
445       context 'js形式' do\r
446         it 'edit.jsテンプレートを描画する' do\r
447           get :edit, :id => @panel.id, :format => :js\r
448           response.should render_template("edit")\r
449         end\r
450       end\r
451     end\r
452     context '作家権限がないとき' do\r
453       before do\r
454         sign_out @user\r
455       end\r
456       context 'html形式' do\r
457         it 'ステータスコード302 Foundを返す' do\r
458           get :edit, :id => @panel.id\r
459           response.status.should eq 302\r
460         end\r
461         it 'サインインページへ遷移する' do\r
462           get :edit, :id => @panel.id\r
463           response.body.should redirect_to '/users/sign_in'\r
464         end\r
465       end\r
466       context 'js形式' do\r
467         it 'ステータスコード401 Unauthorizedを返す' do\r
468           get :edit, :id => @panel.id, :format => :js\r
469           response.status.should eq 401\r
470         end\r
471         it '応答メッセージにUnauthorizedを返す' do\r
472           get :edit, :id => @panel.id, :format => :js\r
473           response.message.should match(/Unauthorized/)\r
474         end\r
475       end\r
476     end\r
477   end\r
478 \r
479   describe '更新に於いて' do\r
480     before do\r
481       @panel = Factory :panel, :author_id => @user.author.id\r
482       @attr = Factory.attributes_for(:panel, :author_id => @author.id)\r
483       sign_in @user\r
484     end\r
485     context '事前チェックする' do\r
486       before do\r
487         controller\r
488         Panel.stub(:count).and_return(10)\r
489       end\r
490       it 'panelがパラメータにあれば、展開する' do\r
491         put :update, :id => @panel.id, :panel => @attr\r
492         assigns(:prm)['border'].to_i.should eq @panel.border\r
493       end\r
494       it 'jsonがパラメータにあれば、展開する' do\r
495         put :update, :id => @panel.id, :json => Factory.attributes_for(:panel, :border => 4).to_json\r
496         assigns(:prm)['border'].to_i.should eq 4\r
497       end\r
498       it 'panel・json両パラメータがあれば、panelを優先して展開する' do\r
499         put :update, {\r
500           :id => @panel.id, \r
501           :panel => Factory.attributes_for(:panel), \r
502           :json => Factory.attributes_for(:panel, :border => 4).to_json\r
503         }\r
504         assigns(:prm)['border'].to_i.should eq @panel.border\r
505       end\r
506     end\r
507     context 'つつがなく終わるとき' do\r
508       it 'モデルに編集取得依頼する' do\r
509         Panel.stub(:edit).with(any_args).and_return(@panel)\r
510         Panel.should_receive(:edit).exactly(1)\r
511         put :update, :id => @panel.id, :panel => @attr\r
512       end\r
513       it 'コマモデルに上書き補充を依頼している' do\r
514         Panel.any_instance.should_receive(:overwrite).exactly(1)\r
515         put :update, :id => @panel.id, :panel => @attr\r
516       end\r
517       it 'モデルに保存依頼する' do\r
518         Panel.any_instance.should_receive(:store).exactly(1)\r
519         put :update, :id => @panel.id, :panel => @attr\r
520       end\r
521       it "@panelに作成されたコマを保持していて、それがDBにある" do\r
522         put :update, :id => @panel.id, :panel => @attr\r
523         assigns(:panel).should be_a(Panel)\r
524         assigns(:panel).should be_persisted\r
525       end\r
526       context 'html形式' do\r
527         it 'ステータスコード302 Foundを返す' do\r
528           Panel.any_instance.stub(:store).and_return(true)\r
529           put :update, :id => @panel.id, :panel => @attr\r
530           response.status.should eq 302\r
531         end\r
532         it '作成されたコマの表示ページへ遷移する' do\r
533 #          Panel.any_instance.stub(:store).and_return(true)\r
534           put :update, :id => @panel.id, :panel => @attr\r
535           response.should redirect_to(Panel.last)\r
536         end\r
537       end\r
538       context 'json形式' do\r
539         it 'ステータスコード200 OKを返す' do\r
540 #          Panel.any_instance.stub(:store).and_return(true)\r
541           put :update, :id => @panel.id, :panel => @attr, :format => :json\r
542           response.should be_success \r
543         end\r
544       end\r
545     end\r
546     context '作家権限がないとき' do\r
547       before do\r
548         sign_out @user\r
549       end\r
550       context 'html形式' do\r
551         it 'ステータスコード302 Foundを返す' do\r
552           put :update, :id => @panel.id, :panel => @attr\r
553           response.status.should eq 302\r
554         end\r
555         it 'サインインページへ遷移する' do\r
556           put :update, :id => @panel.id, :panel => @attr\r
557           response.body.should redirect_to '/users/sign_in'\r
558         end\r
559       end\r
560       context 'json形式' do\r
561         it 'ステータスコード401 Unauthorizedを返す' do\r
562           put :update, :id => @panel.id, :panel => @attr, :format => :json\r
563           response.status.should eq 401\r
564         end\r
565         it '応答メッセージにUnauthorizedを返す' do\r
566           put :update, :id => @panel.id, :panel => @attr, :format => :json\r
567           response.message.should match(/Unauthorized/)\r
568         end\r
569       end\r
570     end\r
571     context '検証、保存に失敗した' do\r
572       before do\r
573         Panel.any_instance.stub(:store).and_return(false)\r
574       end\r
575       it "指定のコマを保持している" do\r
576         put :update, :id => @panel.id, :panel => @attr\r
577         assigns(:panel).should eq @panel\r
578       end\r
579       context 'html形式' do\r
580         it 'ステータスコード200 OKを返す' do\r
581           put :update, :id => @panel.id, :panel => @attr\r
582           response.status.should eq 200\r
583         end\r
584         it '編集ページを描画する' do\r
585           put :update, :id => @panel.id, :panel => @attr\r
586           response.should render_template("edit")\r
587         end\r
588       end\r
589       context 'json形式' do\r
590         it 'ステータスコード422 unprocessable_entity を返す' do\r
591           put :update, :id => @panel.id, :panel => @attr, :format => :json\r
592           response.status.should eq 422\r
593         end\r
594         it '応答メッセージUnprocessable Entityを返す' do\r
595           put :update, :id => @panel.id, :panel => @attr, :format => :json\r
596           response.message.should match(/Unprocessable/)\r
597         end\r
598       end\r
599     end\r
600   end\r
601 \r
602   describe '削除に於いて' do\r
603     before do\r
604       @panel = Factory :panel, :author_id => @user.author.id\r
605       Panel.stub(:edit).and_return(@panel)\r
606       sign_in @user\r
607     end\r
608     context 'つつがなく終わるとき' do\r
609       it 'コマモデルに編集取得を問い合わせている' do\r
610         Panel.should_receive(:edit).exactly(1)\r
611         delete :destroy, :id => @panel.id\r
612       end\r
613       it '@panelにアレを取得している' do\r
614         delete :destroy, :id => @panel.id\r
615         assigns(:panel).id.should eq(@panel.id)\r
616       end\r
617       it 'そのコマを一つのトランザクションで削除する' do\r
618         lambda {\r
619           delete :destroy, :id => @panel.id\r
620         }.should change(Panel, :count)\r
621       end\r
622       context 'html形式' do\r
623         it 'ステータスコード302 Foundを返す' do\r
624           delete :destroy, :id => @panel.id\r
625           response.status.should eq 302\r
626         end\r
627         it 'コマ一覧ページへ遷移する' do\r
628           delete :destroy, :id => @panel.id\r
629           response.should redirect_to(panels_url)\r
630         end\r
631       end\r
632       context 'json形式' do\r
633         it 'ステータスコード200 OKを返す' do\r
634           delete :destroy, :id => @panel.id, :format => :json\r
635           response.should be_success\r
636         end\r
637       end\r
638     end\r
639     context '作家権限がないとき' do\r
640       before do\r
641         sign_out @user\r
642       end\r
643       context 'html形式' do\r
644         it 'ステータスコード302 Foundを返す' do\r
645           delete :destroy, :id => @panel.id\r
646           response.status.should eq 302\r
647         end\r
648         it 'サインインページへ遷移する' do\r
649           delete :destroy, :id => @panel.id\r
650           response.body.should redirect_to '/users/sign_in'\r
651         end\r
652       end\r
653       context 'json形式' do\r
654         it 'ステータスコード401 Unauthorizedを返す' do\r
655           delete :destroy, :id => @panel.id, :format => :json\r
656           response.status.should eq 401\r
657         end\r
658         it '応答メッセージにUnauthorizedを返す' do\r
659           delete :destroy, :id => @panel.id, :format => :json\r
660           response.message.should match(/Unauthorized/)\r
661         end\r
662       end\r
663     end\r
664 =begin\r
665     context '対象コマがないとき' do\r
666     end\r
667     context '他人のコマだったとき' do\r
668     end\r
669 =end\r
670   end\r
671   \r
672 end\r
673 \r