1 /*
2 * Copyright 2003-2021 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "MakeTag.hxx"
21 #include "song/TagSongFilter.hxx"
22 #include "song/LightSong.hxx"
23 #include "tag/Type.h"
24
25 #include <gtest/gtest.h>
26
27 static bool
InvokeFilter(const TagSongFilter & f,const Tag & tag)28 InvokeFilter(const TagSongFilter &f, const Tag &tag) noexcept
29 {
30 return f.Match(LightSong("dummy", tag));
31 }
32
TEST(TagSongFilter,Basic)33 TEST(TagSongFilter, Basic)
34 {
35 const TagSongFilter f(TAG_TITLE,
36 StringFilter("needle", false, false, false));
37
38 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "needle")));
39 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_TITLE, "needle")));
40 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "needle", TAG_TITLE, "foo")));
41 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ARTIST, "foo", TAG_TITLE, "needle", TAG_ALBUM, "bar")));
42
43 EXPECT_FALSE(InvokeFilter(f, MakeTag()));
44 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo")));
45 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_TITLE, "bar")));
46 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_ARTIST, "needle")));
47 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "FOOneedleBAR")));
48 }
49
50 /**
51 * Test with empty string. This matches tags where the given tag type
52 * does not exist.
53 */
TEST(TagSongFilter,Empty)54 TEST(TagSongFilter, Empty)
55 {
56 const TagSongFilter f(TAG_TITLE,
57 StringFilter("", false, false, false));
58
59 EXPECT_TRUE(InvokeFilter(f, MakeTag()));
60
61 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo")));
62 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_TITLE, "bar")));
63 }
64
TEST(TagSongFilter,Substring)65 TEST(TagSongFilter, Substring)
66 {
67 const TagSongFilter f(TAG_TITLE,
68 StringFilter("needle", false, true, false));
69
70 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "needle")));
71 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "needleBAR")));
72 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "FOOneedle")));
73 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "FOOneedleBAR")));
74
75 EXPECT_FALSE(InvokeFilter(f, MakeTag()));
76 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "eedle")));
77 }
78
TEST(TagSongFilter,Negated)79 TEST(TagSongFilter, Negated)
80 {
81 const TagSongFilter f(TAG_TITLE,
82 StringFilter("needle", false, false, true));
83
84 EXPECT_TRUE(InvokeFilter(f, MakeTag()));
85 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "needle")));
86 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo")));
87 }
88
89 /**
90 * Combine the "Empty" and "Negated" tests.
91 */
TEST(TagSongFilter,EmptyNegated)92 TEST(TagSongFilter, EmptyNegated)
93 {
94 const TagSongFilter f(TAG_TITLE,
95 StringFilter("", false, false, true));
96
97 EXPECT_FALSE(InvokeFilter(f, MakeTag()));
98 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo")));
99 }
100
101 /**
102 * Negation with multiple tag values.
103 */
TEST(TagSongFilter,MultiNegated)104 TEST(TagSongFilter, MultiNegated)
105 {
106 const TagSongFilter f(TAG_TITLE,
107 StringFilter("needle", false, false, true));
108
109 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_TITLE, "bar")));
110 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "needle", TAG_TITLE, "bar")));
111 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_TITLE, "foo", TAG_TITLE, "needle")));
112 }
113
114 /**
115 * Check whether fallback tags work, e.g. AlbumArtist falls back to
116 * just Artist if there is no AlbumArtist.
117 */
TEST(TagSongFilter,Fallback)118 TEST(TagSongFilter, Fallback)
119 {
120 const TagSongFilter f(TAG_ALBUM_ARTIST,
121 StringFilter("needle", false, false, false));
122
123 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ALBUM_ARTIST, "needle")));
124 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ARTIST, "needle")));
125
126 EXPECT_FALSE(InvokeFilter(f, MakeTag()));
127 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ALBUM_ARTIST, "foo")));
128 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ARTIST, "foo")));
129
130 /* no fallback, thus the Artist tag isn't used and this must
131 be a mismatch */
132 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ARTIST, "needle", TAG_ALBUM_ARTIST, "foo")));
133 }
134
135 /**
136 * Combine the "Empty" and "Fallback" tests.
137 */
TEST(TagSongFilter,EmptyFallback)138 TEST(TagSongFilter, EmptyFallback)
139 {
140 const TagSongFilter f(TAG_ALBUM_ARTIST,
141 StringFilter("", false, false, false));
142
143 EXPECT_TRUE(InvokeFilter(f, MakeTag()));
144
145 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ALBUM_ARTIST, "foo")));
146 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ARTIST, "foo")));
147 }
148
149 /**
150 * Combine the "Negated" and "Fallback" tests.
151 */
TEST(TagSongFilter,NegatedFallback)152 TEST(TagSongFilter, NegatedFallback)
153 {
154 const TagSongFilter f(TAG_ALBUM_ARTIST,
155 StringFilter("needle", false, false, true));
156
157 EXPECT_TRUE(InvokeFilter(f, MakeTag()));
158 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ALBUM_ARTIST, "foo")));
159 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ALBUM_ARTIST, "needle")));
160 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ARTIST, "foo")));
161 EXPECT_FALSE(InvokeFilter(f, MakeTag(TAG_ARTIST, "needle")));
162 EXPECT_TRUE(InvokeFilter(f, MakeTag(TAG_ARTIST, "needle", TAG_ALBUM_ARTIST, "foo")));
163 }
164