Merge pull request #3982 from adsultana/fix-ifdef-nonstring-fields

Fix ifdef behavior with non-string fields (bug #3852)
This commit is contained in:
Adrian Sampson 2021-06-17 11:12:44 -04:00 committed by GitHub
commit bc2fd38690
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 1 deletions

View file

@ -1753,7 +1753,7 @@ class DefaultTemplateFunctions(object):
:param falseval: The string if the condition is false
:return: The string, based on condition
"""
if self.item.formatted().get(field):
if field in self.item:
return trueval if trueval else self.item.formatted().get(field)
else:
return falseval

View file

@ -377,6 +377,9 @@ Fixes:
* :doc`/reference/cli`: Remove reference to rarfile version in link
* Fix :bug:`2873`. Duplicates can now generate checksums. Thanks user:`wisp3rwind`
for the pointer to how to solve. Thanks to :user:`arogl`.
* Templates that use ``%ifdef`` now produce the expected behavior when used in
conjunction with non-string fields from the :doc:`/plugins/types`.
:bug:`3852`
For plugin developers:

View file

@ -145,6 +145,39 @@ class TypesPluginTest(unittest.TestCase, TestHelper):
with self.assertRaises(ConfigValueError):
self.run_command(u'ls')
def test_template_if_def(self):
# Tests for a subtle bug when using %ifdef in templates along with
# types that have truthy default values (e.g. '0', '0.0', 'False')
# https://github.com/beetbox/beets/issues/3852
self.config['types'] = {'playcount': u'int', 'rating': u'float',
'starred': u'bool'}
with_fields = self.add_item(artist=u'prince')
self.modify(u'playcount=10', u'artist=prince')
self.modify(u'rating=5.0', u'artist=prince')
self.modify(u'starred=yes', u'artist=prince')
with_fields.load()
without_fields = self.add_item(artist=u'britney')
int_template = u'%ifdef{playcount,Play count: $playcount,Not played}'
self.assertEqual(with_fields.evaluate_template(int_template),
u'Play count: 10')
self.assertEqual(without_fields.evaluate_template(int_template),
u'Not played')
float_template = u'%ifdef{rating,Rating: $rating,Not rated}'
self.assertEqual(with_fields.evaluate_template(float_template),
u'Rating: 5.0')
self.assertEqual(without_fields.evaluate_template(float_template),
u'Not rated')
bool_template = u'%ifdef{starred,Starred: $starred,Not starred}'
self.assertIn(with_fields.evaluate_template(bool_template).lower(),
(u'starred: true', u'starred: yes', u'starred: y'))
self.assertEqual(without_fields.evaluate_template(bool_template),
u'Not starred')
def modify(self, *args):
return self.run_with_output(u'modify', u'--yes', u'--nowrite',
u'--nomove', *args)