puttext 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ class TestClass
2
+ _('string')
3
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'unindent'
4
+
5
+ RSpec.shared_examples 'PutText::Parser::Base' do
6
+ describe '#strings_from_file' do
7
+ let(:fixture_file_path) do
8
+ File.join(
9
+ File.dirname(__FILE__),
10
+ '../fixtures/parser_base_shared_fixture.rb'
11
+ )
12
+ end
13
+
14
+ let(:fixture_file_contents) do
15
+ <<-RUBY.unindent
16
+ class TestClass
17
+ _('string')
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ before do
23
+ allow(subject).to receive(:strings_from_source).and_return(['something'])
24
+ end
25
+
26
+ it 'passes file content to strings_from_source' do
27
+ subject.strings_from_file(fixture_file_path)
28
+
29
+ expect(subject).to have_received(:strings_from_source).with(
30
+ fixture_file_contents, filename: fixture_file_path
31
+ )
32
+ end
33
+
34
+ it 'returns the result from strings_from_source' do
35
+ expect(subject.strings_from_file(fixture_file_path)).to eq(['something'])
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+
5
+ SimpleCov.start do
6
+ add_filter '/spec/'
7
+ end
8
+
9
+ require 'puttext'
10
+
11
+ # Load shared specs.
12
+ Dir[File.join(File.dirname(__FILE__), 'shared/**/*.rb')].each { |f| require f }
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'unindent'
5
+
6
+ describe PutText::Extractor do
7
+ describe '.file_supported?(path)' do
8
+ context 'passing a file with a supported extension' do
9
+ it 'returns true' do
10
+ expect(described_class.file_supported?('test/file.rb')).to be true
11
+ end
12
+ end
13
+
14
+ context 'passing a file with an unsupported extension' do
15
+ it 'returns false' do
16
+ expect(described_class.file_supported?('test/file.php')).to be false
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '#extract_from_file' do
22
+ context 'passing a Ruby file' do
23
+ before do
24
+ allow_any_instance_of(PutText::Parser::Ruby).to(
25
+ receive(:strings_from_file).and_return(['stuff'])
26
+ )
27
+ end
28
+
29
+ it 'uses the Ruby parser to extract strings' do
30
+ expect_any_instance_of(PutText::Parser::Ruby).to(
31
+ receive(:strings_from_file).with('test/file.rb')
32
+ )
33
+
34
+ subject.extract_from_file('test/file.rb')
35
+ end
36
+
37
+ it 'returns the results of the #strings_from_file call' do
38
+ expect(subject.extract_from_file('test/file.rb')).to eq(['stuff'])
39
+ end
40
+ end
41
+
42
+ context 'passing a Slim file' do
43
+ before do
44
+ allow_any_instance_of(PutText::Parser::Slim).to(
45
+ receive(:strings_from_file).and_return(['stuff'])
46
+ )
47
+ end
48
+
49
+ it 'uses the Slim parser to extract strings' do
50
+ expect_any_instance_of(PutText::Parser::Slim).to(
51
+ receive(:strings_from_file).with('test/file.slim')
52
+ )
53
+
54
+ subject.extract_from_file('test/file.slim')
55
+ end
56
+
57
+ it 'returns the results of the #strings_from_file call' do
58
+ expect(subject.extract_from_file('test/file.slim')).to eq(['stuff'])
59
+ end
60
+ end
61
+
62
+ context 'passing an unsupported file' do
63
+ it 'throws a PutText::Extractor::UnsupportedFileError' do
64
+ expect { subject.extract_from_file('test/file.php') }.to raise_error(
65
+ PutText::Extractor::UnsupportedFileError
66
+ )
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#extract' do
72
+ let(:entry) { PutText::POEntry.new(msgid: 'test') }
73
+
74
+ context 'passing a folder as the path' do
75
+ let(:fixtures_path) do
76
+ File.join(File.dirname(__FILE__), '../fixtures/extractor_fixtures')
77
+ end
78
+
79
+ context 'files do not contain any strings' do
80
+ before do
81
+ allow(subject).to receive(:extract_from_file).and_return([])
82
+ subject.extract(fixtures_path)
83
+ end
84
+
85
+ it 'extracts strings from 4 files' do
86
+ expect(subject).to have_received(:extract_from_file).exactly(4).times
87
+ end
88
+
89
+ it 'extracts strings from file_1.rb' do
90
+ expect(subject).to have_received(:extract_from_file).with(
91
+ %r{extractor_fixtures/file_1\.rb$}
92
+ )
93
+ end
94
+
95
+ it 'extracts strings from file_2.rb' do
96
+ expect(subject).to have_received(:extract_from_file).with(
97
+ %r{extractor_fixtures/file_2\.rb$}
98
+ )
99
+ end
100
+
101
+ it 'extracts strings from subfolder/subfile_1.rb' do
102
+ expect(subject).to have_received(:extract_from_file).with(
103
+ %r{extractor_fixtures/subfolder/subfile_1\.rb$}
104
+ )
105
+ end
106
+
107
+ it 'extracts strings from subfolder/subfile_2.rb' do
108
+ expect(subject).to have_received(:extract_from_file).with(
109
+ %r{extractor_fixtures/subfolder/subfile_2\.rb$}
110
+ )
111
+ end
112
+ end
113
+
114
+ context 'files contain some strings' do
115
+ before do
116
+ allow(subject).to receive(:extract_from_file).and_return([entry])
117
+ end
118
+
119
+ it 'returns a POFile with entries extracted from the files' do
120
+ dup_entry = entry.dup
121
+
122
+ expect(subject.extract(fixtures_path)).to eq(
123
+ PutText::POFile.new([dup_entry, dup_entry, dup_entry, dup_entry])
124
+ )
125
+ end
126
+ end
127
+ end
128
+
129
+ context 'passing a folder as the path' do
130
+ let(:fixture_path) do
131
+ File.join(
132
+ File.dirname(__FILE__),
133
+ '../fixtures/extractor_fixtures/file_1.rb'
134
+ )
135
+ end
136
+
137
+ before do
138
+ allow(subject).to receive(:extract_from_file).and_return([entry])
139
+ end
140
+
141
+ it 'extracts strings from 1 file' do
142
+ subject.extract(fixture_path)
143
+ expect(subject).to have_received(:extract_from_file).once
144
+ end
145
+
146
+ it 'extracts contents from file_1.rb' do
147
+ subject.extract(fixture_path)
148
+ expect(subject).to have_received(:extract_from_file).with(
149
+ %r{extractor_fixtures/file_1\.rb$}
150
+ )
151
+ end
152
+
153
+ it 'returns a POFile with entries extracted from the file' do
154
+ expect(subject.extract(fixture_path)).to eq(
155
+ PutText::POFile.new([entry])
156
+ )
157
+ end
158
+ end
159
+
160
+ context 'passing a not existing path' do
161
+ it 'throws a PutText::Extractor::NoSuchFileError' do
162
+ expect { subject.extract('non/existing/path') }.to raise_error(
163
+ PutText::Extractor::NoSuchFileError
164
+ )
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'unindent'
5
+
6
+ describe PutText::Parser::Ruby do
7
+ it_behaves_like 'PutText::Parser::Base'
8
+
9
+ describe '#strings_from_source' do
10
+ context 'passing Ruby code with gettext usages' do
11
+ let(:ruby_code) do
12
+ <<-RUBY.unindent
13
+ class RandomClass
14
+ def array_of_text
15
+ [
16
+ gettext('gettext'),
17
+ _('underscore'),
18
+ ngettext('1 ngettext', '%d ngettexts', 5),
19
+ n_('1 underscore', '%d underscores', 5),
20
+ sgettext('context|sgettext'),
21
+ s_('context---s underscore', '---'),
22
+ nsgettext('context|1 nsgettext', '%d nsgettexts', 5),
23
+ ns_('context---1 ns underscore', '%d ns underscores', 5, '---'),
24
+ pgettext('context', 'pgettext'),
25
+ p_('context', 'p underscore'),
26
+ npgettext('context', '1 npgettext', '%d npgettexts', 5),
27
+ np_('context', '1 np underscore', '%d np underscores', 5)
28
+ ]
29
+ end
30
+
31
+ def method_with_underscore_param(_)
32
+ 'something'
33
+ end
34
+
35
+ before_event -> (_) { 'do_important_stuff' }
36
+ end
37
+ RUBY
38
+ end
39
+
40
+ before do
41
+ allow(PutText::POEntry).to receive(:new)
42
+ subject.strings_from_source(
43
+ ruby_code, filename: 'test.rb', first_line: 8
44
+ )
45
+ end
46
+
47
+ it 'extracts the correct number of strings' do
48
+ expect(PutText::POEntry).to have_received(:new).exactly(12).times
49
+ end
50
+
51
+ it 'correctly extracts string from gettext calls' do
52
+ expect(PutText::POEntry).to have_received(:new).with(
53
+ msgid: 'gettext',
54
+ references: ['test.rb:11']
55
+ )
56
+ end
57
+
58
+ it 'correctly extracts string from _ calls' do
59
+ expect(PutText::POEntry).to have_received(:new).with(
60
+ msgid: 'underscore',
61
+ references: ['test.rb:12']
62
+ )
63
+ end
64
+
65
+ it 'correctly extracts string from ngettext calls' do
66
+ expect(PutText::POEntry).to have_received(:new).with(
67
+ msgid: '1 ngettext',
68
+ msgid_plural: '%d ngettexts',
69
+ references: ['test.rb:13']
70
+ )
71
+ end
72
+
73
+ it 'correctly extracts string from n_ calls' do
74
+ expect(PutText::POEntry).to have_received(:new).with(
75
+ msgid: '1 underscore',
76
+ msgid_plural: '%d underscores',
77
+ references: ['test.rb:14']
78
+ )
79
+ end
80
+
81
+ it 'correctly extracts string from sgettext calls' do
82
+ expect(PutText::POEntry).to have_received(:new).with(
83
+ msgid: 'context|sgettext',
84
+ references: ['test.rb:15']
85
+ )
86
+ end
87
+
88
+ it 'correctly extracts string from s_ calls' do
89
+ expect(PutText::POEntry).to have_received(:new).with(
90
+ msgid: 'context---s underscore',
91
+ separator: '---',
92
+ references: ['test.rb:16']
93
+ )
94
+ end
95
+
96
+ it 'correctly extracts string from nsgettext calls' do
97
+ expect(PutText::POEntry).to have_received(:new).with(
98
+ msgid: 'context|1 nsgettext',
99
+ msgid_plural: '%d nsgettexts',
100
+ references: ['test.rb:17']
101
+ )
102
+ end
103
+
104
+ it 'correctly extracts string from ns_ calls' do
105
+ expect(PutText::POEntry).to have_received(:new).with(
106
+ msgid: 'context---1 ns underscore',
107
+ msgid_plural: '%d ns underscores',
108
+ separator: '---',
109
+ references: ['test.rb:18']
110
+ )
111
+ end
112
+
113
+ it 'correctly extracts string from pgettext calls' do
114
+ expect(PutText::POEntry).to have_received(:new).with(
115
+ msgctxt: 'context',
116
+ msgid: 'pgettext',
117
+ references: ['test.rb:19']
118
+ )
119
+ end
120
+
121
+ it 'correctly extracts string from p_ calls' do
122
+ expect(PutText::POEntry).to have_received(:new).with(
123
+ msgctxt: 'context',
124
+ msgid: 'p underscore',
125
+ references: ['test.rb:20']
126
+ )
127
+ end
128
+
129
+ it 'correctly extracts string from npgettext calls' do
130
+ expect(PutText::POEntry).to have_received(:new).with(
131
+ msgctxt: 'context',
132
+ msgid: '1 npgettext',
133
+ msgid_plural: '%d npgettexts',
134
+ references: ['test.rb:21']
135
+ )
136
+ end
137
+
138
+ it 'correctly extracts string from np_ calls' do
139
+ expect(PutText::POEntry).to have_received(:new).with(
140
+ msgctxt: 'context',
141
+ msgid: '1 np underscore',
142
+ msgid_plural: '%d np underscores',
143
+ references: ['test.rb:22']
144
+ )
145
+ end
146
+ end
147
+
148
+ context 'passing an empty string' do
149
+ it 'returns an empty array' do
150
+ expect(subject.strings_from_source('')).to eq([])
151
+ end
152
+ end
153
+
154
+ context 'passing Ruby code that uses text interpolations' do
155
+ let(:ruby_code) do
156
+ <<-RUBY.unindent
157
+ class RandomClass
158
+ def interpolations
159
+ 'stuff'
160
+ end
161
+
162
+ def do_something
163
+ _("something with \#{interpolations}")
164
+ end
165
+ end
166
+ RUBY
167
+ end
168
+
169
+ it 'throws a PutText::Parser::ParseError error' do
170
+ expect { subject.strings_from_source(ruby_code) }.to raise_error(
171
+ PutText::Parser::ParseError
172
+ )
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'unindent'
5
+
6
+ describe PutText::Parser::Slim do
7
+ it_behaves_like 'PutText::Parser::Base'
8
+
9
+ describe '#strings_from_source' do
10
+ let(:slim_template) do
11
+ <<-SLIM.unindent
12
+ html attr=code(_('attr')) attr_2="\#{_('attr interpolation')}"
13
+ = multiline_ruby\\
14
+ n_('1 multiline ruby', '%d multiline rubies', 8)
15
+
16
+ - if condition
17
+ div *{'hash_attr'=>p_('ctx','splat hash attr')}
18
+
19
+ coffee:
20
+ _('should be ignored')
21
+
22
+ = method_call do
23
+ html
24
+ | inside
25
+ | with interpolations \#{_('text interpolation')}
26
+ # and_also_ruby
27
+ == _('unescaped string')
28
+ SLIM
29
+ end
30
+
31
+ before do
32
+ allow(PutText::POEntry).to receive(:new)
33
+ subject.strings_from_source(
34
+ slim_template, filename: 'test.slim', first_line: 8
35
+ )
36
+ end
37
+
38
+ it 'extracts the correct number of strings' do
39
+ expect(PutText::POEntry).to have_received(:new).exactly(6).times
40
+ end
41
+
42
+ it 'correctly extracts string from dynamic attribute value' do
43
+ expect(PutText::POEntry).to have_received(:new).with(
44
+ msgid: 'attr',
45
+ references: ['test.slim:8']
46
+ )
47
+ end
48
+
49
+ it 'correctly extracts string from interpolated attribute value' do
50
+ expect(PutText::POEntry).to have_received(:new).with(
51
+ msgid: 'attr interpolation',
52
+ references: ['test.slim:8']
53
+ )
54
+ end
55
+
56
+ it 'correctly extracts string from embedded Ruby code' do
57
+ expect(PutText::POEntry).to have_received(:new).with(
58
+ msgid: '1 multiline ruby',
59
+ msgid_plural: '%d multiline rubies',
60
+ references: ['test.slim:10']
61
+ )
62
+ end
63
+
64
+ it 'correctly extracts string from splat attributes' do
65
+ expect(PutText::POEntry).to have_received(:new).with(
66
+ msgctxt: 'ctx',
67
+ msgid: 'splat hash attr',
68
+ references: ['test.slim:13']
69
+ )
70
+ end
71
+
72
+ it 'correctly extracts string from text interpolation' do
73
+ expect(PutText::POEntry).to have_received(:new).with(
74
+ msgid: 'text interpolation',
75
+ references: ['test.slim:21']
76
+ )
77
+ end
78
+
79
+ it 'correctly extracts string from unescaped Ruby output code' do
80
+ expect(PutText::POEntry).to have_received(:new).with(
81
+ msgid: 'unescaped string',
82
+ references: ['test.slim:23']
83
+ )
84
+ end
85
+ end
86
+ end