deepl-rb 3.5.0 → 3.5.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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +27 -0
  3. data/.github/workflows/add_issues_to_kanban.yml +16 -0
  4. data/.gitlab-ci.yml +172 -0
  5. data/.rubocop.yml +51 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CODE_OF_CONDUCT.md +132 -0
  8. data/CONTRIBUTING.md +37 -0
  9. data/Gemfile +24 -0
  10. data/Rakefile +56 -0
  11. data/SECURITY.md +58 -0
  12. data/VERSION +1 -0
  13. data/deepl-rb.gemspec +139 -0
  14. data/lib/deepl/api.rb +22 -0
  15. data/lib/deepl/configuration.rb +59 -0
  16. data/lib/deepl/constants/base_constant.rb +18 -0
  17. data/lib/deepl/constants/formality.rb +16 -0
  18. data/lib/deepl/constants/model_type.rb +14 -0
  19. data/lib/deepl/constants/split_sentences.rb +14 -0
  20. data/lib/deepl/constants/tag_handling.rb +13 -0
  21. data/lib/deepl/constants/tone.rb +20 -0
  22. data/lib/deepl/constants/writing_style.rb +20 -0
  23. data/lib/deepl/document_api.rb +121 -0
  24. data/lib/deepl/exceptions/authorization_failed.rb +14 -0
  25. data/lib/deepl/exceptions/bad_request.rb +16 -0
  26. data/lib/deepl/exceptions/document_translation_error.rb +15 -0
  27. data/lib/deepl/exceptions/error.rb +14 -0
  28. data/lib/deepl/exceptions/limit_exceeded.rb +18 -0
  29. data/lib/deepl/exceptions/not_found.rb +16 -0
  30. data/lib/deepl/exceptions/not_supported.rb +14 -0
  31. data/lib/deepl/exceptions/quota_exceeded.rb +14 -0
  32. data/lib/deepl/exceptions/request_entity_too_large.rb +15 -0
  33. data/lib/deepl/exceptions/request_error.rb +21 -0
  34. data/lib/deepl/exceptions/server_error.rb +18 -0
  35. data/lib/deepl/glossary_api.rb +38 -0
  36. data/lib/deepl/requests/base.rb +196 -0
  37. data/lib/deepl/requests/document/download.rb +44 -0
  38. data/lib/deepl/requests/document/get_status.rb +44 -0
  39. data/lib/deepl/requests/document/upload.rb +74 -0
  40. data/lib/deepl/requests/glossary/create.rb +59 -0
  41. data/lib/deepl/requests/glossary/destroy.rb +37 -0
  42. data/lib/deepl/requests/glossary/entries.rb +37 -0
  43. data/lib/deepl/requests/glossary/find.rb +38 -0
  44. data/lib/deepl/requests/glossary/language_pairs.rb +38 -0
  45. data/lib/deepl/requests/glossary/list.rb +37 -0
  46. data/lib/deepl/requests/languages.rb +37 -0
  47. data/lib/deepl/requests/rephrase.rb +55 -0
  48. data/lib/deepl/requests/style_rule/list.rb +59 -0
  49. data/lib/deepl/requests/translate.rb +93 -0
  50. data/lib/deepl/requests/usage.rb +33 -0
  51. data/lib/deepl/resources/base.rb +17 -0
  52. data/lib/deepl/resources/document_handle.rb +57 -0
  53. data/lib/deepl/resources/document_translation_status.rb +54 -0
  54. data/lib/deepl/resources/glossary.rb +28 -0
  55. data/lib/deepl/resources/language.rb +30 -0
  56. data/lib/deepl/resources/language_pair.rb +23 -0
  57. data/lib/deepl/resources/style_rule.rb +85 -0
  58. data/lib/deepl/resources/text.rb +24 -0
  59. data/lib/deepl/resources/usage.rb +27 -0
  60. data/lib/deepl/style_rule_api.rb +17 -0
  61. data/lib/deepl/utils/backoff_timer.rb +46 -0
  62. data/lib/deepl/utils/exception_builder.rb +34 -0
  63. data/lib/deepl.rb +158 -0
  64. data/lib/http_client_options.rb +22 -0
  65. data/lib/version.rb +8 -0
  66. data/spec/api/api_spec.rb +20 -0
  67. data/spec/api/configuration_spec.rb +122 -0
  68. data/spec/api/deepl_spec.rb +460 -0
  69. data/spec/constants/constants_spec.rb +158 -0
  70. data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
  71. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
  72. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +1163 -0
  73. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +54 -0
  74. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +87 -0
  75. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +358 -0
  76. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +129 -0
  77. data/spec/fixtures/vcr_cassettes/glossaries.yml +1702 -0
  78. data/spec/fixtures/vcr_cassettes/languages.yml +229 -0
  79. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +401 -0
  80. data/spec/fixtures/vcr_cassettes/style_rules.yml +92 -0
  81. data/spec/fixtures/vcr_cassettes/translate_texts.yml +10458 -0
  82. data/spec/fixtures/vcr_cassettes/usage.yml +171 -0
  83. data/spec/integration_tests/document_api_spec.rb +178 -0
  84. data/spec/integration_tests/integration_test_utils.rb +170 -0
  85. data/spec/integration_tests/style_rule_api_spec.rb +79 -0
  86. data/spec/requests/glossary/create_spec.rb +65 -0
  87. data/spec/requests/glossary/destroy_spec.rb +66 -0
  88. data/spec/requests/glossary/entries_spec.rb +62 -0
  89. data/spec/requests/glossary/find_spec.rb +68 -0
  90. data/spec/requests/glossary/language_pairs_spec.rb +40 -0
  91. data/spec/requests/glossary/list_spec.rb +54 -0
  92. data/spec/requests/languages_spec.rb +68 -0
  93. data/spec/requests/rephrase_spec.rb +172 -0
  94. data/spec/requests/translate_spec.rb +459 -0
  95. data/spec/requests/usage_spec.rb +43 -0
  96. data/spec/resources/glossary_spec.rb +38 -0
  97. data/spec/resources/language_pair_spec.rb +23 -0
  98. data/spec/resources/language_spec.rb +45 -0
  99. data/spec/resources/text_spec.rb +23 -0
  100. data/spec/resources/usage_spec.rb +35 -0
  101. data/spec/spec_helper.rb +92 -0
  102. metadata +101 -2
@@ -0,0 +1,459 @@
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 `model_type` options' do
212
+ it 'works with a nil value' do
213
+ request = described_class.new(api, nil, nil, nil, model_type: nil)
214
+ expect(request.options[:model_type]).to be_nil
215
+ end
216
+
217
+ it 'works with a string' do
218
+ request = described_class.new(api, nil, nil, nil, model_type: 'latency_optimized')
219
+ expect(request.options[:model_type]).to eq('latency_optimized')
220
+ end
221
+
222
+ it 'works with provided constants' do
223
+ request = described_class.new(api, nil, nil, nil,
224
+ model_type: DeepL::Constants::ModelType::LATENCY_OPTIMIZED)
225
+ expect(request.options[:model_type]).to eq('latency_optimized')
226
+ end
227
+ end
228
+
229
+ context 'when using `custom_instructions` options' do
230
+ it 'works with a nil value' do
231
+ request = described_class.new(api, nil, nil, nil, custom_instructions: nil)
232
+ expect(request.options[:custom_instructions]).to be_nil
233
+ end
234
+
235
+ it 'works with an array of strings' do
236
+ instructions = ['Use informal language', 'Be concise']
237
+ request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
238
+ expect(request.options[:custom_instructions]).to eq(instructions)
239
+ end
240
+
241
+ it 'works with a single string' do
242
+ request = described_class.new(api, nil, nil, nil, custom_instructions: ['Be concise'])
243
+ expect(request.options[:custom_instructions]).to eq(['Be concise'])
244
+ end
245
+
246
+ it 'works with a single string and converts it to an array' do
247
+ instructions = 'Use informal language,Be concise'
248
+ request = described_class.new(api, nil, nil, nil, custom_instructions: instructions)
249
+ expect(request.options[:custom_instructions]).to eq(['Use informal language', 'Be concise'])
250
+ end
251
+ end
252
+ end
253
+
254
+ describe '#request' do
255
+ around do |example|
256
+ VCR.use_cassette('translate_texts') { example.call }
257
+ end
258
+
259
+ context 'when performing a valid request with one text' do
260
+ it 'returns a text object' do
261
+ text = translate.request
262
+
263
+ expect(text).to be_a(DeepL::Resources::Text)
264
+ expect(text.text).to eq('Texto de muestra')
265
+ expect(text.detected_source_language).to eq('EN')
266
+ end
267
+ end
268
+
269
+ context 'when performing a valid request with multiple texts' do
270
+ let(:text) { %w[Sample Word] }
271
+
272
+ it 'returns a text object' do
273
+ texts = translate.request
274
+
275
+ expect(texts).to be_a(Array)
276
+ expect(texts.first.text).to eq('Muestra')
277
+ expect(texts.first.detected_source_language).to eq('EN')
278
+
279
+ expect(texts.last.text).to eq('Palabra')
280
+ expect(texts.last.detected_source_language).to eq('EN')
281
+ end
282
+ end
283
+
284
+ context 'when performing a valid request with tag handling' do
285
+ let(:text) { '<p>Sample text</p>' }
286
+ let(:options) { { tag_handling: 'xml' } }
287
+
288
+ it 'returns a text object' do
289
+ text = translate.request
290
+
291
+ expect(text).to be_a(DeepL::Resources::Text)
292
+ expect(text.text).to eq('<p>Texto de muestra</p>')
293
+ expect(text.detected_source_language).to eq('EN')
294
+ end
295
+ end
296
+
297
+ context 'when performing a valid request and passing a variable' do
298
+ let(:text) { 'Welcome and <code>Hello great World</code> Good Morning!' }
299
+ let(:options) { { tag_handling: 'xml', ignore_tags: %w[code span] } }
300
+
301
+ it 'returns a text object' do
302
+ text = translate.request
303
+
304
+ expect(text).to be_a(DeepL::Resources::Text)
305
+ expect(text.text).to eq('Bienvenido y <code>Hello great World</code> ¡Buenos días!')
306
+ expect(text.detected_source_language).to eq('EN')
307
+ end
308
+ end
309
+
310
+ context 'when performing a valid request with an HTML document' do
311
+ let(:text) do
312
+ <<~XML
313
+ <document>
314
+ <meta>
315
+ <title>A document's title</title>
316
+ </meta>
317
+ <content>
318
+ <par>This is the first sentence. Followed by a second one.</par>
319
+ <par>This is the third sentence.</par>
320
+ </content>
321
+ </document>
322
+ XML
323
+ end
324
+ let(:options) do
325
+ {
326
+ tag_handling: 'xml',
327
+ split_sentences: 'nonewlines',
328
+ outline_detection: false,
329
+ splitting_tags: %w[title par]
330
+ }
331
+ end
332
+
333
+ it 'returns a text object' do
334
+ text = translate.request
335
+
336
+ expect(text).to be_a(DeepL::Resources::Text)
337
+ expect(text.text).to eq(
338
+ <<~XML
339
+ <document>
340
+ <meta>
341
+ <title>Título de un documento</title>
342
+ </meta>
343
+ <content>
344
+ <par>Es la primera frase. Seguido de una segunda.</par>
345
+ <par>Esta es la tercera frase.</par>
346
+ </content>
347
+ </document>
348
+ XML
349
+ )
350
+ expect(text.detected_source_language).to eq('EN')
351
+ end
352
+ end
353
+
354
+ context 'when performing a valid request with context' do
355
+ let(:text) { 'That is hot!' }
356
+
357
+ context 'when context is empty' do
358
+ let(:options) { { context: '' } }
359
+
360
+ it 'translates correctly with empty context' do
361
+ res = translate.request
362
+ expect(res).to be_a(DeepL::Resources::Text)
363
+ expect(res.text).to eq('¡Eso está caliente!')
364
+ end
365
+ end
366
+
367
+ context 'when context is set' do
368
+ let(:options) { { context: 'He did not like the jalapenos in his meal.' } }
369
+
370
+ it 'translates correctly with context taken into account' do
371
+ res = translate.request
372
+ expect(res).to be_a(DeepL::Resources::Text)
373
+ expect(res.text).to eq('¡Eso es picante!')
374
+ end
375
+ end
376
+ end
377
+
378
+ context 'when performing a request with a model type' do
379
+ let(:target_lang) { 'DE' }
380
+
381
+ %w[quality_optimized latency_optimized prefer_quality_optimized].each do |model_type_str|
382
+ it "translates correctly with #{model_type_str} models" do
383
+ options = { model_type: model_type_str }
384
+ translate = described_class.new(api, text, source_lang, target_lang, options)
385
+ res = translate.request
386
+ expect(res).to be_a(DeepL::Resources::Text)
387
+ expected_model_type = model_type_str.sub(/^prefer_/, '')
388
+ expect(res.model_type_used).to eq(expected_model_type)
389
+ end
390
+ end
391
+ end
392
+
393
+ context 'when performing a request with extra_body_parameters' do
394
+ it 'allows extra parameters to override standard parameters' do
395
+ extra_options = { extra_body_parameters: { target_lang: 'FR', debug: '1' } }
396
+ translate = described_class.new(api, text, source_lang, target_lang, extra_options)
397
+ res = translate.request
398
+
399
+ expect(res).to be_a(DeepL::Resources::Text)
400
+ expect(res.text).to eq('Texte modèle')
401
+ expect(res.detected_source_language).to eq('EN')
402
+ end
403
+ end
404
+
405
+ context 'when performing a request with custom_instructions' do
406
+ let(:text) { 'Hello world' }
407
+ let(:target_lang) { 'DE' }
408
+
409
+ it 'includes custom_instructions in the payload' do
410
+ options = { custom_instructions: ['Use formal language', 'Be concise'] }
411
+ translate = described_class.new(api, text, source_lang, target_lang, options)
412
+
413
+ # Verify the options are properly stored
414
+ expect(translate.options[:custom_instructions]).to eq(['Use formal language', 'Be concise'])
415
+ end
416
+ end
417
+
418
+ context 'when performing a bad request' do
419
+ context 'when using an invalid token' do
420
+ let(:api) do
421
+ api = build_deepl_api
422
+ api.configuration.auth_key = 'invalid'
423
+ api
424
+ end
425
+
426
+ it 'raises an unauthorized error' do
427
+ expect { translate.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
428
+ end
429
+ end
430
+
431
+ context 'when using an invalid text' do
432
+ let(:text) { nil }
433
+
434
+ it 'raises a bad request error' do
435
+ message = "Invalid request: Expected 'text' parameter to be an array of strings"
436
+ expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
437
+ end
438
+ end
439
+
440
+ context 'when using an invalid target language' do
441
+ let(:target_lang) { nil }
442
+
443
+ it 'raises a bad request error' do
444
+ message = "Value for 'target_lang' not supported."
445
+ expect { translate.request }.to raise_error(DeepL::Exceptions::BadRequest, message)
446
+ end
447
+ end
448
+ end
449
+
450
+ context 'when performing a request with too many texts' do
451
+ let(:text) { Array.new(10_000) { |i| "This is the sentence number #{i}" } }
452
+
453
+ it 'raises a request entity too large error' do
454
+ expect { translate.request }.to raise_error(DeepL::Exceptions::RequestEntityTooLarge,
455
+ /request size has reached the supported limit/)
456
+ end
457
+ end
458
+ end
459
+ 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
@@ -0,0 +1,35 @@
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::Usage do
9
+ subject(:usage) { described_class.new(3, 5, nil, nil) }
10
+
11
+ describe '#initialize' do
12
+ context 'when building a basic object' do
13
+ it 'creates a resource' do
14
+ expect(usage).to be_a(described_class)
15
+ end
16
+
17
+ it 'assigns the attributes' do
18
+ expect(usage.character_count).to eq(3)
19
+ expect(usage.character_limit).to eq(5)
20
+ end
21
+
22
+ it 'does not exceed the quota' do
23
+ expect(usage).not_to be_quota_exceeded
24
+ end
25
+ end
26
+
27
+ context 'when building a quota exceeded object' do
28
+ subject(:usage) { described_class.new(5, 5, nil, nil) }
29
+
30
+ it 'exceeds the quota' do
31
+ expect(usage).to be_quota_exceeded
32
+ end
33
+ end
34
+ end
35
+ end