-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Camelize/decamelize asymmetries #37
Comments
@mjschock What behavior do you expect for |
@antonagestam hmm... i would expect the following:
so
the general rules would be something like: class IrreversibleProcessException(Exception):
pass
def camelize(chars, root=True):
camelized_chars = []
for i, char in enumerate(chars):
if char == '_':
continue
if i in (0, 1, len(chars) - 1):
camelized_chars.append(char)
continue
if chars[i-1] == '_' and char.isalpha() and char.islower():
camelized_chars.append(char.upper())
elif chars[i-1] == '_':
camelized_chars.append('_')
camelized_chars.append(char)
else:
camelized_chars.append(char)
camelized_chars_string = ''.join(camelized_chars)
if root and decamelize(camelized_chars_string, False) != chars:
raise IrreversibleProcessException
return camelized_chars_string
def decamelize(chars, root=True):
decamelized_chars = []
for i, char in enumerate(chars):
if i in (0, 1, len(chars) - 1):
decamelized_chars.append(char)
continue
if chars[i+1] == '_' or chars[i-1] == '_':
decamelized_chars.append(char)
elif (chars[i-1].isalpha() and chars[i-1].islower()) and char.isupper():
decamelized_chars.append('_')
decamelized_chars.append(char.lower())
elif not chars[i-1].isalpha() and char.isalpha() and char.isupper():
decamelized_chars.append('_')
decamelized_chars.append(char.lower())
else:
decamelized_chars.append(char)
decamelized_chars_string = ''.join(decamelized_chars)
if root and camelize(decamelized_chars_string, False) != chars:
raise IrreversibleProcessException
return decamelized_chars_string
assert camelize('item1_entry') == 'item1Entry'
assert camelize('N1_item') == 'N1Item'
assert camelize('n1_item') == 'n1Item'
assert camelize('item_1entry') == 'item_1entry'
assert camelize('ADVERTISED_1000baseT_Full') == 'ADVERTISED_1000baseT_Full'
assert decamelize('item1Entry') == 'item1_entry'
assert decamelize('item1entry') == 'item1entry'
assert decamelize('N1Item') == 'N1_item'
assert decamelize('N1item') == 'N1item'
assert decamelize('n1Item') == 'n1_item'
assert decamelize('item_1entry') == 'item_1entry'
assert decamelize('ADVERTISED_1000baseT_Full') == 'ADVERTISED_1000baseT_Full' |
I think this is the same issue as #168, I've added these examples in that issue. # Inconsistent behaviour
>>> humps.camelize("ab")
'ab'
>>> humps.camelize("a_b")
'a_b'
>>> humps.camelize("a_be")
'a_be'
>>> humps.camelize("a_best")
'a_best'
>>> humps.camelize("ar_best")
'arBest'
# Incorrect roundtrip
>>> humps.decamelize(humps.camelize("area_b"))
'areab'
# Correct
>>> humps.decamelize(humps.camelize("aa_bb"))
'aa_bb'
# Wrong
>>> humps.decamelize(humps.camelize("aa_b"))
'aab'
# Correct
>>> humps.decamelize(humps.camelize("a_b"))
'a_b'
>>> humps.decamelize(humps.camelize("a_bb"))
'a_bb'
# Frist is wrong, second correct
>>> humps.camelize("a_b")
'a_b'
>>> humps.camelize("aa_ab")
'aaAb' |
I'd recommend using property based testing as this is a very classic round trip case. import humps.main
from hypothesis import given
from hypothesis import strategies as st
@given(str_or_iter=st.text(min_size=1))
def test_roundtrip_camelize_decamelize(str_or_iter):
value0 = humps.main.camelize(str_or_iter=str_or_iter)
value1 = humps.main.decamelize(str_or_iter=value0)
assert str_or_iter == value1, (str_or_iter, value1) Results:
|
Describe the bug
Camelize/decamelize asymmetry when numbers are involved.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Additional context
This is for version 1.3.1 of pyhumps.
The text was updated successfully, but these errors were encountered: