PoParser 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4001750c5298956f310f421c8f9cfe8d8c64283c
4
- data.tar.gz: bff6cd76882df6d406cc2f993a010a48b41320b9
3
+ metadata.gz: 32f20604e8c93db11ec6985ba1080532234efb33
4
+ data.tar.gz: 43ffda461e75249098e7e4b3fd2fc5cbe8918359
5
5
  SHA512:
6
- metadata.gz: a67f9b02929802776b34717d0f4d3f3144bf500a9df17a4f9811f43446f15b64f964ccb0736486e44c73bc22760a3687a98fe0414c92e70843ef5247b7b8821e
7
- data.tar.gz: 2ffcdb67d60a39d43d49f55222e1dbae130a852522105a1452adebe57285332c68741ac60aefa8c5fbcedeed61a34cc66c183b7bace7588f62993296a7182db4
6
+ metadata.gz: e038dce601f0c92ce204a5bfb79f3298c6f1d048447515a373d9fb4fce007a548b1701b4d9f45ab9303f8f2f4d953772baa55baa2eabfa99c2f280bafee1d9c1
7
+ data.tar.gz: 02c28740f60996c1b1b3d1989a99f14cf97e50bf93aac8ff22df3691c3c43ee40ae1aa3ad408461d2704ef752ed93fe135b3bcfb0e634be3e364674ef74672fa
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ 3.0.0 / 2017-03-03
2
+ ==================
3
+ * replaced parslet with simple_po_parser. Speedup parsing by up to 500x.
4
+ Courtesy of @dfherr
1
5
 
2
6
  2.0.1 / 2016-12-29
3
7
  ==================
data/Gemfile CHANGED
@@ -2,14 +2,17 @@ source 'https://rubygems.org'
2
2
 
3
3
  group :test do
4
4
  gem 'coveralls', :require => false
5
- gem 'pry-byebug', :platforms => :mri
6
5
  gem 'rspec', '~> 3.5.0'
7
6
  gem 'awesome_print'
8
7
  end
9
8
 
10
9
  group :development do
11
- gem 'pry-byebug', :platforms => :mri
12
10
  gem 'guard-rspec'
11
+ gem 'ruby-prof'
12
+ end
13
+
14
+ group :test, :development do
15
+ gem 'pry-byebug', :platforms => :mri
13
16
  end
14
17
 
15
18
  # Specify your gem's dependencies in poparser.gemspec
data/README.md CHANGED
@@ -103,7 +103,9 @@ translator_comment
103
103
  reference
104
104
  extracted_comment
105
105
  flag
106
- previous_untraslated_string
106
+ previous_msgctxt
107
+ previous_msgid
108
+ previous_msgid_plural
107
109
  cached # obsolete entries
108
110
  msgid
109
111
  msgid_plural
@@ -140,6 +142,16 @@ entry.msgstr.to_s
140
142
  #=> "This entry is translated"
141
143
  ```
142
144
 
145
+ But be careful with plural messages, there msgstr is an array
146
+ ```ruby
147
+ if entry.plural?
148
+ entry.msgstr.each do |msgstr|
149
+ msgstr.to_s
150
+ #=> This is one of the plural translations
151
+ end
152
+ end
153
+ ```
154
+
143
155
  You can mark an entry as fuzzy:
144
156
 
145
157
  ```ruby
@@ -220,6 +232,16 @@ You can get and set following variables from `header`:
220
232
  * Update header after changing/saving po
221
233
  * add `before_save` and `after_save` callbacks
222
234
 
235
+ ##Authors
236
+
237
+ [Arash Mousavi](https://github.com/arashm)
238
+
239
+ ### [Contributors](https://github.com/arashm/PoParser/contributors)
240
+ - [Dennis-Florian Herr](https://github.com/dfherr)
241
+ - [Roland Gropmair](https://github.com/roland9)
242
+
243
+ License: [MIT](https://github.com/arashm/PoParser/blob/master/LICENSE.txt)
244
+
223
245
  ## Contributing
224
246
 
225
247
  1. Fork it ( http://github.com/arashm/poparser/fork )
data/Rakefile CHANGED
@@ -1 +1,65 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
9
+
10
+ desc "Generate a random po file. Takes optional rake args for number of entries"
11
+ task 'generate_random_pofile', :messages, :obsoletes do |t, args|
12
+ args.with_defaults(:messages => "200", :obsoletes => "10")
13
+ require_relative 'spec/utils/random_pofile_generator'
14
+ PoParser::RandomPoFileGenerator.generate_file(
15
+ File.expand_path("test/benchmark.po", __dir__), args[:messages].to_i, args[:obsoletes].to_i
16
+ )
17
+ end
18
+
19
+ namespace :debug do
20
+ require 'benchmark'
21
+ require_relative 'lib/poparser'
22
+
23
+ desc "Benchmark of 10 full PoParser runs of test/benchmark.po"
24
+ task "benchmark" do
25
+ pofile = File.expand_path("test/benchmark.po", __dir__)
26
+ Benchmark.bmbm do |x|
27
+ x.report("Parser:") {10.times { PoParser.new.parse(pofile) }}
28
+ end
29
+ end
30
+
31
+ desc "Generate 5 random PO files with 100 to 500 messages and benchmark each full PoParser run"
32
+ task 'five_random_po_full' do
33
+ include Benchmark
34
+ require_relative 'spec/utils/random_pofile_generator'
35
+ pofile = File.expand_path("test/benchmark.po.tmp", __dir__)
36
+ Benchmark.benchmark(CAPTION, 6, FORMAT, "total:") do |x|
37
+ total = nil
38
+ total_length = 0
39
+ for i in 0..5 do
40
+ length = (Random.new.rand * 400.0 + 100).to_i
41
+ total_length += length
42
+ puts "Benchmarking file of length #{length}"
43
+ SimplePoParser::RandomPoFileGenerator.generate_file(pofile, length)
44
+ t = x.report("try#{i}:") {PoParser.new.parse(pofile)}
45
+ File.unlink(pofile)
46
+ total = total ? total+t : t
47
+ end
48
+ puts "Total message length #{total_length}"
49
+ [total]
50
+ end
51
+ end
52
+
53
+ desc "Show ruby-prof profiler for spec/fixtures/complex_entry.po"
54
+ task "profile_parser" do
55
+ require 'ruby-prof'
56
+ RubyProf.start
57
+ po_message = File.read(File.expand_path("spec/simple_po_parser/fixtures/complex_entry.po", __dir__))
58
+ PoParser.new.parse(po_message)
59
+ result = RubyProf.stop
60
+
61
+ printer = RubyProf::FlatPrinter.new(result)
62
+ printer.print(STDOUT)
63
+ end
64
+
65
+ end
@@ -10,23 +10,50 @@ module PoParser
10
10
  def to_s(with_label = false)
11
11
  return to_str unless with_label
12
12
  if @value.is_a? Array
13
- string = []
14
- @value.each do |str|
15
- string << "#{COMMENTS_LABELS[@type]} #{str}\n".gsub(/[^\S\n]+$/, '')
13
+ if @type.to_s =~ /^previous_/ # these behave more like messages
14
+ remove_empty_line
15
+ string = ["#{COMMENTS_LABELS[@type]} \"\"\n"]
16
+ @value.each do |str|
17
+ string << "#| \"#{str}\"\n".gsub(/[\p{Blank}]+$/, '')
18
+ end
19
+ else
20
+ string = []
21
+ @value.each do |str|
22
+ string << "#{COMMENTS_LABELS[@type]} #{str}\n".gsub(/[\p{Blank}]+$/, '')
23
+ end
16
24
  end
17
25
  return string.join
18
26
  else
19
- # removes the space but not newline at the end
20
- "#{COMMENTS_LABELS[@type]} #{@value}\n".gsub(/[^\S\n]+$/, '')
27
+ if @type.to_s =~ /^previous_/ # these behave more like messages
28
+ "#{COMMENTS_LABELS[@type]} \"#{@value}\"\n".gsub(/[\p{Blank}]+$/, '')
29
+ else
30
+ # removes the space but not newline at the end
31
+ "#{COMMENTS_LABELS[@type]} #{@value}\n".gsub(/[\p{Blank}]+$/, '')
32
+ end
21
33
  end
22
34
  end
23
35
 
24
36
  def to_str
25
- @value.is_a?(Array) ? @value.join : @value
37
+ if @value.is_a?(Array)
38
+ if @type.to_s =~ /^previous_/ # these behave more like messages
39
+ @value.join
40
+ else
41
+ @value.join("\n")
42
+ end
43
+ else
44
+ @value
45
+ end
26
46
  end
27
47
 
28
48
  def inspect
29
49
  @value
30
50
  end
51
+
52
+ private
53
+ def remove_empty_line
54
+ if @value.is_a? Array
55
+ @value.shift if @value.first == ''
56
+ end
57
+ end
31
58
  end
32
59
  end
@@ -4,8 +4,10 @@ module PoParser
4
4
  :extracted_comment => '#.',
5
5
  :reference => '#:',
6
6
  :flag => '#,',
7
- :previous_untraslated_string => '#|',
8
- :cached => '#~'
7
+ :previous_msgctxt => '#| msgctxt',
8
+ :previous_msgid => '#| msgid',
9
+ :previous_msgid_plural => '#| msgid_plural',
10
+ :obsolete => '#~'
9
11
  }
10
12
 
11
13
  ENTRIES_LABELS = {
@@ -18,27 +18,27 @@ module PoParser
18
18
  define_reader_methods
19
19
 
20
20
  self.class.send(:alias_method, :translate, :msgstr=)
21
- self.class.send(:alias_method, :obsolete, :cached)
22
- self.class.send(:alias_method, :obsolete=, :cached=)
21
+ self.class.send(:alias_method, :cached, :obsolete)
22
+ self.class.send(:alias_method, :cached=, :obsolete=)
23
23
  # alias for backward compatibility of this typo
24
24
  self.class.send(:alias_method, :refrence, :reference)
25
- self.class.send(:alias_method, :refrence=, :reference)
25
+ self.class.send(:alias_method, :refrence=, :reference=)
26
26
  end
27
27
 
28
- # If entry doesn't have any msgid, it's probably a cached entry that is
28
+ # If entry doesn't have any msgid, it's probably a obsolete entry that is
29
29
  # kept by the program for later use. These entries will usually start with: #~
30
30
  #
31
31
  # @return [Boolean]
32
- def cached?
33
- !@cached.nil?
32
+ def obsolete?
33
+ !@obsolete.nil?
34
34
  end
35
- alias_method :obsolete?, :cached?
35
+ alias_method :cached?, :obsolete?
36
36
 
37
37
  # Checks if the entry is untraslated
38
38
  #
39
39
  # @return [Boolean]
40
40
  def untranslated?
41
- return false if cached? || fuzzy?
41
+ return false if obsolete? || fuzzy?
42
42
  if @msgstr.is_a? Array
43
43
  return @msgstr.map {|ms| ms.str}.join.empty?
44
44
  end
@@ -50,7 +50,7 @@ module PoParser
50
50
  #
51
51
  # @return [Boolean]
52
52
  def translated?
53
- return false if cached? || fuzzy?
53
+ return false if obsolete? || fuzzy?
54
54
  not untranslated?
55
55
  end
56
56
  alias_method :complete? , :translated?
@@ -66,7 +66,7 @@ module PoParser
66
66
  #
67
67
  # @return [Boolean]
68
68
  def fuzzy?
69
- return false if cached?
69
+ return false if obsolete?
70
70
  @flag.to_s.match('fuzzy') ? true : false
71
71
  end
72
72
 
@@ -70,6 +70,26 @@ module PoParser
70
70
  string.join("\n")
71
71
  end
72
72
 
73
+ def inspect
74
+ string = []
75
+ if @comments.is_a?(Array)
76
+ @comments.each do |comment|
77
+ string << "# #{comment}".strip
78
+ end
79
+ else
80
+ string << "# #{@comments}".strip
81
+ end
82
+ string << "#, #{@flag.to_s}" if @flag
83
+ string << "msgid \"\"\nmsgstr \"\""
84
+ configs.each do |k, v|
85
+ if v.nil? || v.empty?
86
+ next
87
+ end
88
+ string << "#{k}: #{v}\n".dump
89
+ end
90
+ string.join("\n")
91
+ end
92
+
73
93
  private
74
94
  def convert_msgstr_to_hash(msgstr)
75
95
  options_array = msgstr.value.map do |options|
data/lib/poparser/po.rb CHANGED
@@ -38,14 +38,14 @@ module PoParser
38
38
 
39
39
  # Returns an array of all entries in po file
40
40
  #
41
- # @param include_cached [Boolean] Whether include cached entries or not
41
+ # @param include_obsolete [Boolean] Whether include obsolete entries or not
42
42
  # @return [Array]
43
- def entries(include_cached=false)
44
- if include_cached
43
+ def entries(include_obsolete=false)
44
+ if include_obsolete
45
45
  @entries
46
46
  else
47
47
  find_all do |entry|
48
- !entry.cached?
48
+ !entry.obsolete?
49
49
  end
50
50
  end
51
51
  end
@@ -78,17 +78,17 @@ module PoParser
78
78
  end
79
79
  end
80
80
 
81
- # Finds all cached entries
81
+ # Finds all obsolete entries
82
82
  #
83
- # @return [Array] an array of cached entries
84
- def cached
83
+ # @return [Array] an array of obsolete entries
84
+ def obsolete
85
85
  find_all do |entry|
86
- entry.cached?
86
+ entry.obsolete?
87
87
  end
88
88
  end
89
- alias_method :obsolete, :cached
89
+ alias_method :obsolete, :obsolete
90
90
 
91
- # Count of all entries without counting cached entries
91
+ # Count of all entries without counting obsolete entries
92
92
  #
93
93
  # @return [String]
94
94
  def size
@@ -2,33 +2,21 @@ module PoParser
2
2
  # Feed each block of PO file to Parser.
3
3
  class Tokenizer
4
4
  def initialize
5
- @parser = Parser.new
6
- @po = Po.new
5
+ @po = Po.new
7
6
  end
8
7
 
9
8
  def extract_entries(path)
10
9
  @po.path = path
11
- block = ''
12
- File.open(path, 'r') do |f|
13
- f.each_line do |line|
14
- if line.match(/^\n$/)
15
- @po << parse_block(block) if block != ''
16
- block = ''
17
- elsif f.eof?
18
- block += line
19
- @po << parse_block(block)
20
- else
21
- block += line
22
- end
23
- end
10
+ File.open(path, 'r').each_line("\n\n") do |block|
11
+ block.strip!
12
+ @po << parse_block(block) if block != ''
24
13
  end
25
14
  @po
26
15
  end
27
16
 
28
17
  private
29
18
  def parse_block(block)
30
- parsed_hash = @parser.parse(block)
31
- Transformer.new.transform(parsed_hash)
19
+ hash = SimplePoParser.parse_message(block)
32
20
  end
33
21
  end
34
22
  end
@@ -1,3 +1,3 @@
1
1
  module PoParser
2
- VERSION = "2.0.1"
2
+ VERSION = "3.0.0"
3
3
  end
data/lib/poparser.rb CHANGED
@@ -1,17 +1,15 @@
1
1
  # External Libs
2
- require 'parslet'
2
+ require 'simple_po_parser'
3
3
 
4
4
  # Local files
5
- require 'poparser/constants'
6
- require 'poparser/parser'
7
- require 'poparser/transformer'
8
- require 'poparser/tokenizer'
9
- require 'poparser/comment'
10
- require 'poparser/message'
11
- require 'poparser/header'
12
- require 'poparser/entry'
13
- require 'poparser/po'
14
- require 'poparser/version'
5
+ require_relative 'poparser/constants'
6
+ require_relative 'poparser/tokenizer'
7
+ require_relative 'poparser/comment'
8
+ require_relative 'poparser/message'
9
+ require_relative 'poparser/header'
10
+ require_relative 'poparser/entry'
11
+ require_relative 'poparser/po'
12
+ require_relative 'poparser/version'
15
13
 
16
14
  module PoParser
17
15
  class << self
data/poparser.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  # Runtime deps
22
- spec.add_runtime_dependency "parslet", "~> 1.7"
22
+ spec.add_runtime_dependency "simple_po_parser", "~> 1.1"
23
23
 
24
24
  # Development deps
25
25
  spec.add_development_dependency "bundler", ">= 0"
@@ -10,7 +10,9 @@ describe PoParser::Comment do
10
10
 
11
11
  it 'converts array of same comment to string' do
12
12
  comment = PoParser::Comment.new(:translator_comment, ["this is a line", "this is another line"])
13
- result = "# this is a line\n# this is another line\n"
14
- expect(comment.to_s(true)).to eq(result)
13
+ result = "this is a line\nthis is another line"
14
+ result_with_label = "# this is a line\n# this is another line\n"
15
+ expect(comment.to_s).to eq(result)
16
+ expect(comment.to_s(true)).to eq(result_with_label)
15
17
  end
16
18
  end
@@ -8,8 +8,7 @@ describe PoParser::Entry do
8
8
  end
9
9
 
10
10
  let(:labels) do
11
- [:reference, :refrence, :extracted_comment, :flag, :previous_untraslated_string,
12
- :translator_comment, :msgid, :msgid_plural, :msgstr, :msgctxt]
11
+ PoParser::LABELS + [:refrence] # backward typos
13
12
  end
14
13
 
15
14
  it 'should respond to labels' do
@@ -90,16 +89,34 @@ describe PoParser::Entry do
90
89
  end
91
90
  end
92
91
 
93
- context 'Cached' do
92
+ context 'Previous' do
93
+ it 'should be able to show content of previous_msgid' do
94
+ @entry.previous_msgid = 'Hello'
95
+ result = "Hello"
96
+ result_with_label = "#| msgid \"Hello\"\n"
97
+ expect(@entry.previous_msgid.to_s).to eq result
98
+ expect(@entry.previous_msgid.to_s(true)).to eq result_with_label
99
+ end
100
+
101
+ it 'convert multiline entries to string' do
102
+ @entry.previous_msgid = ['first line\n', 'second line']
103
+ result = "first line\\nsecond line"
104
+ result_with_label = "#| msgid \"\"\n#| \"first line\\n\"\n#| \"second line\"\n"
105
+ expect(@entry.previous_msgid.to_s).to eq result
106
+ expect(@entry.previous_msgid.to_s(true)).to eq result_with_label
107
+ end
108
+ end
109
+
110
+ context 'obsolete' do
94
111
  before do
95
112
  @entry = PoParser::Entry.new
96
- @entry.cached = '#~ msgid "a cached entry"'
113
+ @entry.obsolete = '#~ msgid "a obsolete entry"'
97
114
  @entry.flag = 'Fuzzy'
98
115
  end
99
116
 
100
- it 'checks for chached entries' do
101
- expect(@entry.cached?).to be_truthy
117
+ it 'checks for obsolete entries' do
102
118
  expect(@entry.obsolete?).to be_truthy
119
+ expect(@entry.cached?).to be_truthy
103
120
  end
104
121
 
105
122
  it 'shouldn be counted as untranslated' do
@@ -39,11 +39,11 @@ describe PoParser::Po do
39
39
  expect(@po.untranslated.size).to eq 2
40
40
  end
41
41
 
42
- it 'returns all cached strings' do
42
+ it 'returns all obsolete strings' do
43
43
  entry2, entry3 = entry.dup, entry.dup
44
- [entry2, entry3].each { |en| en[:cached] = 'test' }
44
+ [entry2, entry3].each { |en| en[:obsolete] = 'test' }
45
45
  @po << [entry, entry2, entry3]
46
- expect(@po.cached.size).to eq 2
46
+ expect(@po.obsolete.size).to eq 2
47
47
  end
48
48
 
49
49
  it 'shows stats' do
@@ -58,10 +58,10 @@ describe PoParser::Po do
58
58
  expect(result[:fuzzy]).to eq 25
59
59
  end
60
60
 
61
- it 'shouldn\'t count cached entries' do
61
+ it 'shouldn\'t count obsolete entries' do
62
62
  @po << entry
63
- cached = { cached: 'sth', flag: 'Fuzzy' }
64
- @po << cached
63
+ obsolete = { obsolete: 'sth', flag: 'Fuzzy' }
64
+ @po << obsolete
65
65
  expect(@po.size).to eq(1)
66
66
  end
67
67
 
@@ -3,8 +3,134 @@ require "spec_helper"
3
3
 
4
4
  describe PoParser do
5
5
  let(:po_file) { Pathname.new('spec/poparser/fixtures/tokenizer.po').realpath }
6
+ let(:header_fixture) { Pathname.new('spec/poparser/fixtures/header.po').realpath }
7
+ let(:multiline_fixture) { Pathname.new('spec/poparser/fixtures/multiline.po').realpath }
8
+ let(:plural_fixture) { Pathname.new('spec/poparser/fixtures/plural.po').realpath }
9
+ let(:test_fixture) { Pathname.new('spec/poparser/fixtures/test.po').realpath }
6
10
 
7
11
  it 'parses a file' do
8
12
  expect(PoParser.parse(po_file)).to be_a_kind_of PoParser::Po
9
13
  end
14
+
15
+ it 'correclty parses header fixture' do
16
+ entry = PoParser::Entry.new(
17
+ {
18
+ :translator_comment => [
19
+ "Arash Mousavi <mousavi.arash@gmail.com>, 2014.",
20
+ ""],
21
+ :flag => "fuzzy",
22
+ :msgid => "",
23
+ :msgstr => [
24
+ "",
25
+ "Project-Id-Version: damned-lies master\\n",
26
+ "Report-Msgid-Bugs-To: \\n"]
27
+ })
28
+ expected_result = PoParser::Header.new(entry)
29
+ expect(PoParser.parse(header_fixture).header.inspect).to eql(expected_result.inspect)
30
+ end
31
+
32
+ it 'correclty parses multiline fixture' do
33
+ expected_result = PoParser::Entry.new(
34
+ {
35
+ :msgid => [
36
+ "",
37
+ "first",
38
+ "second"],
39
+ :msgstr => [
40
+ "",
41
+ "aval",
42
+ "dovom"]
43
+ })
44
+ expect(PoParser.parse(multiline_fixture).entries[0].inspect).to eq(expected_result.inspect)
45
+ end
46
+
47
+ it 'correclty parses plural fixture' do
48
+ expected_result = PoParser::Entry.new(
49
+ {
50
+ :msgid => " including <a href=\\\"%(img_url)s\\\">%(stats)s image</a>",
51
+ :msgid_plural => " including <a href=\\\"%(img_url)s\\\">%(stats)s images</a>",
52
+ "msgstr[0]" => [
53
+ "",
54
+ "sad ads fdsaf ds fdfs dsa "
55
+ ],
56
+ "msgstr[1]" => [
57
+ "",
58
+ "sad ads fdsaf ds fdfs dsa "
59
+ ]
60
+ })
61
+ expect(PoParser.parse(plural_fixture).entries[0].inspect).to eq(expected_result.inspect)
62
+ end
63
+
64
+ it 'correclty parses test fixture' do
65
+ expected_result = PoParser::Po.new
66
+ expected_result << { :translator_comment => [
67
+ "Persian translation for damned-lies.",
68
+ "Copyright (C) 2012 damned-lies's COPYRIGHT HOLDER",
69
+ "This file is distributed under the same license as the damned-lies package.",
70
+ "Arash Mousavi <mousavi.arash@gmail.com>, 2014.",
71
+ ""
72
+ ],
73
+ :msgid => "",
74
+ :msgstr => [
75
+ "",
76
+ "Project-Id-Version: damned-lies master\\n",
77
+ "Report-Msgid-Bugs-To: \\n",
78
+ "POT-Creation-Date: 2012-05-04 12:56+0000\\n",
79
+ "PO-Revision-Date: 2014-05-15 22:24+0330\\n",
80
+ "Last-Translator: Arash Mousavi <mousavi.arash@gmail.com>\\n",
81
+ "Language-Team: Persian <fa@li.org>\\n",
82
+ "MIME-Version: 1.0\\n",
83
+ "Content-Type: text/plain; charset=UTF-8\\n",
84
+ "Content-Transfer-Encoding: 8bit\\n",
85
+ "Plural-Forms: nplurals=1; plural=0;\\n",
86
+ "X-Generator: Poedit 1.6.4\\n"
87
+ ]
88
+ }
89
+ expected_result << {
90
+ :reference => "database-content.py:1 database-content.py:129 settings.py:52",
91
+ :msgid => "Afrikaans",
92
+ :msgstr => "آفریقایی"
93
+ }
94
+ expected_result << { :reference => "templates/vertimus/vertimus_detail.html:105",
95
+ :flag => "python-format",
96
+ :msgid => " including <a href=\\\"%(img_url)s\\\">%(stats)s image</a>",
97
+ :msgid_plural => " including <a href=\\\"%(img_url)s\\\">%(stats)s images</a>",
98
+ "msgstr[0]" => "",
99
+ "msgstr[1]" => ""
100
+ }
101
+ expected_result << {
102
+ :reference => "templates/vertimus/vertimus_detail.html:136 vertimus/forms.py:79",
103
+ :msgid => "Invalid action. Someone probably posted another action just before you.",
104
+ :msgstr => [
105
+ "",
106
+ "فعالیت نامعتبر. شاید یک نفر دیگر دقیقا قبل از شما یک فعالیت دیگر ارسال کرده ",
107
+ "است."
108
+ ]
109
+ }
110
+ expected_result << { :reference => "vertimus/models.py:470",
111
+ :flag => "python-format",
112
+ :previous_msgid => [
113
+ "",
114
+ "Hello,\\n",
115
+ "\\n",
116
+ "The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is ",
117
+ "now '%(new_state)s'.\\n",
118
+ "%(url)s\\n",
119
+ "\\n"
120
+ ],
121
+ :msgid => [
122
+ "",
123
+ "The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now ",
124
+ "'%(new_state)s'."
125
+ ],
126
+ :msgstr => [
127
+ "",
128
+ "وضعیت جدید %(module)s - %(branch)s - %(domain)s (%(language)s) هم‌اکنون ",
129
+ "«%(new_state)s» است."
130
+ ]
131
+ }
132
+ allow_any_instance_of(PoParser::Header).to receive(:puts)
133
+ expect(PoParser.parse(test_fixture).to_s).to eq(expected_result.to_s)
134
+ end
135
+
10
136
  end