添加测试用例

This commit is contained in:
Hami Lemon 2022-03-29 11:16:04 +08:00
parent a4ea096e3d
commit 3e2af31678
9 changed files with 335 additions and 130 deletions

22
cloudlyric_test.go Normal file
View file

@ -0,0 +1,22 @@
package lrc2srt
import (
"fmt"
"testing"
)
func TestGet163Lyric(t *testing.T) {
tests := []struct {
input string
}{
{"1423123512"},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("id=%s", tt.input), func(t *testing.T) {
l, lt := Get163Lyric(tt.input)
if l == "" || lt == "" {
t.Errorf("get cloud lyric faild, id = %s", tt.input)
}
})
}
}

View file

@ -12,163 +12,163 @@ const (
// Node 链表中的一个结点
type Node[E any] struct {
Element E //保存的内容
Prev *Node[E] //前一个结点
Next *Node[E] //后一个结点
element E //保存的内容
prev *Node[E] //前一个结点
next *Node[E] //后一个结点
}
// Clone 克隆Node,返回的Node的Prev和Next均为nil,Element保持不变
func (n *Node[E]) Clone() *Node[E] {
node := &Node[E]{
Element: n.Element,
Prev: nil,
Next: nil,
element: n.element,
prev: nil,
next: nil,
}
return node
}
// LinkedList 链表,实现了List
type LinkedList[E any] struct {
Len uint //链表中元素个数
First *Node[E] //头指针
Last *Node[E] //尾指针
len uint //链表中元素个数
first *Node[E] //头指针
last *Node[E] //尾指针
}
// NewLinkedList 创建一个链表,
//列表的最大容量为uint类型的最大值
func NewLinkedList[E any]() *LinkedList[E] {
return &LinkedList[E]{
Len: 0,
First: nil,
Last: nil,
len: 0,
first: nil,
last: nil,
}
}
func (l *LinkedList[E]) Size() uint {
return l.Len
return l.len
}
func (l *LinkedList[E]) IsEmpty() bool {
return l.Len == 0
return l.len == 0
}
func (l *LinkedList[E]) IsNotEmpty() bool {
return l.Len != 0
return l.len != 0
}
func (l *LinkedList[E]) Append(element E) bool {
//超出最大值无法添加
if l.Len == CAPACITY {
if l.len == CAPACITY {
return false
}
node := &Node[E]{
Element: element,
Prev: nil,
Next: nil,
element: element,
prev: nil,
next: nil,
}
//链表为空,头指针指向该结点
if l.First == nil {
l.First = node
l.Last = node
if l.first == nil {
l.first = node
l.last = node
} else {
//链表不为空,添加到尾部
node.Prev = l.Last
l.Last.Next = node
l.Last = node
node.prev = l.last
l.last.next = node
l.last = node
}
l.Len++
l.len++
return true
}
func (l *LinkedList[E]) Insert(index uint, element E) bool {
//当前size已经达到最大值或者索引越界
if l.Len == CAPACITY || index > l.Len {
if l.len == CAPACITY || index > l.len {
return false
}
node := &Node[E]{
Element: element,
Prev: nil,
Next: nil,
element: element,
prev: nil,
next: nil,
}
//插入头部
if index == 0 {
if l.First == nil {
if l.first == nil {
//链表为空
l.First = node
l.Last = node
l.first = node
l.last = node
} else {
//链表不为空
node.Next = l.First
l.First.Prev = node
l.First = node
node.next = l.first
l.first.prev = node
l.first = node
}
} else if index == l.Len {
} else if index == l.len {
//插入尾部
l.Last.Next = node
node.Prev = l.Last
l.Last = node
l.last.next = node
node.prev = l.last
l.last = node
} else {
var prev *Node[E]
head := l.First
head := l.first
for i := ZERO; i < index; i++ {
prev = head
head = head.Next
head = head.next
}
node.Next = head
node.Prev = prev
prev.Next = node
head.Prev = node
node.next = head
node.prev = prev
prev.next = node
head.prev = node
}
l.Len++
l.len++
return true
}
func (l *LinkedList[E]) Remove(index uint) bool {
if index >= l.Len {
if index >= l.len {
return false
}
head := l.First
head := l.first
var prev *Node[E]
for i := ZERO; i < index; i++ {
prev = head
head = head.Next
head = head.next
}
//删除第一个结点
if head == l.First {
l.First.Next = nil
l.First = head.Next
} else if head == l.Last {
if head == l.first {
l.first.next = nil
l.first = head.next
} else if head == l.last {
//删除最后一个结点
l.Last = prev
l.Last.Next = nil
l.last = prev
l.last.next = nil
} else {
prev.Next = head.Next
head.Next.Prev = prev
prev.next = head.next
head.next.prev = prev
}
l.Len--
l.len--
return true
}
func (l *LinkedList[E]) Get(index uint) *E {
if index >= l.Len {
if index >= l.len {
return nil
}
node := l.First
node := l.first
for i := ZERO; i < index; i++ {
node = node.Next
node = node.next
}
return &(node.Element)
return &(node.element)
}
func (l *LinkedList[E]) Set(index uint, element E) bool {
if index >= l.Len {
if index >= l.len {
return false
}
node := l.First
node := l.first
for i := ZERO; i < index; i++ {
node = node.Next
node = node.next
}
node.Element = element
node.element = element
return true
}
@ -182,57 +182,57 @@ func (l *LinkedList[E]) PushFront(element E) bool {
func (l *LinkedList[E]) PopBack() *E {
//链表为空
if l.Len == 0 {
if l.len == 0 {
return nil
}
node := l.Last
node := l.last
//只有一个元素
if l.Len == 1 {
l.Last = nil
l.First = nil
if l.len == 1 {
l.last = nil
l.first = nil
} else {
l.Last = node.Prev
l.Last.Next = nil
l.last = node.prev
l.last.next = nil
}
l.Len--
return &(node.Element)
l.len--
return &(node.element)
}
func (l *LinkedList[E]) PopFront() *E {
if l.Len == 0 {
if l.len == 0 {
return nil
}
node := l.First
if l.Len == 1 {
l.First = nil
l.Last = nil
node := l.first
if l.len == 1 {
l.first = nil
l.last = nil
} else {
l.First = node.Next
l.First.Prev = nil
l.first = node.next
l.first.prev = nil
}
l.Len--
return &(node.Element)
l.len--
return &(node.element)
}
func (l *LinkedList[E]) PullBack() *E {
if l.Len == 0 {
if l.len == 0 {
return nil
}
return &(l.Last.Element)
return &(l.last.element)
}
func (l *LinkedList[E]) PullFront() *E {
if l.Len == 0 {
if l.len == 0 {
return nil
}
return &(l.First.Element)
return &(l.first.element)
}
// Iterator 获取该链表的迭代器
func (l *LinkedList[E]) Iterator() Iterator[E] {
return &LinkedListIterator[E]{
reverse: false,
next: l.First,
next: l.first,
}
}
@ -240,7 +240,7 @@ func (l *LinkedList[E]) Iterator() Iterator[E] {
func (l *LinkedList[E]) ReverseIterator() Iterator[E] {
return &LinkedListIterator[E]{
reverse: true,
next: l.Last,
next: l.last,
}
}
@ -260,9 +260,9 @@ func (l *LinkedListIterator[E]) Next() E {
panic("iterator is empty.")
}
if l.reverse {
l.next = e.Prev
l.next = e.prev
} else {
l.next = e.Next
l.next = e.next
}
return e.Element
return e.element
}

View file

@ -7,8 +7,8 @@ import (
)
func checkListElement[T comparable](list *LinkedList[T], items []T, t *testing.T) {
if list.Len != uint(len(items)) {
t.Errorf("list Len= %d, items Len = %d.", list.Len, len(items))
if list.len != uint(len(items)) {
t.Errorf("list len= %d, items len = %d.", list.len, len(items))
}
i := 0
for it := list.Iterator(); it.Has(); {
@ -153,7 +153,7 @@ func TestLinkedList_Remove(t *testing.T) {
values []int
}{
{"empty list", 0, 0, false, nil},
{"index gather than Len", 0, 1, false, nil},
{"index gather than len", 0, 1, false, nil},
{"1 value list:delete index 0", 1, 0, true, []int{}},
{"10 value list:delete index 0", 10, 0, true, []int{1, 2, 3, 4, 5, 6, 7, 8, 9}},
{"10 value list:delete index 5", 10, 5, true, []int{0, 1, 2, 3, 4, 6, 7, 8, 9}},

2
lrc.go
View file

@ -122,7 +122,7 @@ func SplitLyric(src []string) *LRCNode {
}
lrcNode := &LRCNode{
time: time2Millisecond(minute, second, millisecond),
content: content,
content: strings.TrimSpace(content), //去掉前后的空格
}
return lrcNode
}

68
lrc_test.go Normal file
View file

@ -0,0 +1,68 @@
package lrc2srt
import (
"reflect"
"testing"
)
func TestParseLRC(t *testing.T) {
lrc := `[ar:artist]
[al:album]
[ti:title]
[by:author]
[00:24.83] 天涯的尽头 有谁去过
[00:28.53] 山水优雅着 保持沉默
[00:32.20] 我们的青春却热闹很多
[00:35.38] 而且是谁都 不准偷
`
content := []string{
"天涯的尽头 有谁去过", "山水优雅着 保持沉默", "我们的青春却热闹很多", "而且是谁都 不准偷",
}
l := ParseLRC(lrc)
if l.Artist != "artist" {
t.Errorf("LRC Artist=%s, want=%s", l.Artist, "artist")
}
if l.Album != "album" {
t.Errorf("LRC Album=%s, want=%s", l.Album, "album")
}
if l.Title != "title" {
t.Errorf("LRC Title=%s, want=%s", l.Title, "title")
}
if l.Author != "author" {
t.Errorf("LRC Author=%s, want=%s", l.Author, "author")
}
lrcList := l.LrcList
index := 0
for it := lrcList.Iterator(); it.Has(); {
c := it.Next().content
if c != content[index] {
t.Errorf("LRCNode Content=%s, want=%s", c, content[index])
}
index++
}
}
func TestSplitLyric(t *testing.T) {
tests := []struct {
name string
args []string
want *LRCNode
}{
{"lrc:[00:49.88] 有一些话想 对你说", []string{"00", "49", ".88", " 有一些话想 对你说"},
&LRCNode{time: time2Millisecond(0, 49, 880), content: "有一些话想 对你说"}},
{"lrc:[00:49:88] 有一些话想 对你说", []string{"00", "49", ":88", " 有一些话想 对你说"},
&LRCNode{time: time2Millisecond(0, 49, 880), content: "有一些话想 对你说"}},
{"lrc:[00:49.880] 有一些话想 对你说", []string{"00", "49", ".880", " 有一些话想 对你说"},
&LRCNode{time: time2Millisecond(0, 49, 880), content: "有一些话想 对你说"}},
{"lrc:[00:49] 有一些话想 对你说", []string{"00", "49", " 有一些话想 对你说"},
&LRCNode{time: time2Millisecond(0, 49, 0), content: "有一些话想 对你说"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := SplitLyric(tt.args); !reflect.DeepEqual(got, tt.want) {
t.Errorf("SplitLyric() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
@ -22,7 +23,7 @@ type Option struct {
const (
// VERSION 当前版本
VERSION = `"0.2.3" (build 2022.03.28)`
VERSION = `"0.2.4" (build 2022.03.29)`
)
var (
@ -31,13 +32,14 @@ var (
func main() {
//TODO 支持转ass文件
//TODO 酷狗的krc支持逐字更利于打轴 https://shansing.com/read/392/
args, err := flags.Parse(&opt)
if err != nil {
os.Exit(0)
}
//显示版本信息
if opt.Version {
fmt.Printf("LrcToSrt(lts) version %s\n", VERSION)
fmt.Printf("LrcToSrt(lts) version: %s\n", VERSION)
return
}
//获取保存的文件名
@ -121,4 +123,13 @@ func main() {
fmt.Println("出现错误,保存失败")
panic(err.Error())
}
//如果是相对路径,则获取其对应的绝对路径
if !filepath.IsAbs(name) {
//如果是相对路径,父目录即是当前运行路径
dir, er := os.Getwd()
if er == nil {
name = dir + name
}
}
fmt.Printf("保存结果为:%s\n", name)
}

22
qqlyric_test.go Normal file
View file

@ -0,0 +1,22 @@
package lrc2srt
import (
"fmt"
"testing"
)
func TestGetQQLyric(t *testing.T) {
tests := []struct {
input string
}{
{"0002Jztl3eJKu0"},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("id=%s", tt.input), func(t *testing.T) {
l, lt := GetQQLyric(tt.input)
if l == "" || lt == "" {
t.Errorf("get cloud lyric faild, id = %s", tt.input)
}
})
}
}

67
srt.go
View file

@ -6,6 +6,7 @@ import (
"github.com/Hami-Lemon/lrc2srt/glist"
"io"
"os"
"path/filepath"
"strconv"
"strings"
)
@ -111,41 +112,43 @@ func (s *SRT) Merge(other *SRT, mode SRTMergeMode) {
//可以类比为合并两个有序链表,
//算法参考:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
func (s *SRT) mergeStack(other *SRT) {
ls, _ := s.Content.(*glist.LinkedList[*SRTContent])
lo, _ := other.Content.(*glist.LinkedList[*SRTContent])
lhs, lho := ls.First, lo.First
//临时的空结点
preHead := &glist.Node[*SRTContent]{}
prev := preHead
for lhs != nil && lho != nil {
//副本结点,从而不改变other对象中的内容
oCopy := lho.Clone()
if lhs.Element.Start <= oCopy.Element.Start {
prev.Next = lhs
lhs.Prev = prev
lhs = lhs.Next
sIt, oIt := s.Content.Iterator(), other.Content.Iterator()
//不对原来的链表做修改,合并的信息保存在一个新的链表中
merge := glist.NewLinkedList[*SRTContent]()
var sNode, oNode *SRTContent
//分别获取两个链表的第一个元素
if sIt.Has() && oIt.Has() {
sNode, oNode = sIt.Next(), oIt.Next()
}
//开始迭代
for sIt.Has() && oIt.Has() {
//小于等于当相等时s中的元素添加进去
if sNode.Start <= oNode.Start {
merge.Append(sNode)
sNode = sIt.Next()
} else {
prev.Next = oCopy
oCopy.Prev = prev
lho = lho.Next
merge.Append(oNode)
oNode = oIt.Next()
}
prev = prev.Next
}
if lhs == nil {
//如果剩下的内容是other中的,则依次迭代复制到s中
for n := lho; n != nil; n = n.Next {
c := n.Clone()
prev.Next = c
c.Prev = prev
prev = prev.Next
if sNode != nil && oNode != nil {
//循环退出时sNode和oNode指向的元素还没有进行比较会导致缺少两条数据
if sNode.Start <= oNode.Start {
merge.Append(sNode)
merge.Append(oNode)
} else {
merge.Append(oNode)
merge.Append(sNode)
}
} else {
prev.Next = lhs
}
ls.First = preHead.Next
ls.First.Prev = nil
//剩下的元素添加到链表中,最多只有一个链表有剩余元素
for sIt.Has() {
merge.Append(sIt.Next())
}
for oIt.Has() {
merge.Append(oIt.Next())
}
s.Content = merge
}
func (s *SRT) mergeUp(other *SRT) {
@ -169,6 +172,10 @@ func (s *SRT) mergeBottom(other *SRT) {
func (s *SRT) WriteFile(path string) error {
f, err := os.Create(path)
if err != nil {
//不存在对应文件夹
if os.IsNotExist(err) {
panic("文件夹不存在:" + filepath.Dir(path))
}
return err
}
err = s.Write(f)

75
srt_test.go Normal file
View file

@ -0,0 +1,75 @@
package lrc2srt
import "testing"
func TestSRTContent_String(t *testing.T) {
type fields struct {
Index int
Start int
End int
Text string
}
tests := []struct {
name string
fields fields
want string
}{
{"srtContent String()", fields{1, 10, 20, "test"},
"1\n00:00:00,010 --> 00:00:00,020\ntest\n\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &SRTContent{
Index: tt.fields.Index,
Start: tt.fields.Start,
End: tt.fields.End,
Text: tt.fields.Text,
}
if got := s.String(); got != tt.want {
t.Errorf("String() = %v, want %v", got, tt.want)
}
})
}
}
func TestLrcToSrt(t *testing.T) {
lrc := `[ar:artist]
[al:album]
[ti:title]
[by:author]
[00:24.83] 天涯的尽头 有谁去过
[00:28.53] 山水优雅着 保持沉默
[00:32.20] 我们的青春却热闹很多
[00:35.38] 而且是谁都 不准偷
`
content := []string{
"天涯的尽头 有谁去过", "山水优雅着 保持沉默", "我们的青春却热闹很多", "而且是谁都 不准偷",
}
l := ParseLRC(lrc)
srt := LrcToSrt(l)
if srt.Title != "title" {
t.Errorf("SRT Title=%s, want=%s", srt.Title, "title")
}
if srt.Artist != "artist" {
t.Errorf("SRT Artist=%s, want=%s", srt.Artist, "altist")
}
index := 0
for it := srt.Content.Iterator(); it.Has(); {
c := it.Next().Text
if c != content[index] {
t.Errorf("srt Text=%s, want=%s", c, content[index])
}
index++
}
}
func TestSRT_MergeStack(t *testing.T) {
}
func TestSRT_MergeUp(t *testing.T) {
}
func TestSRT_MergeBottom(t *testing.T) {
}