puttext 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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