Revision 1298:4f746d8966dd .svn/pristine/0f

View differences:

.svn/pristine/0f/0f05e49d9c9481ce6698da320e7a0f815ec9a184.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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
  def test_get_section_should_support_headings_starting_with_a_tab
423
    text = <<-STR
424
h1.\tHeading 1
425

  
426
Content 1
427

  
428
h1. Heading 2
429

  
430
Content 2
431
STR
432

  
433
    assert_match /\Ah1.\tHeading 1\s+Content 1\z/, @formatter.new(text).get_section(1).first
434
  end
435

  
436
  private
437

  
438
  def assert_html_output(to_test, expect_paragraph = true)
439
    to_test.each do |text, expected|
440
      assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n")
441
    end
442
  end
443

  
444
  def to_html(text)
445
    @formatter.new(text).to_html
446
  end
447
  
448
  def assert_section_with_hash(expected, text, index)
449
    result = @formatter.new(text).get_section(index)
450
    
451
    assert_kind_of Array, result
452
    assert_equal 2, result.size
453
    assert_equal expected, result.first, "section content did not match"
454
    assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match"
455
  end
456
end
.svn/pristine/0f/0f55ca10803bce4cf5a650e17d0e04f01a9b964d.svn-base
1
<div class="splitcontentleft">
2
<% if @group.users.any? %>
3
  <table class="list users">
4
    <thead><tr>
5
      <th><%= l(:label_user) %></th>
6
      <th style="width:15%"></th>
7
    </tr></thead>
8
    <tbody>
9
    <% @group.users.sort.each do |user| %>
10
      <tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
11
        <td class="user"><%= link_to_user user %></td>
12
        <td class="buttons">
13
            <%= link_to_remote l(:button_delete), { :url => group_user_path(@group, :user_id => user), :method => :delete }, :class => 'icon icon-del' %>
14
        </td>
15
      </tr>
16
    <% end %>
17
    </tbody>
18
  </table>
19
<% else %>
20
  <p class="nodata"><%= l(:label_no_data) %></p>
21
<% end %>
22
</div>
23

  
24
<div class="splitcontentright">
25
<% users = User.active.not_in_group(@group).all(:limit => 100) %>
26
<% if users.any? %>
27
  <% remote_form_for(@group, :url => group_users_path(@group), :html => {:method => :post}) do |f| %>
28
    <fieldset><legend><%=l(:label_user_new)%></legend>
29

  
30
    <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
31
    <%= observe_field(:user_search,
32
                 :frequency => 0.5,
33
                 :update => :users,
34
                 :url => autocomplete_for_user_group_path(@group),
35
                 :method => :get,
36
                 :with => 'q')
37
                  %>
38

  
39
    <div id="users">
40
      <%= principals_check_box_tags 'user_ids[]', users %>
41
    </div>
42

  
43
    <p><%= submit_tag l(:button_add) %></p>
44
    </fieldset>
45
  <% end %>
46
<% end %>
47

  
48
</div>
.svn/pristine/0f/0f5d0b28aa88dc0b634f0aed6c20653f95af7206.svn-base
1
module CodeRay
2
  
3
  # = FileType
4
  #
5
  # A simple filetype recognizer.
6
  #
7
  # == Usage
8
  #
9
  #  # determine the type of the given
10
  #  lang = FileType[file_name]
11
  #  
12
  #  # return :text if the file type is unknown
13
  #  lang = FileType.fetch file_name, :text
14
  #  
15
  #  # try the shebang line, too
16
  #  lang = FileType.fetch file_name, :text, true
17
  module FileType
18
    
19
    UnknownFileType = Class.new Exception
20
    
21
    class << self
22
      
23
      # Try to determine the file type of the file.
24
      #
25
      # +filename+ is a relative or absolute path to a file.
26
      #
27
      # The file itself is only accessed when +read_shebang+ is set to true.
28
      # That means you can get filetypes from files that don't exist.
29
      def [] filename, read_shebang = false
30
        name = File.basename filename
31
        ext = File.extname(name).sub(/^\./, '')  # from last dot, delete the leading dot
32
        ext2 = filename.to_s[/\.(.*)/, 1]  # from first dot
33
        
34
        type =
35
          TypeFromExt[ext] ||
36
          TypeFromExt[ext.downcase] ||
37
          (TypeFromExt[ext2] if ext2) ||
38
          (TypeFromExt[ext2.downcase] if ext2) ||
39
          TypeFromName[name] ||
40
          TypeFromName[name.downcase]
41
        type ||= shebang(filename) if read_shebang
42
        
43
        type
44
      end
45
      
46
      # This works like Hash#fetch.
47
      #
48
      # If the filetype cannot be found, the +default+ value
49
      # is returned.
50
      def fetch filename, default = nil, read_shebang = false
51
        if default && block_given?
52
          warn 'Block supersedes default value argument; use either.'
53
        end
54
        
55
        if type = self[filename, read_shebang]
56
          type
57
        else
58
          return yield if block_given?
59
          return default if default
60
          raise UnknownFileType, 'Could not determine type of %p.' % filename
61
        end
62
      end
63
      
64
    protected
65
      
66
      def shebang filename
67
        return unless File.exist? filename
68
        File.open filename, 'r' do |f|
69
          if first_line = f.gets
70
            if type = first_line[TypeFromShebang]
71
              type.to_sym
72
            end
73
          end
74
        end
75
      end
76
      
77
    end
78
    
79
    TypeFromExt = {
80
      'c'        => :c,
81
      'cfc'      => :xml,
82
      'cfm'      => :xml,
83
      'clj'      => :clojure,
84
      'css'      => :css,
85
      'diff'     => :diff,
86
      'dpr'      => :delphi,
87
      'gemspec'  => :ruby,
88
      'groovy'   => :groovy,
89
      'gvy'      => :groovy,
90
      'h'        => :c,
91
      'haml'     => :haml,
92
      'htm'      => :page,
93
      'html'     => :page,
94
      'html.erb' => :erb,
95
      'java'     => :java,
96
      'js'       => :java_script,
97
      'json'     => :json,
98
      'mab'      => :ruby,
99
      'pas'      => :delphi,
100
      'patch'    => :diff,
101
      'php'      => :php,
102
      'php3'     => :php,
103
      'php4'     => :php,
104
      'php5'     => :php,
105
      'prawn'    => :ruby,
106
      'py'       => :python,
107
      'py3'      => :python,
108
      'pyw'      => :python,
109
      'rake'     => :ruby,
110
      'raydebug' => :raydebug,
111
      'rb'       => :ruby,
112
      'rbw'      => :ruby,
113
      'rhtml'    => :erb,
114
      'rjs'      => :ruby,
115
      'rpdf'     => :ruby,
116
      'ru'       => :ruby,
117
      'rxml'     => :ruby,
118
      # 'sch'      => :scheme,
119
      'sql'      => :sql,
120
      # 'ss'       => :scheme,
121
      'xhtml'    => :page,
122
      'xml'      => :xml,
123
      'yaml'     => :yaml,
124
      'yml'      => :yaml,
125
    }
126
    for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu]
127
      TypeFromExt[cpp_alias] = :cpp
128
    end
129
    
130
    TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/
131
    
132
    TypeFromName = {
133
      'Capfile'  => :ruby,
134
      'Rakefile' => :ruby,
135
      'Rantfile' => :ruby,
136
      'Gemfile'  => :ruby,
137
    }
138
    
139
  end
140
  
141
end
.svn/pristine/0f/0f6a1a5f91b1625dba02a90214d3f1e2572096f8.svn-base
1
--- a.txt	2013-04-05 14:19:39.000000000 +0900
2
+++ b.txt	2013-04-05 14:19:51.000000000 +0900
3
@@ -1,3 +1,3 @@
4
 aaaa
5
-日本
6
+日本語
7
 bbbb
.svn/pristine/0f/0f78241a73ec8550e8a5f3850c895c44e2ed8e56.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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 'net/imap'
19

  
20
module Redmine
21
  module IMAP
22
    class << self
23
      def check(imap_options={}, options={})
24
        host = imap_options[:host] || '127.0.0.1'
25
        port = imap_options[:port] || '143'
26
        ssl = !imap_options[:ssl].nil?
27
        folder = imap_options[:folder] || 'INBOX'
28

  
29
        imap = Net::IMAP.new(host, port, ssl)
30
        imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil?
31
        imap.select(folder)
32
        imap.search(['NOT', 'SEEN']).each do |message_id|
33
          msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
34
          logger.debug "Receiving message #{message_id}" if logger && logger.debug?
35
          if MailHandler.receive(msg, options)
36
            logger.debug "Message #{message_id} successfully received" if logger && logger.debug?
37
            if imap_options[:move_on_success]
38
              imap.copy(message_id, imap_options[:move_on_success])
39
            end
40
            imap.store(message_id, "+FLAGS", [:Seen, :Deleted])
41
          else
42
            logger.debug "Message #{message_id} can not be processed" if logger && logger.debug?
43
            imap.store(message_id, "+FLAGS", [:Seen])
44
            if imap_options[:move_on_failure]
45
              imap.copy(message_id, imap_options[:move_on_failure])
46
              imap.store(message_id, "+FLAGS", [:Deleted])
47
            end
48
          end
49
        end
50
        imap.expunge
51
      end
52

  
53
      private
54

  
55
      def logger
56
        ::Rails.logger
57
      end
58
    end
59
  end
60
end
.svn/pristine/0f/0f842304e58a7a419abba90bd185840b383c9907.svn-base
1
module Engines
2
  class Plugin
3
    class FileSystemLocator < Rails::Plugin::FileSystemLocator
4
      def create_plugin(path)
5
        plugin = Engines::Plugin.new(path)
6
        plugin.valid? ? plugin : nil
7
      end        
8
    end
9
  end
10
end
11

  
.svn/pristine/0f/0fa8b994f508f388585e802196325aae4a4107f7.svn-base
1
<%= error_messages_for 'user' %>
2

  
3
<div id="user_form">
4
<!--[form:user]-->
5
<div class="splitcontentleft">
6
<fieldset class="box tabular">
7
  <legend><%=l(:label_information_plural)%></legend>
8
  <p><%= f.text_field :login, :required => true, :size => 25  %></p>
9
  <p><%= f.text_field :firstname, :required => true %></p>
10
  <p><%= f.text_field :lastname, :required => true %></p>
11
  <p><%= f.text_field :mail, :required => true %></p>
12
  <p><%= f.select :language, lang_options_for_select %></p>
13
  <% if Setting.openid? %>
14
  <p><%= f.text_field :identity_url  %></p>
15
  <% end %>
16

  
17
  <% @user.custom_field_values.each do |value| %>
18
    <p><%= custom_field_tag_with_label :user, value %></p>
19
  <% end %>
20

  
21
  <p><%= f.check_box :admin, :disabled => (@user == User.current) %></p>
22
  <%= call_hook(:view_users_form, :user => @user, :form => f) %>
23
</fieldset>
24

  
25
<fieldset class="box tabular">
26
  <legend><%=l(:label_authentication)%></legend>
27
  <% unless @auth_sources.empty? %>
28
  <p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
29
  <% end %>
30
  <div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>">
31
  <p><%= f.password_field :password, :required => true, :size => 25  %><br />
32
  <em><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
33
  <p><%= f.password_field :password_confirmation, :required => true, :size => 25  %></p>
34
  </div>
35
</fieldset>
36
</div>
37

  
38
<div class="splitcontentright">
39
<fieldset class="box">
40
  <legend><%=l(:field_mail_notification)%></legend>
41
  <%= render :partial => 'users/mail_notifications' %>
42
</fieldset>
43

  
44
<fieldset class="box tabular">
45
  <legend><%=l(:label_preferences)%></legend>
46
  <%= render :partial => 'users/preferences' %>
47
</fieldset>
48
</div>
49
</div>
50
<div style="clear:left;"></div>
51
<!--[eoform:user]-->
.svn/pristine/0f/0fd45ffc205637b86a8a066d7efda723815c1464.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  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 'settings_controller'
20

  
21
# Re-raise errors caught by the controller.
22
class SettingsController; def rescue_action(e) raise e end; end
23

  
24
class SettingsControllerTest < ActionController::TestCase
25
  fixtures :users
26

  
27
  def setup
28
    @controller = SettingsController.new
29
    @request    = ActionController::TestRequest.new
30
    @response   = ActionController::TestResponse.new
31
    User.current = nil
32
    @request.session[:user_id] = 1 # admin
33
  end
34

  
35
  def test_index
36
    get :index
37
    assert_response :success
38
    assert_template 'edit'
39
  end
40

  
41
  def test_get_edit
42
    get :edit
43
    assert_response :success
44
    assert_template 'edit'
45

  
46
    assert_tag 'input', :attributes => {:name => 'settings[enabled_scm][]', :value => ''}
47
  end
48

  
49
  def test_post_edit_notifications
50
    post :edit, :settings => {:mail_from => 'functional@test.foo',
51
                              :bcc_recipients  => '0',
52
                              :notified_events => %w(issue_added issue_updated news_added),
53
                              :emails_footer => 'Test footer'
54
                              }
55
    assert_redirected_to '/settings/edit'
56
    assert_equal 'functional@test.foo', Setting.mail_from
57
    assert !Setting.bcc_recipients?
58
    assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
59
    assert_equal 'Test footer', Setting.emails_footer
60
  end
61
end
.svn/pristine/0f/0ff0bfae04ec7a8241921bdb8bb6771c6ffcd5d9.svn-base
1
api.version do
2
  api.id @version.id
3
  api.project(:id => @version.project_id, :name => @version.project.name) unless @version.project.nil?
4

  
5
  api.name        @version.name
6
  api.description @version.description
7
  api.status      @version.status
8
  api.due_date    @version.effective_date
9

  
10
  render_api_custom_values @version.custom_field_values, api
11

  
12
  api.created_on @version.created_on
13
  api.updated_on @version.updated_on
14
end

Also available in: Unified diff