Revision 1297:0a574315af3e .svn/pristine/6e

View differences:

.svn/pristine/6e/6e19e1e338055e9065d37596fdaf97de3c4d84c3.svn-base
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module CustomFieldsHelper
21

  
22
  def custom_fields_tabs
23
    CustomField::CUSTOM_FIELDS_TABS
24
  end
25

  
26
  # Return custom field html tag corresponding to its format
27
  def custom_field_tag(name, custom_value)	
28
    custom_field = custom_value.custom_field
29
    field_name = "#{name}[custom_field_values][#{custom_field.id}]"
30
    field_name << "[]" if custom_field.multiple?
31
    field_id = "#{name}_custom_field_values_#{custom_field.id}"
32

  
33
    tag_options = {:id => field_id, :class => "#{custom_field.field_format}_cf"}
34

  
35
    field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
36
    case field_format.try(:edit_as)
37
    when "date"
38
      text_field_tag(field_name, custom_value.value, tag_options.merge(:size => 10)) +
39
      calendar_for(field_id)
40
    when "text"
41
      text_area_tag(field_name, custom_value.value, tag_options.merge(:rows => 3))
42
    when "bool"
43
      hidden_field_tag(field_name, '0') + check_box_tag(field_name, '1', custom_value.true?, tag_options)
44
    when "list"
45
      blank_option = ''.html_safe
46
      unless custom_field.multiple?
47
        if custom_field.is_required?
48
          unless custom_field.default_value.present?
49
            blank_option = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '')
50
          end
51
        else
52
          blank_option = content_tag('option')
53
        end
54
      end
55
      s = select_tag(field_name, blank_option + options_for_select(custom_field.possible_values_options(custom_value.customized), custom_value.value),
56
        tag_options.merge(:multiple => custom_field.multiple?))
57
      if custom_field.multiple?
58
        s << hidden_field_tag(field_name, '')
59
      end
60
      s
61
    else
62
      text_field_tag(field_name, custom_value.value, tag_options)
63
    end
64
  end
65

  
66
  # Return custom field label tag
67
  def custom_field_label_tag(name, custom_value, options={})
68
    required = options[:required] || custom_value.custom_field.is_required?
69

  
70
    content_tag "label", h(custom_value.custom_field.name) +
71
      (required ? " <span class=\"required\">*</span>".html_safe : ""),
72
      :for => "#{name}_custom_field_values_#{custom_value.custom_field.id}"
73
  end
74

  
75
  # Return custom field tag with its label tag
76
  def custom_field_tag_with_label(name, custom_value, options={})
77
    custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)
78
  end
79

  
80
  def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil)
81
    field_name = "#{name}[custom_field_values][#{custom_field.id}]"
82
    field_name << "[]" if custom_field.multiple?
83
    field_id = "#{name}_custom_field_values_#{custom_field.id}"
84

  
85
    tag_options = {:id => field_id, :class => "#{custom_field.field_format}_cf"}
86

  
87
    field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
88
    case field_format.try(:edit_as)
89
      when "date"
90
        text_field_tag(field_name, '', tag_options.merge(:size => 10)) +
91
        calendar_for(field_id)
92
      when "text"
93
        text_area_tag(field_name, '', tag_options.merge(:rows => 3))
94
      when "bool"
95
        select_tag(field_name, options_for_select([[l(:label_no_change_option), ''],
96
                                                   [l(:general_text_yes), '1'],
97
                                                   [l(:general_text_no), '0']]), tag_options)
98
      when "list"
99
        options = []
100
        options << [l(:label_no_change_option), ''] unless custom_field.multiple?
101
        options << [l(:label_none), '__none__'] unless custom_field.is_required?
102
        options += custom_field.possible_values_options(projects)
103
        select_tag(field_name, options_for_select(options), tag_options.merge(:multiple => custom_field.multiple?))
104
      else
105
        text_field_tag(field_name, '', tag_options)
106
    end
107
  end
108

  
109
  # Return a string used to display a custom value
110
  def show_value(custom_value)
111
    return "" unless custom_value
112
    format_value(custom_value.value, custom_value.custom_field.field_format)
113
  end
114

  
115
  # Return a string used to display a custom value
116
  def format_value(value, field_format)
117
    if value.is_a?(Array)
118
      value.collect {|v| format_value(v, field_format)}.compact.sort.join(', ')
119
    else
120
      Redmine::CustomFieldFormat.format_value(value, field_format)
121
    end
122
  end
123

  
124
  # Return an array of custom field formats which can be used in select_tag
125
  def custom_field_formats_for_select(custom_field)
126
    Redmine::CustomFieldFormat.as_select(custom_field.class.customized_class.name)
127
  end
128

  
129
  # Renders the custom_values in api views
130
  def render_api_custom_values(custom_values, api)
131
    api.array :custom_fields do
132
      custom_values.each do |custom_value|
133
        attrs = {:id => custom_value.custom_field_id, :name => custom_value.custom_field.name}
134
        attrs.merge!(:multiple => true) if custom_value.custom_field.multiple?
135
        api.custom_field attrs do
136
          if custom_value.value.is_a?(Array)
137
            api.array :value do
138
              custom_value.value.each do |value|
139
                api.value value unless value.blank?
140
              end
141
            end
142
          else
143
            api.value custom_value.value
144
          end
145
        end
146
      end
147
    end unless custom_values.empty?
148
  end
149
end
.svn/pristine/6e/6e9e1243ef58d1f7ab5c26c4b1c4078ac0562ef5.svn-base
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2012  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module MailHandlerHelper
21
end
.svn/pristine/6e/6ec02141f430c80f57516715f8456cabdaf278c2.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.expand_path('../../../../../test_helper', __FILE__)
19
require 'digest/md5'
20

  
21
class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
22

  
23
  def setup
24
    @formatter = Redmine::WikiFormatting::Textile::Formatter
25
  end
26

  
27
  MODIFIERS = {
28
    "*" => 'strong', # bold
29
    "_" => 'em',     # italic
30
    "+" => 'ins',    # underline
31
    "-" => 'del',    # deleted
32
    "^" => 'sup',    # superscript
33
    "~" => 'sub'     # subscript
34
  }
35

  
36
  def test_modifiers
37
    assert_html_output(
38
      '*bold*'                => '<strong>bold</strong>',
39
      'before *bold*'         => 'before <strong>bold</strong>',
40
      '*bold* after'          => '<strong>bold</strong> after',
41
      '*two words*'           => '<strong>two words</strong>',
42
      '*two*words*'           => '<strong>two*words</strong>',
43
      '*two * words*'         => '<strong>two * words</strong>',
44
      '*two* *words*'         => '<strong>two</strong> <strong>words</strong>',
45
      '*(two)* *(words)*'     => '<strong>(two)</strong> <strong>(words)</strong>',
46
      # with class
47
      '*(foo)two words*'      => '<strong class="foo">two words</strong>'
48
    )
49
  end
50

  
51
  def test_modifiers_combination
52
    MODIFIERS.each do |m1, tag1|
53
      MODIFIERS.each do |m2, tag2|
54
        next if m1 == m2
55
        text = "#{m2}#{m1}Phrase modifiers#{m1}#{m2}"
56
        html = "<#{tag2}><#{tag1}>Phrase modifiers</#{tag1}></#{tag2}>"
57
        assert_html_output text => html
58
      end
59
    end
60
  end
61

  
62
  def test_styles
63
    # single style
64
    assert_html_output({
65
      'p{color:red}. text'           => '<p style="color:red;">text</p>',
66
      'p{color:red;}. text'          => '<p style="color:red;">text</p>',
67
      'p{color: red}. text'          => '<p style="color: red;">text</p>',
68
      'p{color:#f00}. text'          => '<p style="color:#f00;">text</p>',
69
      'p{color:#ff0000}. text'       => '<p style="color:#ff0000;">text</p>',
70
      'p{border:10px}. text'         => '<p style="border:10px;">text</p>',
71
      'p{border:10}. text'           => '<p style="border:10;">text</p>',
72
      'p{border:10%}. text'          => '<p style="border:10%;">text</p>',
73
      'p{border:10em}. text'         => '<p style="border:10em;">text</p>',
74
      'p{border:1.5em}. text'        => '<p style="border:1.5em;">text</p>',
75
      'p{border-left:1px}. text'     => '<p style="border-left:1px;">text</p>',
76
      'p{border-right:1px}. text'    => '<p style="border-right:1px;">text</p>',
77
      'p{border-top:1px}. text'      => '<p style="border-top:1px;">text</p>',
78
      'p{border-bottom:1px}. text'   => '<p style="border-bottom:1px;">text</p>',
79
      }, false)
80

  
81
    # multiple styles
82
    assert_html_output({
83
      'p{color:red; border-top:1px}. text'   => '<p style="color:red;border-top:1px;">text</p>',
84
      'p{color:red ; border-top:1px}. text'  => '<p style="color:red;border-top:1px;">text</p>',
85
      'p{color:red;border-top:1px}. text'    => '<p style="color:red;border-top:1px;">text</p>',
86
      }, false)
87

  
88
    # styles with multiple values
89
    assert_html_output({
90
      'p{border:1px solid red;}. text'             => '<p style="border:1px solid red;">text</p>',
91
      'p{border-top-left-radius: 10px 5px;}. text' => '<p style="border-top-left-radius: 10px 5px;">text</p>',
92
      }, false)
93
  end
94

  
95
  def test_invalid_styles_should_be_filtered
96
    assert_html_output({
97
      'p{invalid}. text'                     => '<p>text</p>',
98
      'p{invalid:red}. text'                 => '<p>text</p>',
99
      'p{color:(red)}. text'                 => '<p>text</p>',
100
      'p{color:red;invalid:blue}. text'      => '<p style="color:red;">text</p>',
101
      'p{invalid:blue;color:red}. text'      => '<p style="color:red;">text</p>',
102
      'p{color:"}. text'                     => '<p>p{color:"}. text</p>',
103
      }, false)
104
  end
105

  
106
  def test_inline_code
107
    assert_html_output(
108
      'this is @some code@'      => 'this is <code>some code</code>',
109
      '@<Location /redmine>@'    => '<code>&lt;Location /redmine&gt;</code>'
110
    )
111
  end
112

  
113
  def test_nested_lists
114
    raw = <<-RAW
115
# Item 1
116
# Item 2
117
** Item 2a
118
** Item 2b
119
# Item 3
120
** Item 3a
121
RAW
122

  
123
    expected = <<-EXPECTED
124
<ol>
125
  <li>Item 1</li>
126
  <li>Item 2
127
    <ul>
128
      <li>Item 2a</li>
129
      <li>Item 2b</li>
130
    </ul>
131
  </li>
132
  <li>Item 3
133
    <ul>
134
      <li>Item 3a</li>
135
    </ul>
136
  </li>
137
</ol>
138
EXPECTED
139

  
140
    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
141
  end
142

  
143
  def test_escaping
144
    assert_html_output(
145
      'this is a <script>'      => 'this is a &lt;script&gt;'
146
    )
147
  end
148

  
149
  def test_use_of_backslashes_followed_by_numbers_in_headers
150
    assert_html_output({
151
      'h1. 2009\02\09'      => '<h1>2009\02\09</h1>'
152
    }, false)
153
  end
154

  
155
  def test_double_dashes_should_not_strikethrough
156
    assert_html_output(
157
      'double -- dashes -- test'  => 'double -- dashes -- test',
158
      'double -- *dashes* -- test'  => 'double -- <strong>dashes</strong> -- test'
159
    )
160
  end
161

  
162
  def test_acronyms
163
    assert_html_output(
164
      'this is an acronym: GPL(General Public License)' => 'this is an acronym: <acronym title="General Public License">GPL</acronym>',
165
      '2 letters JP(Jean-Philippe) acronym' => '2 letters <acronym title="Jean-Philippe">JP</acronym> acronym',
166
      'GPL(This is a double-quoted "title")' => '<acronym title="This is a double-quoted &quot;title&quot;">GPL</acronym>'
167
    )
168
  end
169

  
170
  def test_blockquote
171
    # orig raw text
172
    raw = <<-RAW
173
John said:
174
> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
175
> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
176
> * Donec odio lorem,
177
> * sagittis ac,
178
> * malesuada in,
179
> * adipiscing eu, dolor.
180
>
181
> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
182
> Proin a tellus. Nam vel neque.
183

  
184
He's right.
185
RAW
186

  
187
    # expected html
188
    expected = <<-EXPECTED
189
<p>John said:</p>
190
<blockquote>
191
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.<br />
192
Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
193
<ul>
194
  <li>Donec odio lorem,</li>
195
  <li>sagittis ac,</li>
196
  <li>malesuada in,</li>
197
  <li>adipiscing eu, dolor.</li>
198
</ul>
199
<blockquote>
200
<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
201
</blockquote>
202
<p>Proin a tellus. Nam vel neque.</p>
203
</blockquote>
204
<p>He's right.</p>
205
EXPECTED
206

  
207
    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
208
  end
209

  
210
  def test_table
211
    raw = <<-RAW
212
This is a table with empty cells:
213

  
214
|cell11|cell12||
215
|cell21||cell23|
216
|cell31|cell32|cell33|
217
RAW
218

  
219
    expected = <<-EXPECTED
220
<p>This is a table with empty cells:</p>
221

  
222
<table>
223
  <tr><td>cell11</td><td>cell12</td><td></td></tr>
224
  <tr><td>cell21</td><td></td><td>cell23</td></tr>
225
  <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
226
</table>
227
EXPECTED
228

  
229
    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
230
  end
231

  
232
  def test_table_with_line_breaks
233
    raw = <<-RAW
234
This is a table with line breaks:
235

  
236
|cell11
237
continued|cell12||
238
|-cell21-||cell23
239
cell23 line2
240
cell23 *line3*|
241
|cell31|cell32
242
cell32 line2|cell33|
243

  
244
RAW
245

  
246
    expected = <<-EXPECTED
247
<p>This is a table with line breaks:</p>
248

  
249
<table>
250
  <tr>
251
    <td>cell11<br />continued</td>
252
    <td>cell12</td>
253
    <td></td>
254
  </tr>
255
  <tr>
256
    <td><del>cell21</del></td>
257
    <td></td>
258
    <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
259
  </tr>
260
  <tr>
261
    <td>cell31</td>
262
    <td>cell32<br/>cell32 line2</td>
263
    <td>cell33</td>
264
  </tr>
265
</table>
266
EXPECTED
267

  
268
    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
269
  end
270

  
271
  def test_textile_should_not_mangle_brackets
272
    assert_equal '<p>[msg1][msg2]</p>', to_html('[msg1][msg2]')
273
  end
274

  
275
  def test_textile_should_escape_image_urls
276
    # this is onclick="alert('XSS');" in encoded form
277
    raw = '!/images/comment.png"onclick=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;;&#x22;!'
278
    expected = '<p><img src="/images/comment.png&quot;onclick=&amp;#x61;&amp;#x6c;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x27;&amp;#x58;&amp;#x53;&amp;#x53;&amp;#x27;&amp;#x29;;&amp;#x22;" alt="" /></p>'
279
    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
280
  end
281
  
282
  
283
  STR_WITHOUT_PRE = [
284
  # 0
285
"h1. Title
286

  
287
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
288
  # 1
289
"h2. Heading 2
290

  
291
Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
292

  
293
Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.",
294
  # 2
295
"h2. Heading 2
296

  
297
Morbi facilisis accumsan orci non pharetra.
298

  
299
h3. Heading 3
300

  
301
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.",
302
  # 3
303
"h3. Heading 3
304

  
305
Praesent eget turpis nibh, a lacinia nulla.",
306
  # 4
307
"h2. Heading 2
308

  
309
Ut rhoncus elementum adipiscing."]
310

  
311
  TEXT_WITHOUT_PRE = STR_WITHOUT_PRE.join("\n\n").freeze
312
  
313
  def test_get_section_should_return_the_requested_section_and_its_hash
314
    assert_section_with_hash STR_WITHOUT_PRE[1], TEXT_WITHOUT_PRE, 2
315
    assert_section_with_hash STR_WITHOUT_PRE[2..3].join("\n\n"), TEXT_WITHOUT_PRE, 3
316
    assert_section_with_hash STR_WITHOUT_PRE[3], TEXT_WITHOUT_PRE, 5
317
    assert_section_with_hash STR_WITHOUT_PRE[4], TEXT_WITHOUT_PRE, 6
318
    
319
    assert_section_with_hash '', TEXT_WITHOUT_PRE, 0
320
    assert_section_with_hash '', TEXT_WITHOUT_PRE, 10
321
  end
322
  
323
  def test_update_section_should_update_the_requested_section
324
    replacement = "New text"
325
    
326
    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement)
327
    assert_equal [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement)
328
    assert_equal [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement)
329
    assert_equal [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement)
330
    
331
    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement)
332
    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(10, replacement)
333
  end
334
  
335
  def test_update_section_with_hash_should_update_the_requested_section
336
    replacement = "New text"
337
    
338
    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"),
339
      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement, Digest::MD5.hexdigest(STR_WITHOUT_PRE[1]))
340
  end
341
  
342
  def test_update_section_with_wrong_hash_should_raise_an_error
343
    assert_raise Redmine::WikiFormatting::StaleSectionError do
344
      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, "New text", Digest::MD5.hexdigest("Old text"))
345
    end
346
  end
347

  
348
  STR_WITH_PRE = [
349
  # 0
350
"h1. Title
351

  
352
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
353
  # 1
354
"h2. Heading 2
355

  
356
<pre><code class=\"ruby\">
357
  def foo
358
  end
359
</code></pre>
360

  
361
<pre><code><pre><code class=\"ruby\">
362
  Place your code here.
363
</code></pre>
364
</code></pre>
365

  
366
Morbi facilisis accumsan orci non pharetra.
367

  
368
<pre>
369
Pre Content:
370

  
371
h2. Inside pre
372

  
373
<tag> inside pre block
374

  
375
Morbi facilisis accumsan orci non pharetra.
376
</pre>",
377
  # 2
378
"h3. Heading 3
379

  
380
Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
381

  
382
  def test_get_section_should_ignore_pre_content
383
    text = STR_WITH_PRE.join("\n\n")
384

  
385
    assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2
386
    assert_section_with_hash STR_WITH_PRE[2], text, 3
387
  end
388

  
389
  def test_update_section_should_not_escape_pre_content_outside_section
390
    text = STR_WITH_PRE.join("\n\n")
391
    replacement = "New text"
392
    
393
    assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"),
394
      @formatter.new(text).update_section(3, replacement)
395
  end
396

  
397
  def test_get_section_should_support_lines_with_spaces_before_heading
398
    # the lines after Content 2 and Heading 4 contain a space
399
    text = <<-STR
400
h1. Heading 1
401

  
402
Content 1
403

  
404
h1. Heading 2
405

  
406
Content 2
407
 
408
h1. Heading 3
409

  
410
Content 3
411

  
412
h1. Heading 4
413
 
414
Content 4
415
STR
416

  
417
    [1, 2, 3, 4].each do |index|
418
      assert_match /\Ah1. Heading #{index}.+Content #{index}/m, @formatter.new(text).get_section(index).first
419
    end
420
  end
421

  
422
  private
423

  
424
  def assert_html_output(to_test, expect_paragraph = true)
425
    to_test.each do |text, expected|
426
      assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n")
427
    end
428
  end
429

  
430
  def to_html(text)
431
    @formatter.new(text).to_html
432
  end
433
  
434
  def assert_section_with_hash(expected, text, index)
435
    result = @formatter.new(text).get_section(index)
436
    
437
    assert_kind_of Array, result
438
    assert_equal 2, result.size
439
    assert_equal expected, result.first, "section content did not match"
440
    assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match"
441
  end
442
end
.svn/pristine/6e/6edddd93286b4a8ad759793418d47dea3b07191a.svn-base
1
<h2><%=l(:button_change_password)%></h2>
2

  
3
<%= error_messages_for 'user' %>
4

  
5
<%= form_tag({}, :class => "tabular") do %>
6
<div class="box">
7
<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
8
<%= password_field_tag 'password', nil, :size => 25 %></p>
9

  
10
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
11
<%= password_field_tag 'new_password', nil, :size => 25 %>
12
<em class="info"><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
13

  
14
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
15
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
16
</div>
17
<%= submit_tag l(:button_apply) %>
18
<% end %>
19

  
20
<% content_for :sidebar do %>
21
<%= render :partial => 'sidebar' %>
22
<% end %>

Also available in: Unified diff