rad_kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Rakefile +11 -0
  2. data/lib/components/kit.rb +16 -0
  3. data/lib/components/kit.yml +3 -0
  4. data/lib/components/models.rb +7 -0
  5. data/lib/kit/factories.rb +9 -0
  6. data/lib/kit/gems.rb +16 -0
  7. data/lib/kit/http_controller.rb +4 -0
  8. data/lib/kit/http_controller/authorized.rb +51 -0
  9. data/lib/kit/http_controller/localized.rb +13 -0
  10. data/lib/kit/kit.rb +29 -0
  11. data/lib/kit/models.rb +8 -0
  12. data/lib/kit/models/attachment_uploader.rb +15 -0
  13. data/lib/kit/models/attachments_uploader_helper.rb +79 -0
  14. data/lib/kit/models/authorized.rb +188 -0
  15. data/lib/kit/models/authorized_object.rb +167 -0
  16. data/lib/kit/models/default_permissions.yml +29 -0
  17. data/lib/kit/models/file_uploader.rb +26 -0
  18. data/lib/kit/models/micelaneous.rb +1 -0
  19. data/lib/kit/models/role.rb +88 -0
  20. data/lib/kit/models_after.rb +27 -0
  21. data/lib/kit/mongoid.rb +22 -0
  22. data/lib/kit/mongoid/rad_micelaneous.rb +36 -0
  23. data/lib/kit/mongoid/text_processor.rb +44 -0
  24. data/lib/kit/spec.rb +77 -0
  25. data/lib/kit/spec/items_controller_crud.rb +64 -0
  26. data/lib/kit/support.rb +14 -0
  27. data/lib/kit/support/string.rb +6 -0
  28. data/lib/kit/tasks.rb +18 -0
  29. data/lib/kit/text_utils.rb +43 -0
  30. data/lib/kit/text_utils/code_highlighter.rb +58 -0
  31. data/lib/kit/text_utils/custom_markdown.rb +90 -0
  32. data/lib/kit/text_utils/ensure_utf.rb +8 -0
  33. data/lib/kit/text_utils/github_flavoured_markdown.rb +32 -0
  34. data/lib/kit/text_utils/html_sanitizer.rb +89 -0
  35. data/lib/kit/text_utils/image_box.rb +35 -0
  36. data/lib/kit/text_utils/markup.rb +43 -0
  37. data/lib/kit/text_utils/processor.rb +25 -0
  38. data/lib/kit/text_utils/tag_shortcuts.rb +14 -0
  39. data/lib/kit/text_utils/truncate.rb +29 -0
  40. data/lib/kit/text_utils/truncator.rb +15 -0
  41. data/lib/kit/text_utils/urls.rb +13 -0
  42. data/readme.md +10 -0
  43. data/spec/controller/authorization_spec.rb +149 -0
  44. data/spec/controller/comments_spec.rb +54 -0
  45. data/spec/controller/items_spec.rb +45 -0
  46. data/spec/models/attachments_spec.rb +24 -0
  47. data/spec/models/attachments_spec/a.txt +1 -0
  48. data/spec/models/attachments_uploader_helper_spec.rb +108 -0
  49. data/spec/models/attachments_uploader_helper_spec/v1/a.txt +1 -0
  50. data/spec/models/attachments_uploader_helper_spec/v1/b.txt +1 -0
  51. data/spec/models/attachments_uploader_helper_spec/v2/a.txt +1 -0
  52. data/spec/models/authorization_spec.rb +77 -0
  53. data/spec/models/authorized_object_spec.rb +254 -0
  54. data/spec/models/comments_spec.rb +1 -0
  55. data/spec/models/item_spec.rb +51 -0
  56. data/spec/models/role_spec.rb +17 -0
  57. data/spec/models/tags_spec.rb +44 -0
  58. data/spec/models/uploader_spec.rb +37 -0
  59. data/spec/models/uploader_spec//321/204/320/260/320/270/314/206/320/273 /321/201 /320/277/321/200/320/276/320/261/320/265/320/273/320/260/320/274/320/270.txt" +1 -0
  60. data/spec/mongoid/basic_spec.rb +36 -0
  61. data/spec/spec_helper.rb +20 -0
  62. data/spec/spec_helper/controller.rb +9 -0
  63. data/spec/spec_helper/factories.rb +24 -0
  64. data/spec/spec_helper/user.rb +17 -0
  65. data/spec/utils/text_utils_spec.rb +280 -0
  66. metadata +232 -0
@@ -0,0 +1 @@
1
+ # check that comments are inherited properties of item, see CONTAINER_INHERITABLE_ATTRIBUTES
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe "item" do
4
+ with_models
5
+ login_as :user
6
+
7
+ it 'slug validation (from error)' do
8
+ i = Factory.create :item
9
+ i.slug = 'space '
10
+ i.should_not be_valid
11
+ end
12
+
13
+ describe 'safe_query' do
14
+ it "general case" do
15
+ Models::Item.safe_query(
16
+ name: 'name',
17
+ created_at: '10/11/2000',
18
+ order: "state asc",
19
+ owner_name: 'name',
20
+ state: ['state'],
21
+ tags: 'tag',
22
+ _type: 'Note',
23
+ updated_at: ['10/11/2000'],
24
+
25
+ viewers: 'role',
26
+ collaborators: 'role'
27
+ ).should == [{
28
+ "name"=>"name",
29
+ "created_at" => "10/11/2000".to_time,
30
+ "order" => "state asc",
31
+ "owner_name" => "name",
32
+ "state" => ["state"],
33
+ "tags" => "tag",
34
+ "_type" => "Note",
35
+ "updated_at" => ["10/11/2000".to_time]
36
+ }, true]
37
+ end
38
+
39
+ it "should allow only one-level order and only indexed keywords" do
40
+ Models::Item.safe_query(order: "name").should == [{'order' => "name"}, false]
41
+ Models::Item.safe_query(order: "name desc").should == [{'order' => "name desc"}, false]
42
+ Models::Item.safe_query(order: "name asc").should == [{'order' => "name asc"}, false]
43
+
44
+ Models::Item.safe_query(order: "dependent").should == [{}, true] # not indexed
45
+
46
+ # two level order
47
+ Models::Item.safe_query(order: "name created_at").should == [{'order' => 'name'}, true]
48
+ Models::Item.safe_query(order: "name created_at desc").should == [{'order' => 'name'}, true]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Role" do
4
+ with_models
5
+
6
+ it "normalization" do
7
+ Role.normalize_roles(%w{manager member specific_role user:user1}).should == %w{member specific_role user:user1}
8
+ end
9
+
10
+ it "denormalization to higher roles" do
11
+ Role.denormalize_to_higher_roles(%w{member specific_role user:user1}).should == %w{manager member specific_role user:user1}
12
+ end
13
+
14
+ it "denormalization to lower roles" do
15
+ Role.denormalize_to_lower_roles(%w{member specific_role user:user1}).should == %w{member specific_role user user:user1}
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Tags" do
4
+ with_models
5
+ login_as :user
6
+
7
+ it "should create tags with constructor initializer (from error)" do
8
+ item = Models::Item.new name: 'item', tags: ['a', 'b']
9
+ item.save!
10
+
11
+ item.reload
12
+ item.tags.should == ['a', 'b']
13
+ Models::Tag.count.should == 2
14
+ Models::Tag.all.collect(&:name).sort.should == ['a', 'b']
15
+ end
16
+
17
+ it "should create tags" do
18
+ item = Factory.create :item, tags_as_string: 'a, b'
19
+ Models::Item.count.should == 1
20
+ item.reload
21
+ item.tags.should == ['a', 'b']
22
+
23
+ Models::Tag.count.should == 2
24
+ Models::Tag.all.collect(&:name).sort.should == ['a', 'b']
25
+ end
26
+
27
+ it "should update tags after item update" do
28
+ item = Factory.create :item, tags_as_string: 'a, b'
29
+ Models::Tag.count.should == 2
30
+
31
+ item.tags = ['a', 'c']
32
+ item.save!
33
+
34
+ Models::Tag.count.should == 2
35
+ Models::Tag.all.collect(&:name).sort.should == ['a', 'c']
36
+ end
37
+
38
+ it "should update tags after item deletion" do
39
+ item = Factory.create :item, tags_as_string: 'a, b'
40
+ Models::Tag.count.should == 2
41
+ item.destroy
42
+ Models::Tag.count.should == 0
43
+ end
44
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Uploading" do
4
+ with_tmp_spec_dir
5
+ with_mongoid
6
+ with_files
7
+
8
+ before :all do
9
+ class TheImageUploader < Models::FileUploader
10
+ end
11
+
12
+ class ThePost
13
+ include Mongoid::Document
14
+
15
+ field :name, type: String, default: ""
16
+ validates_uniqueness_of :name
17
+
18
+ mount_uploader :image, TheImageUploader
19
+ end
20
+ end
21
+ after(:all){remove_constants :ThePost, :TheImageUploader}
22
+
23
+ it "should preserve spaces and unicode characters in filename" do
24
+ File.open "#{spec_dir}/файл с пробелами.txt" do |f|
25
+ ship = ThePost.new image: f
26
+
27
+ ship.image.url.should =~ /\/файл с пробелами\.txt/
28
+ ship.image.filename =~ /файл с пробелами\.txt/
29
+ ship.image.path =~ /\/файл с пробелами\.txt/
30
+
31
+ # ship.smart_url.should =~ /files\/file with spaces\/file with spaces\.txt\?\d/
32
+ # f.smart_url.should =~ /files\/data\/ship\?\d+/
33
+ # f.smart_url(:icon).should =~ /images\/mime\/dat_icon\.png/
34
+ # f.smart_url(:thumb).should =~ /images\/mime\/dat_thumb\.png/
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Rad Mongoid basics" do
4
+ with_mongoid
5
+
6
+ after(:all){remove_constants :ToRsonTest}
7
+
8
+ it "to_rson" do
9
+ class ToRsonTest
10
+ include Mongoid::Document
11
+
12
+ field :name, type: String
13
+ field :text, type: String
14
+ validates_presence_of :name
15
+ end
16
+ ToRsonTest.delete_all
17
+
18
+ ToRsonTest.create! name: 'a'
19
+ ToRsonTest.create! name: 'b'
20
+
21
+ # model.to_rson
22
+ o = ToRsonTest.first
23
+ r = o.to_rson
24
+ r.delete 'id'
25
+ r.should == {"name" => "a"}
26
+
27
+ o.to_rson(only: :name).should == {"name" => "a"}
28
+
29
+ # collections.to_rson
30
+ r = ToRsonTest.all.to_rson
31
+ r.collect!{|h| h.delete('id'); h}
32
+ r.should == [{"name" => "a"}, {"name" => "b"}]
33
+
34
+ ToRsonTest.all.to_rson(only: :name).should == [{"name" => "a"}, {"name" => "b"}]
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec_ext'
2
+
3
+ require 'rad'
4
+ require 'rad/spec'
5
+
6
+ require 'rad_ext'
7
+ require 'rad_ext/spec'
8
+
9
+ # require 'mongoid_rad'
10
+
11
+ require 'kit/spec'
12
+
13
+ # rad.config.runtime_path = 'tmp'
14
+ rad.kit
15
+
16
+ require 'kit/factories'
17
+
18
+ require 'spec_helper/user.rb'
19
+ require 'spec_helper/controller'
20
+ require 'spec_helper/factories'
@@ -0,0 +1,9 @@
1
+ Controllers::Base.class_eval do
2
+ def prepare_current_user; end
3
+ end
4
+
5
+ Rad::Controller::Context.class_eval do
6
+ def user_path name
7
+ "/user/#{name}"
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ require 'factory_girl'
2
+
3
+ #
4
+ # User
5
+ #
6
+ Factory.define :anonymous, class: 'Models::User' do |u|
7
+ u.name 'anonymous'
8
+ end
9
+
10
+ Factory.define :user, class: 'Models::User' do |u|
11
+ u.sequence(:name){|i| "user#{i}"}
12
+ end
13
+
14
+ Factory.define :admin, parent: :user do |u|
15
+ u.admin true
16
+ end
17
+
18
+ Factory.define :member, parent: :user do |u|
19
+ u.roles %w(member)
20
+ end
21
+
22
+ Factory.define :manager, parent: :user do |u|
23
+ u.roles %w(manager)
24
+ end
@@ -0,0 +1,17 @@
1
+ class Models::User
2
+ include Mongoid::Document
3
+
4
+ field :name, type: String
5
+
6
+ include Mongoid::Authorized
7
+
8
+ def anonymous?
9
+ name == 'anonymous'
10
+ end
11
+
12
+ class << self
13
+ def avatar_url *a; end
14
+
15
+ inject current: :user
16
+ end
17
+ end
@@ -0,0 +1,280 @@
1
+ require 'spec_helper'
2
+
3
+ # require 'kit/utils/text_utils.rb'
4
+
5
+ describe "TextUtils" do
6
+ def to_doc markup
7
+ Nokogiri::HTML(to_html(markup))
8
+ end
9
+
10
+ def to_html markup
11
+ Rad::TextUtils.markup(markup)
12
+ end
13
+
14
+ ::Nokogiri::XML::Node.class_eval do
15
+ def should_be_fuzzy_equal_to attributes
16
+ attributes.stringify_keys!
17
+ self.content.should == content if content = attributes.delete('content')
18
+
19
+ attributes.each do |attr_name, value|
20
+ self[attr_name].to_s.should == value.to_s
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "code highlighting" do
26
+ it "basic" do
27
+ to_html(%{<p> text </p><code lang='ruby'>class A; p "Hello World" end</code><p> text </p>}).should =~ /span/i
28
+ to_html(%{<p> text </p><code language='ruby'>class A; p "Hello World" end</code><p> text </p>}).should =~ /span/i
29
+ to_html(%{<code lang='ruby'>\nclass A \n def p\n 10\n end\nend \n</code>}).should =~ /span/i
30
+ end
31
+
32
+ it "should works with < and > in code" do
33
+ to_html(%{<code lang='ruby'>class A < ClassB; end</code>}).should include('ClassB')
34
+ end
35
+
36
+ it 'should preserve custom classes in <code>' do
37
+ to_html(%{<code lang='ruby' class='my_code'>\nclass A \n def p\n 10\n end\nend \n</code>}).should =~ /my_code/i
38
+ end
39
+ end
40
+
41
+ it "should not raise error on empty string" do
42
+ to_html('').should == ''
43
+ end
44
+
45
+ describe "MarkdDown" do
46
+
47
+
48
+ it "should do basic markup" do
49
+ doc = to_doc "**text**"
50
+ doc.css("p b, p strong").first.should_be_fuzzy_equal_to content: 'text'
51
+ end
52
+
53
+ it "should guess urls" do
54
+ doc = to_doc "This is a http://www.some.com/some link"
55
+ doc.content.strip.should == "This is a http://www.some.com/some link"
56
+ doc.css("p a").first.should_be_fuzzy_equal_to href: "http://www.some.com/some"
57
+
58
+ # from error
59
+ doc = to_doc "http://www.some.com/some"
60
+ doc.content.strip.should == "http://www.some.com/some"
61
+ doc.css("p a").first.should_be_fuzzy_equal_to href: "http://www.some.com/some"
62
+
63
+ # from error
64
+ # http://mastertalk.ru/topic111478.html
65
+ end
66
+
67
+ it "should allow 'a' elements" do
68
+ html = <<HTML
69
+ <a href="http://www.some.com/some">Absolute Link</a>
70
+ <a href="/some">Relative Link</a>
71
+ HTML
72
+
73
+ doc = to_doc html
74
+ doc.css("a").first[:href].should == "http://www.some.com/some"
75
+ doc.css("a").last[:href].should == "/some"
76
+ end
77
+
78
+ it "should embed YouTube Videos" do
79
+ html =<<HTML
80
+ <object width="425" height="344">
81
+ <param name="movie" value="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"></param>
82
+ <param name="allowFullScreen" value="true"></param>
83
+ <param name="allowscriptaccess" value="always"></param>
84
+ <embed src="http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
85
+ </object>
86
+ HTML
87
+
88
+ doc = to_doc html
89
+ obj = doc.css("object").first.should_be_fuzzy_equal_to width: 425, height: 344
90
+ p1, p2, p3, embed = doc.css("object *")
91
+ p1.should_be_fuzzy_equal_to name: "movie", value: "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&"
92
+ p2.should_be_fuzzy_equal_to name: "allowFullScreen", value: "true"
93
+ p3.should_be_fuzzy_equal_to name: "allowscriptaccess", value: "always"
94
+ embed.should_be_fuzzy_equal_to src: "http://www.youtube.com/v/s8hYKKXV5wU&hl=en_US&fs=1&",
95
+ type: "application/x-shockwave-flash", allowscriptaccess: "always",
96
+ allowfullscreen: "true", width: "425", height: "344"
97
+ end
98
+
99
+ it "should skip empty paragraphs" do
100
+ html = "line 1\n\nline 2\n\n\n\nline 3"
101
+ to_html(html).should =~ /<p>\s*line 1<\/p>\n<p>line 2<\/p>\n<p>line 3\s*<\/p>.?/
102
+ end
103
+
104
+ it "should convert \n to <br/>" do
105
+ to_doc("foo\nbar").css('br').size.should == 1
106
+ end
107
+
108
+ it "should not touch single underscores inside words" do
109
+ to_html("foo_bar").should include("foo_bar")
110
+ end
111
+
112
+ it "should works with unicode" do
113
+ html = %{Юникод <a href="http://www.some.com/" class="_image_box">Юникод</a>}
114
+ doc = to_doc html
115
+ doc.css('p').first.content.should =~ /Юникод/
116
+ doc.css('p a').first.should_be_fuzzy_equal_to href: "http://www.some.com/", class: "_image_box", content: "Юникод"
117
+ end
118
+
119
+ it 'should allow class and rel attribute' do
120
+ html = %{<a href="http://www.some.com/" class="_image_box" rel="nofollow">Some</a>}
121
+ doc = to_doc html
122
+ doc.css('a').first.should_be_fuzzy_equal_to href: "http://www.some.com/", class: "_image_box", rel: "nofollow"
123
+ end
124
+
125
+ it "should allow image inside of link" do
126
+ html = <<HTML
127
+ <a rel="article_images" class="_image_box" href="/some_image">
128
+ <img src="/some_image"></img>
129
+ </a>
130
+ HTML
131
+
132
+ doc = to_doc html
133
+ doc.css('a').first.should_be_fuzzy_equal_to href: "/some_image", class: "_image_box"
134
+ doc.css('a img').first.should_be_fuzzy_equal_to src: "/some_image"
135
+ end
136
+
137
+ it "should use simplifyed syntax for image boxes (!![img_thumb] => [![img_thumb]][img_full_version])" do
138
+ html = <<HTML
139
+ !![img]
140
+ ![img]
141
+
142
+ !![img_2]
143
+ ![img_2]
144
+
145
+ [img]: /some_prefix/image_name.png
146
+ [img_2]: /some_prefix/image_name2.icon.png
147
+ HTML
148
+
149
+ doc = to_doc html
150
+ doc.css('a').first.should_be_fuzzy_equal_to href: "/some_prefix/image_name.png"
151
+ doc.css('a img').first.should_be_fuzzy_equal_to src: "/some_prefix/image_name.thumb.png"
152
+
153
+ doc.css('a').last.should_be_fuzzy_equal_to href: "/some_prefix/image_name2.png"
154
+ doc.css('a img').last.should_be_fuzzy_equal_to src: "/some_prefix/image_name2.icon.png"
155
+
156
+ doc.css('img').size.should == 4
157
+ end
158
+
159
+ it "simplifyed syntax for image boxes should be robust (from error)" do
160
+ html = "!![img] " # without resolved reference
161
+ to_html(html)
162
+ lambda{to_html(html)}.should_not raise_error
163
+ end
164
+
165
+ it "should create teaser from text" do
166
+ text = %{Hi there, I have a page that will list news articles}
167
+ Rad::TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
168
+ end
169
+
170
+ it "should create teaser from html" do
171
+ text = %{Hi <div><b>there</b>, I have a page that will list news articles</div>}
172
+ Rad::TextUtils.truncate(text, 20).should == "Hi there, I have a ..."
173
+
174
+ Rad::TextUtils.truncate(%{a<br/>b}, 20).should == "a b" # from error
175
+ end
176
+
177
+ # it "embed metaweb.com wiget" do
178
+ # html = <<HTML
179
+ # <div itemtype="http://www.freebase.com/id/computer/software" itemid="http://www.freebase.com/id/en/google_web_toolkit" itemscope="" style="border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt; position: relative;" id="fbtb-6ffc2545598340cbbc7945f43ebd45de" class="fb-widget">
180
+ # <iframe frameborder="0" scrolling="no" src="http://www.freebase.com/widget/topic?track=topicblocks_homepage&amp;mode=content&amp;id=%2Fen%2Fgoogle_web_toolkit" style="height: 285px; width: 413px; border: 0pt none; outline: 0pt none; padding: 0pt; margin: 0pt;" classname="fb-widget-iframe" allowtransparency="true" class=" "></iframe>
181
+ # <script defer="" type="text/javascript" src="http://freebaselibs.com/static/widgets/2/widget.js"></script>
182
+ # </div>
183
+ # HTML
184
+ #
185
+ # text = "{metaweb:google_web_toolkit}"
186
+ # to_html(text).should include(html)
187
+ # end
188
+
189
+ it "should correctly insert newline (from error)" do
190
+ html = <<HTML
191
+ ![img] Open Design.
192
+ http://oomps.com
193
+
194
+ [img]: /some_link
195
+ HTML
196
+
197
+ to_doc(html).css('br').size.should == 1
198
+ end
199
+
200
+ it "clear div" do
201
+ html = "[clear]"
202
+
203
+ doc = to_doc html
204
+ doc.css('div.clear').size.should == 1
205
+ end
206
+
207
+ it "space div" do
208
+ html = "[space]"
209
+
210
+ doc = to_doc html
211
+ doc.css('div.space').size.should == 1
212
+ end
213
+
214
+ it "should correctly guess links (from error)" do
215
+ to_doc("http://some_domain.com http://some_domain.com").css('a').size == 2
216
+ end
217
+
218
+ it "should leave existing links intact" do
219
+ doc = to_doc(%{<a href="http://some_domain.com">http://some_domain.com</a>})
220
+ doc.css('a').size.should == 1
221
+ doc.css('a').first['href'].should == "http://some_domain.com"
222
+ end
223
+
224
+ it "should leave existing links intact" do
225
+ md = %{\
226
+ [Download Page][dl]
227
+ [dl]: http://www.mozilla.org/products/firefox/}
228
+
229
+ to_doc(md).css('a').first['href'].should == 'http://www.mozilla.org/products/firefox/'
230
+ end
231
+
232
+ it "should allow div with any classes (from error)" do
233
+ html = %{<div class="col3 left"><a href='#'>text</a></div>}
234
+ to_doc(html).css("div.col3.left a").size.should == 1
235
+ end
236
+
237
+ it "should apply markup inside of html elements (from error)" do
238
+ html = <<HTML
239
+ <div class='right'>
240
+ ![img]
241
+ </div>
242
+
243
+ [img]: /some_link
244
+ HTML
245
+
246
+ to_doc(html).css('.right img').size.should == 1
247
+ end
248
+
249
+ it "shouldn't create newline after > sign (from error)" do
250
+ html = %{\
251
+ <div>text</div>
252
+ text}
253
+ to_doc(html).css('br').size.should == 0
254
+ end
255
+
256
+ it "shouldn't add empty <p> before first line (from error)" do
257
+ to_html("<span>text</span>text").should_not =~ /<p>\s*<\/p>/
258
+ end
259
+ end
260
+
261
+ it "should not aply markdown if document specified as [html]" do
262
+ html = %{\
263
+ [html]
264
+ first line
265
+ **text**
266
+ second line}
267
+
268
+ r = to_html(html)
269
+ r.should_not include('<')
270
+ r.should_not include('[html]')
271
+ end
272
+
273
+ it "should still escape input in [html] mode" do
274
+ html = %{\
275
+ [html]
276
+ <script>some dangerous code</script>}
277
+
278
+ to_html(html).should_not include('script')
279
+ end
280
+ end