youtube-transcript-rb 0.1.0 → 0.2.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.
Potentially problematic release.
This version of youtube-transcript-rb might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +42 -42
- data/lib/youtube-transcript-rb.rb +3 -0
- data/lib/youtube_rb/transcript/api.rb +148 -0
- data/lib/youtube_rb/transcript/errors.rb +215 -0
- data/lib/youtube_rb/transcript/formatters.rb +267 -0
- data/lib/youtube_rb/transcript/settings.rb +26 -0
- data/lib/youtube_rb/transcript/transcript.rb +237 -0
- data/lib/youtube_rb/transcript/transcript_list.rb +168 -0
- data/lib/youtube_rb/transcript/transcript_list_fetcher.rb +223 -0
- data/lib/youtube_rb/transcript/transcript_parser.rb +81 -0
- data/lib/{youtube/transcript/rb → youtube_rb/transcript}/version.rb +2 -4
- data/lib/youtube_rb/transcript.rb +35 -0
- data/sig/youtube_rb/transcript.rbs +6 -0
- data/spec/api_spec.rb +20 -20
- data/spec/errors_spec.rb +39 -39
- data/spec/formatters_spec.rb +36 -36
- data/spec/integration_spec.rb +32 -32
- data/spec/settings_spec.rb +16 -16
- data/spec/spec_helper.rb +1 -1
- data/spec/transcript_list_fetcher_spec.rb +27 -27
- data/spec/transcript_list_spec.rb +6 -6
- data/spec/transcript_parser_spec.rb +3 -3
- data/spec/transcript_spec.rb +16 -16
- metadata +13 -12
- data/lib/youtube/transcript/rb/api.rb +0 -150
- data/lib/youtube/transcript/rb/errors.rb +0 -217
- data/lib/youtube/transcript/rb/formatters.rb +0 -269
- data/lib/youtube/transcript/rb/settings.rb +0 -28
- data/lib/youtube/transcript/rb/transcript.rb +0 -239
- data/lib/youtube/transcript/rb/transcript_list.rb +0 -170
- data/lib/youtube/transcript/rb/transcript_list_fetcher.rb +0 -225
- data/lib/youtube/transcript/rb/transcript_parser.rb +0 -83
- data/lib/youtube/transcript/rb.rb +0 -37
- data/sig/youtube/transcript/rb.rbs +0 -8
data/spec/errors_spec.rb
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
|
-
require "
|
|
4
|
+
require "youtube_rb/transcript"
|
|
5
5
|
|
|
6
|
-
RSpec.describe
|
|
6
|
+
RSpec.describe YoutubeRb::Transcript do
|
|
7
7
|
describe "Error hierarchy" do
|
|
8
8
|
it "has Error as the base class" do
|
|
9
|
-
expect(
|
|
9
|
+
expect(YoutubeRb::Transcript::Error).to be < StandardError
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it "has CouldNotRetrieveTranscript inheriting from Error" do
|
|
13
|
-
expect(
|
|
13
|
+
expect(YoutubeRb::Transcript::CouldNotRetrieveTranscript).to be < YoutubeRb::Transcript::Error
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
describe "error classes inherit from CouldNotRetrieveTranscript" do
|
|
17
17
|
[
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
YoutubeRb::Transcript::YouTubeDataUnparsable,
|
|
19
|
+
YoutubeRb::Transcript::YouTubeRequestFailed,
|
|
20
|
+
YoutubeRb::Transcript::VideoUnplayable,
|
|
21
|
+
YoutubeRb::Transcript::VideoUnavailable,
|
|
22
|
+
YoutubeRb::Transcript::InvalidVideoId,
|
|
23
|
+
YoutubeRb::Transcript::RequestBlocked,
|
|
24
|
+
YoutubeRb::Transcript::IpBlocked,
|
|
25
|
+
YoutubeRb::Transcript::TooManyRequests,
|
|
26
|
+
YoutubeRb::Transcript::TranscriptsDisabled,
|
|
27
|
+
YoutubeRb::Transcript::AgeRestricted,
|
|
28
|
+
YoutubeRb::Transcript::NotTranslatable,
|
|
29
|
+
YoutubeRb::Transcript::TranslationLanguageNotAvailable,
|
|
30
|
+
YoutubeRb::Transcript::FailedToCreateConsentCookie,
|
|
31
|
+
YoutubeRb::Transcript::NoTranscriptFound,
|
|
32
|
+
YoutubeRb::Transcript::NoTranscriptAvailable,
|
|
33
|
+
YoutubeRb::Transcript::PoTokenRequired
|
|
34
34
|
].each do |error_class|
|
|
35
35
|
it "#{error_class} inherits from CouldNotRetrieveTranscript" do
|
|
36
|
-
expect(error_class).to be <
|
|
36
|
+
expect(error_class).to be < YoutubeRb::Transcript::CouldNotRetrieveTranscript
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
describe
|
|
42
|
+
describe YoutubeRb::Transcript::CouldNotRetrieveTranscript do
|
|
43
43
|
let(:video_id) { "test_video_123" }
|
|
44
44
|
|
|
45
45
|
it "stores the video_id" do
|
|
46
46
|
# Using a subclass since CouldNotRetrieveTranscript needs CAUSE_MESSAGE
|
|
47
|
-
error =
|
|
47
|
+
error = YoutubeRb::Transcript::VideoUnavailable.new(video_id)
|
|
48
48
|
expect(error.video_id).to eq(video_id)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
it "includes video URL in error message" do
|
|
52
|
-
error =
|
|
52
|
+
error = YoutubeRb::Transcript::VideoUnavailable.new(video_id)
|
|
53
53
|
expect(error.message).to include("https://www.youtube.com/watch?v=#{video_id}")
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
it "includes cause message in error message" do
|
|
57
|
-
error =
|
|
57
|
+
error = YoutubeRb::Transcript::VideoUnavailable.new(video_id)
|
|
58
58
|
expect(error.message).to include("The video is no longer available")
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
describe
|
|
62
|
+
describe YoutubeRb::Transcript::VideoUnavailable do
|
|
63
63
|
let(:video_id) { "unavailable_video" }
|
|
64
64
|
let(:error) { described_class.new(video_id) }
|
|
65
65
|
|
|
@@ -68,7 +68,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
describe
|
|
71
|
+
describe YoutubeRb::Transcript::TranscriptsDisabled do
|
|
72
72
|
let(:video_id) { "disabled_video" }
|
|
73
73
|
let(:error) { described_class.new(video_id) }
|
|
74
74
|
|
|
@@ -77,7 +77,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
describe
|
|
80
|
+
describe YoutubeRb::Transcript::TooManyRequests do
|
|
81
81
|
let(:video_id) { "rate_limited" }
|
|
82
82
|
let(:error) { described_class.new(video_id) }
|
|
83
83
|
|
|
@@ -86,7 +86,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
describe
|
|
89
|
+
describe YoutubeRb::Transcript::PoTokenRequired do
|
|
90
90
|
let(:video_id) { "po_token_video" }
|
|
91
91
|
let(:error) { described_class.new(video_id) }
|
|
92
92
|
|
|
@@ -95,7 +95,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
describe
|
|
98
|
+
describe YoutubeRb::Transcript::InvalidVideoId do
|
|
99
99
|
let(:video_id) { "https://www.youtube.com/watch?v=1234" }
|
|
100
100
|
let(:error) { described_class.new(video_id) }
|
|
101
101
|
|
|
@@ -105,7 +105,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
describe
|
|
108
|
+
describe YoutubeRb::Transcript::YouTubeRequestFailed do
|
|
109
109
|
let(:video_id) { "failed_request" }
|
|
110
110
|
let(:http_error) { StandardError.new("Connection refused") }
|
|
111
111
|
let(:error) { described_class.new(video_id, http_error) }
|
|
@@ -119,7 +119,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
describe
|
|
122
|
+
describe YoutubeRb::Transcript::VideoUnplayable do
|
|
123
123
|
let(:video_id) { "unplayable_video" }
|
|
124
124
|
|
|
125
125
|
context "with reason only" do
|
|
@@ -157,7 +157,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
157
157
|
end
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
-
describe
|
|
160
|
+
describe YoutubeRb::Transcript::NoTranscriptFound do
|
|
161
161
|
let(:video_id) { "no_transcript" }
|
|
162
162
|
let(:requested_languages) { ["ko", "ja"] }
|
|
163
163
|
let(:transcript_data) { double("TranscriptList", to_s: "Available: en, es") }
|
|
@@ -181,7 +181,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
describe
|
|
184
|
+
describe YoutubeRb::Transcript::RequestBlocked do
|
|
185
185
|
let(:video_id) { "blocked_video" }
|
|
186
186
|
let(:error) { described_class.new(video_id) }
|
|
187
187
|
|
|
@@ -194,12 +194,12 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
describe
|
|
197
|
+
describe YoutubeRb::Transcript::IpBlocked do
|
|
198
198
|
let(:video_id) { "ip_blocked" }
|
|
199
199
|
let(:error) { described_class.new(video_id) }
|
|
200
200
|
|
|
201
201
|
it "inherits from RequestBlocked" do
|
|
202
|
-
expect(described_class).to be <
|
|
202
|
+
expect(described_class).to be < YoutubeRb::Transcript::RequestBlocked
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
it "mentions IP or proxies as workaround" do
|
|
@@ -207,7 +207,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
207
207
|
end
|
|
208
208
|
end
|
|
209
209
|
|
|
210
|
-
describe
|
|
210
|
+
describe YoutubeRb::Transcript::AgeRestricted do
|
|
211
211
|
let(:video_id) { "age_restricted" }
|
|
212
212
|
let(:error) { described_class.new(video_id) }
|
|
213
213
|
|
|
@@ -220,7 +220,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
220
220
|
end
|
|
221
221
|
end
|
|
222
222
|
|
|
223
|
-
describe
|
|
223
|
+
describe YoutubeRb::Transcript::NotTranslatable do
|
|
224
224
|
let(:video_id) { "not_translatable" }
|
|
225
225
|
let(:error) { described_class.new(video_id) }
|
|
226
226
|
|
|
@@ -229,7 +229,7 @@ RSpec.describe Youtube::Transcript::Rb do
|
|
|
229
229
|
end
|
|
230
230
|
end
|
|
231
231
|
|
|
232
|
-
describe
|
|
232
|
+
describe YoutubeRb::Transcript::TranslationLanguageNotAvailable do
|
|
233
233
|
let(:video_id) { "translation_unavailable" }
|
|
234
234
|
let(:error) { described_class.new(video_id) }
|
|
235
235
|
|
data/spec/formatters_spec.rb
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
RSpec.describe
|
|
5
|
+
RSpec.describe YoutubeRb::Transcript::Formatters do
|
|
6
6
|
# Helper to create a FetchedTranscript with snippets
|
|
7
7
|
def create_transcript(video_id: "test123", language: "English", language_code: "en", is_generated: false, snippets: nil)
|
|
8
8
|
snippets ||= [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Hello world", start: 0.0, duration: 2.5),
|
|
10
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "This is a test", start: 2.5, duration: 3.0),
|
|
11
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Thank you", start: 5.5, duration: 2.0)
|
|
12
12
|
]
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
YoutubeRb::Transcript::FetchedTranscript.new(
|
|
15
15
|
video_id: video_id,
|
|
16
16
|
language: language,
|
|
17
17
|
language_code: language_code,
|
|
@@ -24,7 +24,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
24
24
|
let(:transcript2) { create_transcript(video_id: "video2", language_code: "es", language: "Spanish") }
|
|
25
25
|
let(:transcripts) { [transcript, transcript2] }
|
|
26
26
|
|
|
27
|
-
describe
|
|
27
|
+
describe YoutubeRb::Transcript::Formatters::Formatter do
|
|
28
28
|
let(:formatter) { described_class.new }
|
|
29
29
|
|
|
30
30
|
describe "#format_transcript" do
|
|
@@ -40,7 +40,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
describe
|
|
43
|
+
describe YoutubeRb::Transcript::Formatters::JSONFormatter do
|
|
44
44
|
let(:formatter) { described_class.new }
|
|
45
45
|
|
|
46
46
|
describe "#format_transcript" do
|
|
@@ -88,7 +88,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
describe
|
|
91
|
+
describe YoutubeRb::Transcript::Formatters::TextFormatter do
|
|
92
92
|
let(:formatter) { described_class.new }
|
|
93
93
|
|
|
94
94
|
describe "#format_transcript" do
|
|
@@ -118,7 +118,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
describe
|
|
121
|
+
describe YoutubeRb::Transcript::Formatters::PrettyPrintFormatter do
|
|
122
122
|
let(:formatter) { described_class.new }
|
|
123
123
|
|
|
124
124
|
describe "#format_transcript" do
|
|
@@ -156,7 +156,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
156
156
|
end
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
-
describe
|
|
159
|
+
describe YoutubeRb::Transcript::Formatters::SRTFormatter do
|
|
160
160
|
let(:formatter) { described_class.new }
|
|
161
161
|
|
|
162
162
|
describe "#format_transcript" do
|
|
@@ -205,7 +205,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
205
205
|
describe "timestamp edge cases" do
|
|
206
206
|
it "handles hours correctly" do
|
|
207
207
|
snippets = [
|
|
208
|
-
|
|
208
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Long video", start: 3661.5, duration: 2.0)
|
|
209
209
|
]
|
|
210
210
|
transcript = create_transcript(snippets: snippets)
|
|
211
211
|
result = formatter.format_transcript(transcript)
|
|
@@ -215,8 +215,8 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
215
215
|
|
|
216
216
|
it "handles overlapping timestamps" do
|
|
217
217
|
snippets = [
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "First", start: 0.0, duration: 5.0),
|
|
219
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Second", start: 2.0, duration: 3.0)
|
|
220
220
|
]
|
|
221
221
|
transcript = create_transcript(snippets: snippets)
|
|
222
222
|
result = formatter.format_transcript(transcript)
|
|
@@ -227,7 +227,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
227
227
|
end
|
|
228
228
|
end
|
|
229
229
|
|
|
230
|
-
describe
|
|
230
|
+
describe YoutubeRb::Transcript::Formatters::WebVTTFormatter do
|
|
231
231
|
let(:formatter) { described_class.new }
|
|
232
232
|
|
|
233
233
|
describe "#format_transcript" do
|
|
@@ -272,7 +272,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
272
272
|
describe "timestamp edge cases" do
|
|
273
273
|
it "handles hours correctly" do
|
|
274
274
|
snippets = [
|
|
275
|
-
|
|
275
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Long video", start: 3661.5, duration: 2.0)
|
|
276
276
|
]
|
|
277
277
|
transcript = create_transcript(snippets: snippets)
|
|
278
278
|
result = formatter.format_transcript(transcript)
|
|
@@ -282,55 +282,55 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
282
282
|
end
|
|
283
283
|
end
|
|
284
284
|
|
|
285
|
-
describe
|
|
285
|
+
describe YoutubeRb::Transcript::Formatters::FormatterLoader do
|
|
286
286
|
let(:loader) { described_class.new }
|
|
287
287
|
|
|
288
288
|
describe "#load" do
|
|
289
289
|
it "loads JSONFormatter for 'json'" do
|
|
290
290
|
formatter = loader.load("json")
|
|
291
|
-
expect(formatter).to be_a(
|
|
291
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::JSONFormatter)
|
|
292
292
|
end
|
|
293
293
|
|
|
294
294
|
it "loads TextFormatter for 'text'" do
|
|
295
295
|
formatter = loader.load("text")
|
|
296
|
-
expect(formatter).to be_a(
|
|
296
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::TextFormatter)
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
it "loads PrettyPrintFormatter for 'pretty'" do
|
|
300
300
|
formatter = loader.load("pretty")
|
|
301
|
-
expect(formatter).to be_a(
|
|
301
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::PrettyPrintFormatter)
|
|
302
302
|
end
|
|
303
303
|
|
|
304
304
|
it "loads SRTFormatter for 'srt'" do
|
|
305
305
|
formatter = loader.load("srt")
|
|
306
|
-
expect(formatter).to be_a(
|
|
306
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::SRTFormatter)
|
|
307
307
|
end
|
|
308
308
|
|
|
309
309
|
it "loads WebVTTFormatter for 'webvtt'" do
|
|
310
310
|
formatter = loader.load("webvtt")
|
|
311
|
-
expect(formatter).to be_a(
|
|
311
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::WebVTTFormatter)
|
|
312
312
|
end
|
|
313
313
|
|
|
314
314
|
it "defaults to PrettyPrintFormatter" do
|
|
315
315
|
formatter = loader.load
|
|
316
|
-
expect(formatter).to be_a(
|
|
316
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::PrettyPrintFormatter)
|
|
317
317
|
end
|
|
318
318
|
|
|
319
319
|
it "accepts symbol as formatter type" do
|
|
320
320
|
formatter = loader.load(:json)
|
|
321
|
-
expect(formatter).to be_a(
|
|
321
|
+
expect(formatter).to be_a(YoutubeRb::Transcript::Formatters::JSONFormatter)
|
|
322
322
|
end
|
|
323
323
|
|
|
324
324
|
it "raises UnknownFormatterType for invalid type" do
|
|
325
325
|
expect { loader.load("invalid") }.to raise_error(
|
|
326
|
-
|
|
326
|
+
YoutubeRb::Transcript::Formatters::FormatterLoader::UnknownFormatterType
|
|
327
327
|
)
|
|
328
328
|
end
|
|
329
329
|
|
|
330
330
|
it "includes available formats in error message" do
|
|
331
331
|
begin
|
|
332
332
|
loader.load("invalid")
|
|
333
|
-
rescue
|
|
333
|
+
rescue YoutubeRb::Transcript::Formatters::FormatterLoader::UnknownFormatterType => e
|
|
334
334
|
expect(e.message).to include("json")
|
|
335
335
|
expect(e.message).to include("text")
|
|
336
336
|
expect(e.message).to include("srt")
|
|
@@ -352,7 +352,7 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
352
352
|
end
|
|
353
353
|
|
|
354
354
|
describe "integration tests" do
|
|
355
|
-
let(:loader) {
|
|
355
|
+
let(:loader) { YoutubeRb::Transcript::Formatters::FormatterLoader.new }
|
|
356
356
|
|
|
357
357
|
it "can format transcript with each formatter type" do
|
|
358
358
|
%w[json text pretty srt webvtt].each do |type|
|
|
@@ -378,25 +378,25 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
378
378
|
let(:empty_transcript) { create_transcript(snippets: empty_snippets) }
|
|
379
379
|
|
|
380
380
|
it "JSONFormatter handles empty transcript" do
|
|
381
|
-
formatter =
|
|
381
|
+
formatter = YoutubeRb::Transcript::Formatters::JSONFormatter.new
|
|
382
382
|
result = formatter.format_transcript(empty_transcript)
|
|
383
383
|
expect(JSON.parse(result)).to eq([])
|
|
384
384
|
end
|
|
385
385
|
|
|
386
386
|
it "TextFormatter handles empty transcript" do
|
|
387
|
-
formatter =
|
|
387
|
+
formatter = YoutubeRb::Transcript::Formatters::TextFormatter.new
|
|
388
388
|
result = formatter.format_transcript(empty_transcript)
|
|
389
389
|
expect(result).to eq("")
|
|
390
390
|
end
|
|
391
391
|
|
|
392
392
|
it "SRTFormatter handles empty transcript" do
|
|
393
|
-
formatter =
|
|
393
|
+
formatter = YoutubeRb::Transcript::Formatters::SRTFormatter.new
|
|
394
394
|
result = formatter.format_transcript(empty_transcript)
|
|
395
395
|
expect(result).to eq("\n")
|
|
396
396
|
end
|
|
397
397
|
|
|
398
398
|
it "WebVTTFormatter handles empty transcript" do
|
|
399
|
-
formatter =
|
|
399
|
+
formatter = YoutubeRb::Transcript::Formatters::WebVTTFormatter.new
|
|
400
400
|
result = formatter.format_transcript(empty_transcript)
|
|
401
401
|
expect(result).to eq("WEBVTT\n\n\n")
|
|
402
402
|
end
|
|
@@ -405,15 +405,15 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
405
405
|
describe "special character handling" do
|
|
406
406
|
let(:special_snippets) do
|
|
407
407
|
[
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
408
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Hello <b>world</b>", start: 0.0, duration: 2.0),
|
|
409
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: 'Quote: "test"', start: 2.0, duration: 2.0),
|
|
410
|
+
YoutubeRb::Transcript::TranscriptSnippet.new(text: "Line1\nLine2", start: 4.0, duration: 2.0)
|
|
411
411
|
]
|
|
412
412
|
end
|
|
413
413
|
let(:special_transcript) { create_transcript(snippets: special_snippets) }
|
|
414
414
|
|
|
415
415
|
it "JSONFormatter escapes special characters" do
|
|
416
|
-
formatter =
|
|
416
|
+
formatter = YoutubeRb::Transcript::Formatters::JSONFormatter.new
|
|
417
417
|
result = formatter.format_transcript(special_transcript)
|
|
418
418
|
parsed = JSON.parse(result)
|
|
419
419
|
expect(parsed[0]["text"]).to eq("Hello <b>world</b>")
|
|
@@ -421,14 +421,14 @@ RSpec.describe Youtube::Transcript::Rb::Formatters do
|
|
|
421
421
|
end
|
|
422
422
|
|
|
423
423
|
it "TextFormatter preserves special characters" do
|
|
424
|
-
formatter =
|
|
424
|
+
formatter = YoutubeRb::Transcript::Formatters::TextFormatter.new
|
|
425
425
|
result = formatter.format_transcript(special_transcript)
|
|
426
426
|
expect(result).to include("<b>world</b>")
|
|
427
427
|
expect(result).to include('"test"')
|
|
428
428
|
end
|
|
429
429
|
|
|
430
430
|
it "SRTFormatter preserves HTML tags in text" do
|
|
431
|
-
formatter =
|
|
431
|
+
formatter = YoutubeRb::Transcript::Formatters::SRTFormatter.new
|
|
432
432
|
result = formatter.format_transcript(special_transcript)
|
|
433
433
|
expect(result).to include("<b>world</b>")
|
|
434
434
|
end
|