deepl-rb 3.6.0 → 3.6.1
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +27 -0
- data/.github/workflows/add_issues_to_kanban.yml +16 -0
- data/.gitlab-ci.yml +172 -0
- data/.rubocop.yml +51 -0
- data/CHANGELOG.md +22 -3
- data/CODE_OF_CONDUCT.md +132 -0
- data/CONTRIBUTING.md +37 -0
- data/Gemfile +24 -0
- data/Rakefile +56 -0
- data/SECURITY.md +58 -0
- data/VERSION +1 -0
- data/deepl-rb.gemspec +140 -0
- data/lib/deepl/api.rb +22 -0
- data/lib/deepl/configuration.rb +59 -0
- data/lib/deepl/constants/base_constant.rb +18 -0
- data/lib/deepl/constants/formality.rb +16 -0
- data/lib/deepl/constants/model_type.rb +14 -0
- data/lib/deepl/constants/split_sentences.rb +14 -0
- data/lib/deepl/constants/tag_handling.rb +13 -0
- data/lib/deepl/constants/tone.rb +20 -0
- data/lib/deepl/constants/writing_style.rb +20 -0
- data/lib/deepl/document_api.rb +121 -0
- data/lib/deepl/exceptions/authorization_failed.rb +14 -0
- data/lib/deepl/exceptions/bad_request.rb +16 -0
- data/lib/deepl/exceptions/document_translation_error.rb +15 -0
- data/lib/deepl/exceptions/error.rb +14 -0
- data/lib/deepl/exceptions/limit_exceeded.rb +18 -0
- data/lib/deepl/exceptions/not_found.rb +16 -0
- data/lib/deepl/exceptions/not_supported.rb +14 -0
- data/lib/deepl/exceptions/quota_exceeded.rb +14 -0
- data/lib/deepl/exceptions/request_entity_too_large.rb +15 -0
- data/lib/deepl/exceptions/request_error.rb +21 -0
- data/lib/deepl/exceptions/server_error.rb +18 -0
- data/lib/deepl/glossary_api.rb +38 -0
- data/lib/deepl/requests/base.rb +196 -0
- data/lib/deepl/requests/document/download.rb +44 -0
- data/lib/deepl/requests/document/get_status.rb +44 -0
- data/lib/deepl/requests/document/upload.rb +74 -0
- data/lib/deepl/requests/glossary/create.rb +59 -0
- data/lib/deepl/requests/glossary/destroy.rb +37 -0
- data/lib/deepl/requests/glossary/entries.rb +37 -0
- data/lib/deepl/requests/glossary/find.rb +38 -0
- data/lib/deepl/requests/glossary/language_pairs.rb +38 -0
- data/lib/deepl/requests/glossary/list.rb +37 -0
- data/lib/deepl/requests/languages.rb +37 -0
- data/lib/deepl/requests/rephrase.rb +55 -0
- data/lib/deepl/requests/style_rule/list.rb +59 -0
- data/lib/deepl/requests/translate.rb +93 -0
- data/lib/deepl/requests/usage.rb +33 -0
- data/lib/deepl/resources/base.rb +17 -0
- data/lib/deepl/resources/document_handle.rb +57 -0
- data/lib/deepl/resources/document_translation_status.rb +54 -0
- data/lib/deepl/resources/glossary.rb +28 -0
- data/lib/deepl/resources/language.rb +30 -0
- data/lib/deepl/resources/language_pair.rb +23 -0
- data/lib/deepl/resources/style_rule.rb +85 -0
- data/lib/deepl/resources/text.rb +24 -0
- data/lib/deepl/resources/usage.rb +27 -0
- data/lib/deepl/style_rule_api.rb +17 -0
- data/lib/deepl/utils/backoff_timer.rb +46 -0
- data/lib/deepl/utils/exception_builder.rb +34 -0
- data/lib/deepl.rb +158 -0
- data/lib/http_client_options.rb +22 -0
- data/lib/version.rb +8 -0
- data/spec/api/api_spec.rb +20 -0
- data/spec/api/configuration_spec.rb +122 -0
- data/spec/api/deepl_spec.rb +460 -0
- data/spec/constants/constants_spec.rb +158 -0
- data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
- data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
- data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +1163 -0
- data/spec/fixtures/vcr_cassettes/deepl_languages.yml +54 -0
- data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +87 -0
- data/spec/fixtures/vcr_cassettes/deepl_translate.yml +358 -0
- data/spec/fixtures/vcr_cassettes/deepl_usage.yml +129 -0
- data/spec/fixtures/vcr_cassettes/glossaries.yml +1702 -0
- data/spec/fixtures/vcr_cassettes/languages.yml +229 -0
- data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +401 -0
- data/spec/fixtures/vcr_cassettes/style_rules.yml +92 -0
- data/spec/fixtures/vcr_cassettes/translate_texts.yml +10630 -0
- data/spec/fixtures/vcr_cassettes/usage.yml +171 -0
- data/spec/integration_tests/document_api_spec.rb +178 -0
- data/spec/integration_tests/integration_test_utils.rb +170 -0
- data/spec/integration_tests/style_rule_api_spec.rb +79 -0
- data/spec/requests/extra_body_parameters_types_spec.rb +82 -0
- data/spec/requests/glossary/create_spec.rb +65 -0
- data/spec/requests/glossary/destroy_spec.rb +66 -0
- data/spec/requests/glossary/entries_spec.rb +62 -0
- data/spec/requests/glossary/find_spec.rb +68 -0
- data/spec/requests/glossary/language_pairs_spec.rb +40 -0
- data/spec/requests/glossary/list_spec.rb +54 -0
- data/spec/requests/languages_spec.rb +68 -0
- data/spec/requests/rephrase_spec.rb +172 -0
- data/spec/requests/translate_spec.rb +493 -0
- data/spec/requests/usage_spec.rb +43 -0
- data/spec/resources/glossary_spec.rb +38 -0
- data/spec/resources/language_pair_spec.rb +23 -0
- data/spec/resources/language_spec.rb +45 -0
- data/spec/resources/text_spec.rb +23 -0
- data/spec/resources/usage_spec.rb +35 -0
- data/spec/spec_helper.rb +92 -0
- metadata +102 -2
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Requests::Translate do
|
|
9
|
+
subject(:translate) { described_class.new(api, text, source_lang, target_lang, options) }
|
|
10
|
+
|
|
11
|
+
around do |tests|
|
|
12
|
+
tmp_env = replace_env_preserving_deepl_vars_except_mock_server
|
|
13
|
+
tests.call
|
|
14
|
+
ENV.replace(tmp_env)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:tags_str) { 'p,strong,span' }
|
|
18
|
+
let(:tags_array) { %w[p strong span] }
|
|
19
|
+
|
|
20
|
+
let(:api) { build_deepl_api }
|
|
21
|
+
let(:text) { 'Sample text' }
|
|
22
|
+
let(:source_lang) { 'EN' }
|
|
23
|
+
let(:target_lang) { 'ES' }
|
|
24
|
+
let(:options) { {} }
|
|
25
|
+
|
|
26
|
+
describe '#initialize' do
|
|
27
|
+
context 'when building a request' do
|
|
28
|
+
it 'creates a request object' do
|
|
29
|
+
expect(translate).to be_a(described_class)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'when using `splitting_tags` options' do
|
|
34
|
+
it 'works with a nil values' do
|
|
35
|
+
request = described_class.new(api, nil, nil, nil, splitting_tags: nil)
|
|
36
|
+
expect(request.options[:splitting_tags]).to be_nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'works with a blank list' do
|
|
40
|
+
request = described_class.new(api, nil, nil, nil, splitting_tags: '')
|
|
41
|
+
expect(request.options[:splitting_tags]).to eq([])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'works with a comma-separated list and converts strings to an array' do
|
|
45
|
+
request = described_class.new(api, nil, nil, nil, splitting_tags: tags_str)
|
|
46
|
+
expect(request.options[:splitting_tags]).to eq(tags_array)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'works with an array of tags and leaves it as is' do
|
|
50
|
+
request = described_class.new(api, nil, nil, nil, splitting_tags: tags_array)
|
|
51
|
+
expect(request.options[:splitting_tags]).to eq(tags_array)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context 'when using `non_splitting_tags` options' do
|
|
56
|
+
it 'works with a nil values' do
|
|
57
|
+
request = described_class.new(api, nil, nil, nil, non_splitting_tags: nil)
|
|
58
|
+
expect(request.options[:non_splitting_tags]).to be_nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'works with a blank list' do
|
|
62
|
+
request = described_class.new(api, nil, nil, nil, non_splitting_tags: '')
|
|
63
|
+
expect(request.options[:non_splitting_tags]).to eq([])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'works with a comma-separated list and converts strings to an array' do
|
|
67
|
+
request = described_class.new(api, nil, nil, nil, non_splitting_tags: tags_str)
|
|
68
|
+
expect(request.options[:non_splitting_tags]).to eq(tags_array)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'works with an array and leaves it as it is' do
|
|
72
|
+
request = described_class.new(api, nil, nil, nil, non_splitting_tags: tags_array)
|
|
73
|
+
expect(request.options[:non_splitting_tags]).to eq(tags_array)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when using `ignore_tags` options' do
|
|
78
|
+
it 'works with a nil values' do
|
|
79
|
+
request = described_class.new(api, nil, nil, nil, ignore_tags: nil)
|
|
80
|
+
expect(request.options[:ignore_tags]).to be_nil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'works with a blank list' do
|
|
84
|
+
request = described_class.new(api, nil, nil, nil, ignore_tags: '')
|
|
85
|
+
expect(request.options[:ignore_tags]).to eq([])
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'works with a comma-separated list and converts a string to an array' do
|
|
89
|
+
request = described_class.new(api, nil, nil, nil, ignore_tags: tags_str)
|
|
90
|
+
expect(request.options[:ignore_tags]).to eq(tags_array)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'works with an array and leaves it as it is' do
|
|
94
|
+
request = described_class.new(api, nil, nil, nil, ignore_tags: tags_array)
|
|
95
|
+
expect(request.options[:ignore_tags]).to eq(tags_array)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
context 'when using `split_sentences` options' do
|
|
100
|
+
it 'converts `true` to `1`' do
|
|
101
|
+
request = described_class.new(api, nil, nil, nil, split_sentences: true)
|
|
102
|
+
expect(request.options[:split_sentences]).to eq('1')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'converts `false` to `0`' do
|
|
106
|
+
request = described_class.new(api, nil, nil, nil, split_sentences: false)
|
|
107
|
+
expect(request.options[:split_sentences]).to eq('0')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'leaves `0` as is' do
|
|
111
|
+
request = described_class.new(api, nil, nil, nil, split_sentences: '0')
|
|
112
|
+
expect(request.options[:split_sentences]).to eq('0')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'leaves `nonewlines` as is' do
|
|
116
|
+
request = described_class.new(api, nil, nil, nil, split_sentences: 'nonewlines')
|
|
117
|
+
expect(request.options[:split_sentences]).to eq('nonewlines')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'leaves `1` as is' do
|
|
121
|
+
request = described_class.new(api, nil, nil, nil, split_sentences: '1')
|
|
122
|
+
expect(request.options[:split_sentences]).to eq('1')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'works with provided constants' do
|
|
126
|
+
request = described_class.new(
|
|
127
|
+
api,
|
|
128
|
+
nil,
|
|
129
|
+
nil,
|
|
130
|
+
nil,
|
|
131
|
+
split_sentences: DeepL::Constants::SplitSentences::SPLIT_ON_PUNCTUATION_AND_NEWLINES
|
|
132
|
+
)
|
|
133
|
+
expect(request.options[:split_sentences]).to eq('1')
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context 'when using `preserve_formatting` options' do
|
|
138
|
+
it 'leaves `true` as is' do
|
|
139
|
+
request = described_class.new(api, nil, nil, nil, preserve_formatting: true)
|
|
140
|
+
expect(request.options[:preserve_formatting]).to be(true)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'leaves `false` as is' do
|
|
144
|
+
request = described_class.new(api, nil, nil, nil, preserve_formatting: false)
|
|
145
|
+
expect(request.options[:preserve_formatting]).to be(false)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'converts `0` to `false`' do
|
|
149
|
+
request = described_class.new(api, nil, nil, nil, preserve_formatting: '0')
|
|
150
|
+
expect(request.options[:preserve_formatting]).to be(false)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it 'converts `1` to `true`' do
|
|
154
|
+
request = described_class.new(api, nil, nil, nil, preserve_formatting: '1')
|
|
155
|
+
expect(request.options[:preserve_formatting]).to be(true)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context 'when using `outline_detection` options' do
|
|
160
|
+
it 'leaves `true` as is' do
|
|
161
|
+
request = described_class.new(api, nil, nil, nil, outline_detection: true)
|
|
162
|
+
expect(request.options[:outline_detection]).to be(true)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it 'leaves `false` as is' do
|
|
166
|
+
request = described_class.new(api, nil, nil, nil, outline_detection: false)
|
|
167
|
+
expect(request.options[:outline_detection]).to be(false)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'converts `0` to `false`' do
|
|
171
|
+
request = described_class.new(api, nil, nil, nil, outline_detection: '0')
|
|
172
|
+
expect(request.options[:outline_detection]).to be(false)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'converts `1` to `true`' do
|
|
176
|
+
request = described_class.new(api, nil, nil, nil, outline_detection: '1')
|
|
177
|
+
expect(request.options[:outline_detection]).to be(true)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context 'when using `glossary_id` options' do
|
|
182
|
+
it 'works with a nil values' do
|
|
183
|
+
request = described_class.new(api, nil, nil, nil, glossary_id: nil)
|
|
184
|
+
expect(request.options[:glossary_id]).to be_nil
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'works with a string' do
|
|
188
|
+
request = described_class.new(api, nil, nil, nil, glossary_id: 'sample_id')
|
|
189
|
+
expect(request.options[:glossary_id]).to eq('sample_id')
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context 'when using `formality` options' do
|
|
194
|
+
it 'works with a nil values' do
|
|
195
|
+
request = described_class.new(api, nil, nil, nil, formality: nil)
|
|
196
|
+
expect(request.options[:formality]).to be_nil
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it 'works with a string' do
|
|
200
|
+
request = described_class.new(api, nil, nil, nil, formality: 'more')
|
|
201
|
+
expect(request.options[:formality]).to eq('more')
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'works with provided constants' do
|
|
205
|
+
request = described_class.new(api, nil, nil, nil,
|
|
206
|
+
formality: DeepL::Constants::Formality::MORE)
|
|
207
|
+
expect(request.options[:formality]).to eq('more')
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
context 'when using `tag_handling_version` options' do
|
|
212
|
+
it 'works with a nil value' do
|
|
213
|
+
request = described_class.new(api, nil, nil, nil, tag_handling_version: nil)
|
|
214
|
+
expect(request.options[:tag_handling_version]).to be_nil
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'works with v1' do
|
|
218
|
+
request = described_class.new(api, nil, nil, nil, tag_handling_version: 'v1')
|
|
219
|
+
expect(request.options[:tag_handling_version]).to eq('v1')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'works with v2' do
|
|
223
|
+
request = described_class.new(api, nil, nil, nil, tag_handling_version: 'v2')
|
|
224
|
+
expect(request.options[:tag_handling_version]).to eq('v2')
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
context 'when using `model_type` options' do
|
|
229
|
+
it 'works with a nil value' do
|
|
230
|
+
request = described_class.new(api, nil, nil, nil, model_type: nil)
|
|
231
|
+
expect(request.options[:model_type]).to be_nil
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'works with a string' do
|
|
235
|
+
request = described_class.new(api, nil, nil, nil, model_type: 'latency_optimized')
|
|
236
|
+
expect(request.options[:model_type]).to eq('latency_optimized')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'works with provided constants' do
|
|
240
|
+
request = described_class.new(api, nil, nil, nil,
|
|
241
|
+
model_type: DeepL::Constants::ModelType::LATENCY_OPTIMIZED)
|
|
242
|
+
expect(request.options[:model_type]).to eq('latency_optimized')
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context 'when using `custom_instructions` options' do
|
|
247
|
+
it 'works with a nil value' do
|
|
248
|
+
request = described_class.new(api, nil, nil, nil, custom_instructions: nil)
|
|
249
|
+
expect(request.options[:custom_instructions]).to be_nil
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it 'works with an array of strings' do
|
|
253
|
+
instructions = ['Use informal language', 'Be concise']
|
|
254
|
+
request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
|
|
255
|
+
expect(request.options[:custom_instructions]).to eq(instructions)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'works with a single string' do
|
|
259
|
+
request = described_class.new(api, nil, nil, nil, custom_instructions: ['Be concise'])
|
|
260
|
+
expect(request.options[:custom_instructions]).to eq(['Be concise'])
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'works with a single string and converts it to an array' do
|
|
264
|
+
instructions = 'Use informal language,Be concise'
|
|
265
|
+
request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
|
|
266
|
+
expect(request.options[:custom_instructions]).to eq(['Use informal language', 'Be concise'])
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
describe '#request' do
|
|
272
|
+
around do |example|
|
|
273
|
+
VCR.use_cassette('translate_texts') { example.call }
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
context 'when performing a valid request with one text' do
|
|
277
|
+
it 'returns a text object' do
|
|
278
|
+
text = translate.request
|
|
279
|
+
|
|
280
|
+
expect(text).to be_a(DeepL::Resources::Text)
|
|
281
|
+
expect(text.text).to eq('Texto de muestra')
|
|
282
|
+
expect(text.detected_source_language).to eq('EN')
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
context 'when performing a valid request with multiple texts' do
|
|
287
|
+
let(:text) { %w[Sample Word] }
|
|
288
|
+
|
|
289
|
+
it 'returns a text object' do
|
|
290
|
+
texts = translate.request
|
|
291
|
+
|
|
292
|
+
expect(texts).to be_a(Array)
|
|
293
|
+
expect(texts.first.text).to eq('Muestra')
|
|
294
|
+
expect(texts.first.detected_source_language).to eq('EN')
|
|
295
|
+
|
|
296
|
+
expect(texts.last.text).to eq('Palabra')
|
|
297
|
+
expect(texts.last.detected_source_language).to eq('EN')
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
context 'when performing a valid request with tag handling' do
|
|
302
|
+
let(:text) { '<p>Sample text</p>' }
|
|
303
|
+
let(:options) { { tag_handling: 'xml' } }
|
|
304
|
+
|
|
305
|
+
it 'returns a text object' do
|
|
306
|
+
text = translate.request
|
|
307
|
+
|
|
308
|
+
expect(text).to be_a(DeepL::Resources::Text)
|
|
309
|
+
expect(text.text).to eq('<p>Texto de muestra</p>')
|
|
310
|
+
expect(text.detected_source_language).to eq('EN')
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
context 'when performing a valid request and passing a variable' do
|
|
315
|
+
let(:text) { 'Welcome and <code>Hello great World</code> Good Morning!' }
|
|
316
|
+
let(:options) { { tag_handling: 'xml', ignore_tags: %w[code span] } }
|
|
317
|
+
|
|
318
|
+
it 'returns a text object' do
|
|
319
|
+
text = translate.request
|
|
320
|
+
|
|
321
|
+
expect(text).to be_a(DeepL::Resources::Text)
|
|
322
|
+
expect(text.text).to eq('Bienvenido y <code>Hello great World</code> ¡Buenos días!')
|
|
323
|
+
expect(text.detected_source_language).to eq('EN')
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
context 'when performing a valid request with an HTML document' do
|
|
328
|
+
let(:text) do
|
|
329
|
+
<<~XML
|
|
330
|
+
<document>
|
|
331
|
+
<meta>
|
|
332
|
+
<title>A document's title</title>
|
|
333
|
+
</meta>
|
|
334
|
+
<content>
|
|
335
|
+
<par>This is the first sentence. Followed by a second one.</par>
|
|
336
|
+
<par>This is the third sentence.</par>
|
|
337
|
+
</content>
|
|
338
|
+
</document>
|
|
339
|
+
XML
|
|
340
|
+
end
|
|
341
|
+
let(:options) do
|
|
342
|
+
{
|
|
343
|
+
tag_handling: 'xml',
|
|
344
|
+
split_sentences: 'nonewlines',
|
|
345
|
+
outline_detection: false,
|
|
346
|
+
splitting_tags: %w[title par]
|
|
347
|
+
}
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'returns a text object' do
|
|
351
|
+
text = translate.request
|
|
352
|
+
|
|
353
|
+
expect(text).to be_a(DeepL::Resources::Text)
|
|
354
|
+
expect(text.text).to eq(
|
|
355
|
+
<<~XML
|
|
356
|
+
<document>
|
|
357
|
+
<meta>
|
|
358
|
+
<title>Título de un documento</title>
|
|
359
|
+
</meta>
|
|
360
|
+
<content>
|
|
361
|
+
<par>Es la primera frase. Seguido de una segunda.</par>
|
|
362
|
+
<par>Esta es la tercera frase.</par>
|
|
363
|
+
</content>
|
|
364
|
+
</document>
|
|
365
|
+
XML
|
|
366
|
+
)
|
|
367
|
+
expect(text.detected_source_language).to eq('EN')
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
context 'when performing a valid request with context' do
|
|
372
|
+
let(:text) { 'That is hot!' }
|
|
373
|
+
|
|
374
|
+
context 'when context is empty' do
|
|
375
|
+
let(:options) { { context: '' } }
|
|
376
|
+
|
|
377
|
+
it 'translates correctly with empty context' do
|
|
378
|
+
res = translate.request
|
|
379
|
+
expect(res).to be_a(DeepL::Resources::Text)
|
|
380
|
+
expect(res.text).to eq('¡Eso está caliente!')
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
context 'when context is set' do
|
|
385
|
+
let(:options) { { context: 'He did not like the jalapenos in his meal.' } }
|
|
386
|
+
|
|
387
|
+
it 'translates correctly with context taken into account' do
|
|
388
|
+
res = translate.request
|
|
389
|
+
expect(res).to be_a(DeepL::Resources::Text)
|
|
390
|
+
expect(res.text).to eq('¡Eso es picante!')
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
context 'when performing a request with a model type' do
|
|
396
|
+
let(:target_lang) { 'DE' }
|
|
397
|
+
|
|
398
|
+
%w[quality_optimized latency_optimized prefer_quality_optimized].each do |model_type_str|
|
|
399
|
+
it "translates correctly with #{model_type_str} models" do
|
|
400
|
+
options = { model_type: model_type_str }
|
|
401
|
+
translate = described_class.new(api, text, source_lang, target_lang, options)
|
|
402
|
+
res = translate.request
|
|
403
|
+
expect(res).to be_a(DeepL::Resources::Text)
|
|
404
|
+
expected_model_type = model_type_str.sub(/^prefer_/, '')
|
|
405
|
+
expect(res.model_type_used).to eq(expected_model_type)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context 'when performing a request with extra_body_parameters' do
|
|
411
|
+
it 'allows extra parameters to override standard parameters' do
|
|
412
|
+
extra_options = { extra_body_parameters: { target_lang: 'FR', debug: '1' } }
|
|
413
|
+
translate = described_class.new(api, text, source_lang, target_lang, extra_options)
|
|
414
|
+
res = translate.request
|
|
415
|
+
|
|
416
|
+
expect(res).to be_a(DeepL::Resources::Text)
|
|
417
|
+
expect(res.text).to eq('Texte modèle')
|
|
418
|
+
expect(res.detected_source_language).to eq('EN')
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
context 'when performing a request with custom_instructions' do
|
|
423
|
+
let(:text) { 'Hello world' }
|
|
424
|
+
let(:target_lang) { 'DE' }
|
|
425
|
+
|
|
426
|
+
it 'includes custom_instructions in the payload' do
|
|
427
|
+
options = { custom_instructions: ['Use formal language', 'Be concise'] }
|
|
428
|
+
translate = described_class.new(api, text, source_lang, target_lang, options)
|
|
429
|
+
|
|
430
|
+
# Verify the options are properly stored
|
|
431
|
+
expect(translate.options[:custom_instructions]).to eq(['Use formal language', 'Be concise'])
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
context 'when performing a request with tag_handling_version' do
|
|
436
|
+
let(:text) { '<p>Hello world</p>' }
|
|
437
|
+
let(:target_lang) { 'DE' }
|
|
438
|
+
|
|
439
|
+
%w[v1 v2].each do |version|
|
|
440
|
+
it "translates correctly with tag_handling_version #{version}" do
|
|
441
|
+
options = { tag_handling: 'html', tag_handling_version: version }
|
|
442
|
+
translate = described_class.new(api, text, source_lang, target_lang, options)
|
|
443
|
+
res = translate.request
|
|
444
|
+
|
|
445
|
+
expect(res).to be_a(DeepL::Resources::Text)
|
|
446
|
+
expect(res.text).not_to be_nil
|
|
447
|
+
expect(res.text).not_to be_empty
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
context 'when performing a bad request' do
|
|
453
|
+
context 'when using an invalid token' do
|
|
454
|
+
let(:api) do
|
|
455
|
+
api = build_deepl_api
|
|
456
|
+
api.configuration.auth_key = 'invalid'
|
|
457
|
+
api
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
it 'raises an unauthorized error' do
|
|
461
|
+
expect { translate.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
context 'when using an invalid text' do
|
|
466
|
+
let(:text) { nil }
|
|
467
|
+
|
|
468
|
+
it 'raises a bad request error' do
|
|
469
|
+
message = "Invalid request: Expected 'text' parameter to be an array of strings"
|
|
470
|
+
expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
context 'when using an invalid target language' do
|
|
475
|
+
let(:target_lang) { nil }
|
|
476
|
+
|
|
477
|
+
it 'raises a bad request error' do
|
|
478
|
+
message = "Value for 'target_lang' not supported."
|
|
479
|
+
expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
context 'when performing a request with too many texts' do
|
|
485
|
+
let(:text) { Array.new(10_000) { |i| "This is the sentence number #{i}" } }
|
|
486
|
+
|
|
487
|
+
it 'raises a request entity too large error' do
|
|
488
|
+
expect { translate.request }.to raise_error(DeepL::Exceptions::RequestEntityTooLarge,
|
|
489
|
+
/request size has reached the supported limit/)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Requests::Usage do
|
|
9
|
+
subject(:usage_req) { described_class.new(api, options) }
|
|
10
|
+
|
|
11
|
+
around do |tests|
|
|
12
|
+
tmp_env = replace_env_preserving_deepl_vars_except_mock_server
|
|
13
|
+
tests.call
|
|
14
|
+
ENV.replace(tmp_env)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:api) { build_deepl_api }
|
|
18
|
+
let(:options) { {} }
|
|
19
|
+
|
|
20
|
+
describe '#initialize' do
|
|
21
|
+
context 'when building a request' do
|
|
22
|
+
it 'creates a request object' do
|
|
23
|
+
expect(usage_req).to be_a(described_class)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#request' do
|
|
29
|
+
around do |example|
|
|
30
|
+
VCR.use_cassette('usage') { example.call }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'when performing a valid request' do
|
|
34
|
+
it 'returns an usage object' do
|
|
35
|
+
usage = usage_req.request
|
|
36
|
+
|
|
37
|
+
expect(usage).to be_a(DeepL::Resources::Usage)
|
|
38
|
+
expect(usage.character_count).to be_a(Numeric)
|
|
39
|
+
expect(usage.character_limit).to be_a(Numeric)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Resources::Glossary do
|
|
9
|
+
subject(:glossary) do
|
|
10
|
+
described_class.new({
|
|
11
|
+
'glossary_id' => 'def3a26b-3e84-45b3-84ae-0c0aaf3525f7',
|
|
12
|
+
'name' => 'Mein Glossar',
|
|
13
|
+
'ready' => true,
|
|
14
|
+
'source_lang' => 'EN',
|
|
15
|
+
'target_lang' => 'DE',
|
|
16
|
+
'creation_time' => '2021-08-03T14:16:18.329Z',
|
|
17
|
+
'entry_count' => 1
|
|
18
|
+
}, nil, nil)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#initialize' do
|
|
22
|
+
context 'when building a basic object' do
|
|
23
|
+
it 'creates a resource' do
|
|
24
|
+
expect(glossary).to be_a(described_class)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'assigns the attributes' do
|
|
28
|
+
expect(glossary.id).to eq('def3a26b-3e84-45b3-84ae-0c0aaf3525f7')
|
|
29
|
+
expect(glossary.name).to eq('Mein Glossar')
|
|
30
|
+
expect(glossary.ready).to be(true)
|
|
31
|
+
expect(glossary.source_lang).to eq('EN')
|
|
32
|
+
expect(glossary.target_lang).to eq('DE')
|
|
33
|
+
expect(glossary.creation_time).to eq('2021-08-03T14:16:18.329Z')
|
|
34
|
+
expect(glossary.entry_count).to eq(1)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Resources::LanguagePair do
|
|
9
|
+
subject(:language_pair) { described_class.new('en', 'de', nil, nil) }
|
|
10
|
+
|
|
11
|
+
describe '#initialize' do
|
|
12
|
+
context 'when building a basic object' do
|
|
13
|
+
it 'creates a resource' do
|
|
14
|
+
expect(language_pair).to be_a(described_class)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'assigns the attributes' do
|
|
18
|
+
expect(language_pair.source_lang).to eq('en')
|
|
19
|
+
expect(language_pair.target_lang).to eq('de')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright 2021 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Resources::Language do
|
|
9
|
+
subject(:language) { described_class.new('EN', 'English', nil, nil, nil) }
|
|
10
|
+
|
|
11
|
+
describe '#initialize' do
|
|
12
|
+
context 'when building a basic object' do
|
|
13
|
+
it 'creates a resource' do
|
|
14
|
+
expect(language).to be_a(described_class)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'assigns the attributes' do
|
|
18
|
+
expect(language.code).to eq('EN')
|
|
19
|
+
expect(language.name).to eq('English')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'does not define the supports formality method' do
|
|
23
|
+
expect { language.supports_formality? }.to raise_error(DeepL::Exceptions::NotSupported)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'when building a target language object' do
|
|
28
|
+
subject(:language) { described_class.new('EN', 'English', true, nil, nil) }
|
|
29
|
+
|
|
30
|
+
it 'creates a resource' do
|
|
31
|
+
expect(language).to be_a(described_class)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'assigns the attributes' do
|
|
35
|
+
expect(language.code).to eq('EN')
|
|
36
|
+
expect(language.name).to eq('English')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'includes the supports formality method' do
|
|
40
|
+
expect { language.supports_formality? }.not_to raise_error
|
|
41
|
+
expect(language).to be_supports_formality
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
|
2
|
+
# Use of this source code is governed by an MIT
|
|
3
|
+
# license that can be found in the LICENSE.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require 'spec_helper'
|
|
7
|
+
|
|
8
|
+
describe DeepL::Resources::Text do
|
|
9
|
+
subject(:text) { described_class.new('Target', 'es', nil, nil, nil) }
|
|
10
|
+
|
|
11
|
+
describe '#initialize' do
|
|
12
|
+
context 'when building a basic object' do
|
|
13
|
+
it 'creates a resource' do
|
|
14
|
+
expect(text).to be_a(described_class)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'assigns the attributes' do
|
|
18
|
+
expect(text.text).to eq('Target')
|
|
19
|
+
expect(text.detected_source_language).to eq('es')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|