deepl-rb 3.6.1 → 3.8.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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +8 -1
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +0 -2
  5. data/README.md +165 -34
  6. data/Rakefile +2 -0
  7. data/VERSION +1 -1
  8. data/deepl-rb.gemspec +52 -20
  9. data/lib/deepl/requests/base.rb +16 -0
  10. data/lib/deepl/requests/document/upload.rb +6 -5
  11. data/lib/deepl/requests/rephrase.rb +3 -2
  12. data/lib/deepl/requests/style_rule/create.rb +46 -0
  13. data/lib/deepl/requests/style_rule/create_custom_instruction.rb +45 -0
  14. data/lib/deepl/requests/style_rule/destroy.rb +39 -0
  15. data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +40 -0
  16. data/lib/deepl/requests/style_rule/find.rb +40 -0
  17. data/lib/deepl/requests/style_rule/find_custom_instruction.rb +41 -0
  18. data/lib/deepl/requests/style_rule/update.rb +42 -0
  19. data/lib/deepl/requests/style_rule/update_configured_rules.rb +41 -0
  20. data/lib/deepl/requests/style_rule/update_custom_instruction.rb +47 -0
  21. data/lib/deepl/requests/translate.rb +17 -4
  22. data/lib/deepl/requests/translation_memory/list.rb +58 -0
  23. data/lib/deepl/resources/style_rule.rb +2 -1
  24. data/lib/deepl/resources/translation_memory.rb +25 -0
  25. data/lib/deepl/style_rule_api.rb +44 -0
  26. data/lib/deepl/translation_memory_api.rb +17 -0
  27. data/lib/deepl.rb +75 -55
  28. data/lib/version.rb +1 -1
  29. data/spec/api/deepl_spec.rb +134 -332
  30. data/spec/integration_tests/document_api_spec.rb +4 -18
  31. data/spec/integration_tests/document_error_paths_spec.rb +33 -0
  32. data/spec/integration_tests/glossary_api_spec.rb +114 -0
  33. data/spec/integration_tests/glossary_error_paths_spec.rb +107 -0
  34. data/spec/integration_tests/languages_api_spec.rb +54 -0
  35. data/spec/integration_tests/languages_error_paths_spec.rb +25 -0
  36. data/spec/integration_tests/rephrase_api_spec.rb +90 -0
  37. data/spec/integration_tests/rephrase_error_paths_spec.rb +53 -0
  38. data/spec/integration_tests/smoke_test_spec.rb +24 -0
  39. data/spec/integration_tests/style_rule_api_spec.rb +55 -17
  40. data/spec/integration_tests/style_rule_error_paths_spec.rb +45 -0
  41. data/spec/integration_tests/translate_api_spec.rb +98 -0
  42. data/spec/integration_tests/translate_error_paths_spec.rb +48 -0
  43. data/spec/integration_tests/translation_memory_api_spec.rb +54 -0
  44. data/spec/integration_tests/translation_memory_error_paths_spec.rb +19 -0
  45. data/spec/integration_tests/usage_api_spec.rb +29 -0
  46. data/spec/integration_tests/usage_error_paths_spec.rb +18 -0
  47. data/spec/requests/glossary/create_spec.rb +0 -21
  48. data/spec/requests/glossary/destroy_spec.rb +0 -39
  49. data/spec/requests/glossary/entries_spec.rb +0 -35
  50. data/spec/requests/glossary/find_spec.rb +0 -40
  51. data/spec/requests/glossary/language_pairs_spec.rb +0 -13
  52. data/spec/requests/glossary/list_spec.rb +0 -27
  53. data/spec/requests/languages_spec.rb +0 -41
  54. data/spec/requests/rephrase_spec.rb +13 -139
  55. data/spec/requests/style_rule/create_custom_instruction_spec.rb +30 -0
  56. data/spec/requests/style_rule/create_spec.rb +29 -0
  57. data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +28 -0
  58. data/spec/requests/style_rule/destroy_spec.rb +27 -0
  59. data/spec/requests/style_rule/find_custom_instruction_spec.rb +29 -0
  60. data/spec/requests/style_rule/find_spec.rb +28 -0
  61. data/spec/requests/style_rule/list_spec.rb +27 -0
  62. data/spec/requests/style_rule/update_configured_rules_spec.rb +31 -0
  63. data/spec/requests/style_rule/update_custom_instruction_spec.rb +32 -0
  64. data/spec/requests/style_rule/update_spec.rb +29 -0
  65. data/spec/requests/translate_spec.rb +8 -218
  66. data/spec/requests/translation_memory/list_spec.rb +27 -0
  67. data/spec/requests/usage_spec.rb +0 -16
  68. data/spec/resources/custom_instruction_spec.rb +32 -0
  69. data/spec/resources/style_rule_spec.rb +68 -0
  70. data/spec/resources/translation_memory_spec.rb +35 -0
  71. data/spec/spec_helper.rb +15 -45
  72. data/spec/support/live_mock_server.rb +12 -0
  73. data/spec/support/managed_glossary.rb +17 -0
  74. data/spec/support/managed_style_rule.rb +17 -0
  75. data/spec/support/managed_translation_memory.rb +7 -0
  76. metadata +48 -19
  77. data/spec/fixtures/vcr_cassettes/deepl_document.yml +0 -95
  78. data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +0 -1214
  79. data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +0 -1163
  80. data/spec/fixtures/vcr_cassettes/deepl_languages.yml +0 -54
  81. data/spec/fixtures/vcr_cassettes/deepl_rephrase.yml +0 -87
  82. data/spec/fixtures/vcr_cassettes/deepl_translate.yml +0 -358
  83. data/spec/fixtures/vcr_cassettes/deepl_usage.yml +0 -129
  84. data/spec/fixtures/vcr_cassettes/glossaries.yml +0 -1702
  85. data/spec/fixtures/vcr_cassettes/languages.yml +0 -229
  86. data/spec/fixtures/vcr_cassettes/rephrase_texts.yml +0 -401
  87. data/spec/fixtures/vcr_cassettes/style_rules.yml +0 -92
  88. data/spec/fixtures/vcr_cassettes/translate_texts.yml +0 -10630
  89. data/spec/fixtures/vcr_cassettes/usage.yml +0 -171
@@ -6,8 +6,6 @@
6
6
  require 'spec_helper'
7
7
 
8
8
  describe DeepL::Requests::Rephrase do
9
- subject(:rephrase) { described_class.new(api, text, target_lang, writing_style, tone, options) }
10
-
11
9
  around do |tests|
12
10
  tmp_env = replace_env_preserving_deepl_vars_except_mock_server
13
11
  tests.call
@@ -19,153 +17,29 @@ describe DeepL::Requests::Rephrase do
19
17
  'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.'
20
18
  end
21
19
  let(:target_lang) { 'EN' }
22
- let(:writing_style) { nil }
23
- let(:tone) { nil }
24
- let(:options) { {} }
25
-
26
- describe '#request' do
27
- around do |example|
28
- VCR.use_cassette('rephrase_texts') { example.call }
29
- end
30
-
31
- context 'without a style or tone applied' do
32
- context 'with a string as input' do
33
- it 'returns a valid response as a DeepL Text resource' do
34
- original_length = text.length
35
- response_text = rephrase.request
36
-
37
- expect(response_text).to be_a(DeepL::Resources::Text)
38
- expect(response_text.text.length).not_to eq(original_length)
39
- expect(response_text.detected_source_language.upcase).to eq('EN')
40
- end
41
- end
42
-
43
- context 'with an array of texts as input' do
44
- let(:text) do
45
- [
46
- 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
47
- 'He lay on his armour-like back, and if he lifted his head a little'
48
- ]
49
- end
50
-
51
- it 'returns a valid response as an array of DeepL Text resources' do
52
- response_texts = rephrase.request
53
-
54
- expect(response_texts).to all(be_a(DeepL::Resources::Text))
55
- response_texts.each_with_index do |response_text, index|
56
- expect(response_text.text.length).not_to eq(text[index].length)
57
- expect(response_text.detected_source_language.upcase).to eq('EN')
58
- end
59
- end
60
- end
61
- end
62
-
63
- context 'with a valid tone applied' do
64
- let(:tone) { 'friendly' }
65
-
66
- context 'with a string as input' do
67
- it 'returns a valid response with a string as text input' do
68
- original_length = text.length
69
- response_text = rephrase.request
70
-
71
- expect(response_text).to be_a(DeepL::Resources::Text)
72
- expect(response_text.text.length).not_to eq(original_length)
73
- expect(response_text.detected_source_language.upcase).to eq('EN')
74
- end
75
- end
76
-
77
- context 'with an array of texts as input' do
78
- let(:text) do
79
- [
80
- 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
81
- 'He lay on his armour-like back, and if he lifted his head a little'
82
- ]
83
- end
84
-
85
- it 'returns an array of valid text objects' do
86
- response_texts = rephrase.request
87
-
88
- expect(response_texts).to all(be_a(DeepL::Resources::Text))
89
- response_texts.each_with_index do |response_text, index|
90
- expect(response_text.text.length).not_to eq(text[index].length)
91
- expect(response_text.detected_source_language.upcase).to eq('EN')
92
- end
93
- end
94
- end
95
- end
96
-
97
- context 'with a valid writing style applied' do
98
- let(:writing_style) { 'business' }
99
20
 
100
- context 'with a string as input' do
101
- it 'returns a valid response with a string as text input' do
102
- original_length = text.length
103
- response_text = rephrase.request
104
-
105
- expect(response_text).to be_a(DeepL::Resources::Text)
106
- expect(response_text.text.length).not_to eq(original_length)
107
- expect(response_text.detected_source_language.upcase).to eq('EN')
108
- end
21
+ describe '#initialize' do
22
+ context 'when passing additional headers' do
23
+ it 'merges the headers into the request headers' do
24
+ request = described_class.new(api, text, target_lang, nil, nil, {},
25
+ { 'X-DeepL-Reporting-Tag' => 'my-tag' })
26
+ expect(request.send(:headers)).to include('X-DeepL-Reporting-Tag' => 'my-tag')
109
27
  end
110
28
 
111
- context 'with an array of texts as input' do
112
- let(:text) do
113
- [
114
- 'As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed.',
115
- 'He lay on his armour-like back, and if he lifted his head a little'
116
- ]
117
- end
118
-
119
- it 'returns an array of valid text objects' do
120
- response_texts = rephrase.request
121
-
122
- expect(response_texts).to all(be_a(DeepL::Resources::Text))
123
- response_texts.each_with_index do |response_text, index|
124
- expect(response_text.text.length).not_to eq(text[index].length)
125
- expect(response_text.detected_source_language.upcase).to eq('EN')
126
- end
127
- end
29
+ it 'defaults to no additional headers' do
30
+ request = described_class.new(api, text, target_lang)
31
+ expect(request.send(:headers).keys).to contain_exactly('Authorization', 'User-Agent')
128
32
  end
129
33
  end
130
34
 
131
- context 'with a writing style or tone from the provided constants applied' do
35
+ context 'with a writing style and tone from the provided constants applied' do
132
36
  let(:writing_style) { DeepL::Constants::WritingStyle::BUSINESS }
133
37
  let(:tone) { DeepL::Constants::Tone::FRIENDLY }
134
38
 
135
39
  it 'has the correct writing style and tone applied' do
136
- expect(rephrase.writing_style).to eq('business')
137
- expect(rephrase.tone).to eq('friendly')
138
- end
139
- end
140
-
141
- context 'with an invalid writing style applied' do
142
- let(:writing_style) { 'angry' }
143
-
144
- it 'raises a bad request error' do
145
- expect { rephrase.request }.to raise_error(DeepL::Exceptions::BadRequest)
146
- end
147
- end
148
-
149
- context 'when both writing style and tone are applied' do
150
- let(:writing_style) { 'business' }
151
- let(:tone) { 'friendly' }
152
-
153
- it 'raises a bad request error' do
154
- expect { rephrase.request }.to raise_error(DeepL::Exceptions::BadRequest)
155
- end
156
- end
157
-
158
- context 'when performing a bad request' do
159
- context 'when using an invalid token' do
160
- let(:api) do
161
- api = build_deepl_api
162
- api.configuration.auth_key = 'invalid'
163
- api
164
- end
165
-
166
- it 'raises an unauthorized error' do
167
- expect { rephrase.request }.to raise_error(DeepL::Exceptions::AuthorizationFailed)
168
- end
40
+ request = described_class.new(api, text, target_lang, writing_style, tone)
41
+ expect(request.writing_style).to eq('business')
42
+ expect(request.tone).to eq('friendly')
169
43
  end
170
44
  end
171
45
  end
@@ -0,0 +1,30 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::CreateCustomInstruction do
9
+ subject(:create_instruction) { described_class.new(api, style_id, label, prompt, nil, 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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:label) { 'Test Instruction' }
20
+ let(:prompt) { 'Always use formal language' }
21
+ let(:options) { {} }
22
+
23
+ describe '#initialize' do
24
+ context 'when building a request' do
25
+ it 'creates a request object' do
26
+ expect(create_instruction).to be_a(described_class)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::Create do
9
+ subject(:create) { described_class.new(api, name, language, 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(:name) { 'Test Style Rule' }
19
+ let(:language) { 'en' }
20
+ let(:options) { {} }
21
+
22
+ describe '#initialize' do
23
+ context 'when building a request' do
24
+ it 'creates a request object' do
25
+ expect(create).to be_a(described_class)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::DestroyCustomInstruction do
9
+ subject(:destroy_instruction) { described_class.new(api, style_id, instruction_id) }
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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:instruction_id) { 'test-instruction-id' }
20
+
21
+ describe '#initialize' do
22
+ context 'when building a request' do
23
+ it 'creates a request object' do
24
+ expect(destroy_instruction).to be_a(described_class)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::Destroy do
9
+ subject(:destroy) { described_class.new(api, style_id) }
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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+
20
+ describe '#initialize' do
21
+ context 'when building a request' do
22
+ it 'creates a request object' do
23
+ expect(destroy).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::FindCustomInstruction do
9
+ subject(:find_instruction) { described_class.new(api, style_id, instruction_id, 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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:instruction_id) { 'test-instruction-id' }
20
+ let(:options) { {} }
21
+
22
+ describe '#initialize' do
23
+ context 'when building a request' do
24
+ it 'creates a request object' do
25
+ expect(find_instruction).to be_a(described_class)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::Find do
9
+ subject(:style_rule_find) { described_class.new(api, style_id, 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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:options) { {} }
20
+
21
+ describe '#initialize' do
22
+ context 'when building a request' do
23
+ it 'creates a request object' do
24
+ expect(style_rule_find).to be_a(described_class)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::List do
9
+ subject(:style_rule_list) { 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(style_rule_list).to be_a(described_class)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::UpdateConfiguredRules do
9
+ subject(:update_configured_rules) do
10
+ described_class.new(api, style_id, configured_rules, options)
11
+ end
12
+
13
+ around do |tests|
14
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
15
+ tests.call
16
+ ENV.replace(tmp_env)
17
+ end
18
+
19
+ let(:api) { build_deepl_api }
20
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
21
+ let(:configured_rules) { { 'dates_and_times' => { 'calendar_era' => 'use_bc_and_ad' } } }
22
+ let(:options) { {} }
23
+
24
+ describe '#initialize' do
25
+ context 'when building a request' do
26
+ it 'creates a request object' do
27
+ expect(update_configured_rules).to be_a(described_class)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::UpdateCustomInstruction do
9
+ subject(:update_instruction) do
10
+ described_class.new(api, style_id, instruction_id, label, prompt, nil, {})
11
+ end
12
+
13
+ around do |tests|
14
+ tmp_env = replace_env_preserving_deepl_vars_except_mock_server
15
+ tests.call
16
+ ENV.replace(tmp_env)
17
+ end
18
+
19
+ let(:api) { build_deepl_api }
20
+ let(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
21
+ let(:instruction_id) { 'test-instruction-id' }
22
+ let(:label) { 'Updated Label' }
23
+ let(:prompt) { 'Use casual language' }
24
+
25
+ describe '#initialize' do
26
+ context 'when building a request' do
27
+ it 'creates a request object' do
28
+ expect(update_instruction).to be_a(described_class)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2026 DeepL SE (https://www.deepl.com)
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::StyleRule::Update do
9
+ subject(:update) { described_class.new(api, style_id, name, 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(:style_id) { 'dca2e053-8ae5-45e6-a0d2-881156e7f4e4' }
19
+ let(:name) { 'Updated Name' }
20
+ let(:options) { {} }
21
+
22
+ describe '#initialize' do
23
+ context 'when building a request' do
24
+ it 'creates a request object' do
25
+ expect(update).to be_a(described_class)
26
+ end
27
+ end
28
+ end
29
+ end