spec/srt_spec.lua (4515 bytes)
1 local Srt = require("subread.srt") 2 3 local SAMPLE = table.concat({ 4 "1", 5 "00:00:01,000 --> 00:00:03,500", 6 "It was the best of times,", 7 "", 8 "2", 9 "00:00:03,500 --> 00:00:06,000", 10 "it was the worst of times,", 11 "it was the age of wisdom,", 12 "", 13 "3", 14 "00:00:06,000 --> 00:00:08,000", 15 "\239\188\138 chapter announcement", 16 "", 17 }, "\n") 18 19 describe("SubRead srt", function() 20 it("reads a time line with a comma", function() 21 local start, stop = Srt.parseTimeLine("00:01:02,500 --> 00:01:04,250") 22 assert.near(62.5, start, 1e-6) 23 assert.near(64.25, stop, 1e-6) 24 end) 25 26 it("reads a time line with a full stop", function() 27 local start, stop = Srt.parseTimeLine("01:00:00.000 --> 01:00:01.000") 28 assert.near(3600, start, 1e-6) 29 assert.near(3601, stop, 1e-6) 30 end) 31 32 it("scales the fraction by its length", function() 33 local start = Srt.parseTimeLine("00:00:00,5 --> 00:00:01,0") 34 assert.near(0.5, start, 1e-6) 35 end) 36 37 it("rejects a line that is not a time line", function() 38 assert.is_nil(Srt.parseTimeLine("2")) 39 assert.is_nil(Srt.parseTimeLine("some cue text")) 40 end) 41 42 it("splits CRLF, CR and LF the same way", function() 43 assert.same({ "a", "b", "c" }, Srt.splitLines("a\r\nb\rc")) 44 end) 45 46 it("parses a whole file", function() 47 local cues = Srt.parse(SAMPLE) 48 assert.equals(3, #cues) 49 assert.near(1.0, cues[1].start, 1e-6) 50 assert.near(3.5, cues[1].stop, 1e-6) 51 assert.equals("It was the best of times,", cues[1].text) 52 end) 53 54 it("joins the lines of a cue", function() 55 local cues = Srt.parse(SAMPLE) 56 assert.equals("it was the worst of times,\nit was the age of wisdom,", 57 cues[2].text) 58 assert.equals("it was the worst of times, it was the age of wisdom,", 59 cues[2].norm) 60 end) 61 62 it("marks the cue that has no place in the book", function() 63 local cues = Srt.parse(SAMPLE) 64 assert.is_false(cues[1].no_place) 65 assert.is_true(cues[3].no_place) 66 end) 67 68 it("accepts a byte order mark and CRLF", function() 69 local data = "\239\187\191" .. SAMPLE:gsub("\n", "\r\n") 70 assert.equals(3, #Srt.parse(data)) 71 end) 72 73 it("skips a block that has no time line", function() 74 local data = "header junk\n\n99\nnot a time\n\n" .. SAMPLE 75 assert.equals(3, #Srt.parse(data)) 76 end) 77 78 it("accepts a missing cue number", function() 79 local data = "00:00:01,000 --> 00:00:02,000\nfirst\n\n" .. 80 "00:00:02,000 --> 00:00:03,000\nsecond\n" 81 local cues = Srt.parse(data) 82 assert.equals(2, #cues) 83 assert.equals("second", cues[2].text) 84 end) 85 86 it("ends a cue on the next time line when a blank line is missing", function() 87 local data = "00:00:01,000 --> 00:00:02,000\nfirst\n" .. 88 "00:00:02,000 --> 00:00:03,000\nsecond\n" 89 local cues = Srt.parse(data) 90 assert.equals(2, #cues) 91 assert.equals("first", cues[1].text) 92 end) 93 94 it("drops a cue with no text", function() 95 local data = "00:00:01,000 --> 00:00:02,000\n\n" .. 96 "00:00:02,000 --> 00:00:03,000\nkept\n" 97 local cues = Srt.parse(data) 98 assert.equals(1, #cues) 99 assert.equals("kept", cues[1].text) 100 end) 101 102 it("sorts the cues by start time", function() 103 local data = "00:00:09,000 --> 00:00:10,000\nlate\n\n" .. 104 "00:00:01,000 --> 00:00:02,000\nearly\n" 105 local cues = Srt.parse(data) 106 assert.equals("early", cues[1].text) 107 assert.equals("late", cues[2].text) 108 end) 109 110 it("returns an empty list for empty input", function() 111 assert.same({}, Srt.parse("")) 112 assert.same({}, Srt.parse(nil)) 113 end) 114 115 it("keeps the start times in order for any input", function() 116 local blocks = {} 117 local seed = 7 118 for i = 1, 60 do 119 seed = (seed * 1103515245 + 12345) % 2147483648 120 local start = seed % 1000 121 blocks[#blocks + 1] = string.format( 122 "%d\n00:00:%02d,%03d --> 00:00:%02d,%03d\ncue %d\n", 123 i, start % 60, start % 1000, (start + 2) % 60, start % 1000, i) 124 end 125 local cues = Srt.parse(table.concat(blocks, "\n")) 126 assert.equals(60, #cues) 127 for i = 2, #cues do 128 assert.is_true(cues[i - 1].start <= cues[i].start) 129 end 130 end) 131 end)