From 8d205cbae99ff382b881458431e64765c6cfb8cc Mon Sep 17 00:00:00 2001 From: zyd Date: Wed, 11 May 2022 17:19:11 +0900 Subject: [PATCH] add method propEq --- README.md | 17 +++++++++++++- ramda/__init__.py | 1 + ramda/propEq.py | 10 +++++++++ test/test_propEq.py | 55 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 ramda/propEq.py create mode 100644 test/test_propEq.py diff --git a/README.md b/README.md index e8af3c2..e0cdc36 100644 --- a/README.md +++ b/README.md @@ -386,7 +386,22 @@ R.project(['v1'], [obj1, obj2]) # [{'v1': 1}, {'v1': 3}] - [ ] promap - [x] prop -- [ ] propEq +- [x] propEq + +```python +# works for both dict and object +class Obj: + def __init__(self, v1, v2): + self.v1 = v1 + self.v2 = v2 +obj1 = Obj(1, 2) +R.propEq(1, 'v1', obj1) # True +R.propEq(2, 'v2', obj1) # True +R.propEq(1, 'v2', obj1) # False + +R.propEq(1, 'v1', {'v1': 1}) # True +``` + - [ ] propIs - [ ] propOr - [x] props diff --git a/ramda/__init__.py b/ramda/__init__.py index f3ff734..3d6647a 100644 --- a/ramda/__init__.py +++ b/ramda/__init__.py @@ -61,6 +61,7 @@ from .product import product from .project import project from .prop import prop +from .propEq import propEq from .props import props from .range import range from .reduce import reduce diff --git a/ramda/propEq.py b/ramda/propEq.py new file mode 100644 index 0000000..b090733 --- /dev/null +++ b/ramda/propEq.py @@ -0,0 +1,10 @@ +from .equals import equals +from .private._curry3 import _curry3 +from .prop import prop + + +def inner_propEq(val, name, obj): + return equals(val, prop(name, obj)) + + +propEq = _curry3(inner_propEq) diff --git a/test/test_propEq.py b/test/test_propEq.py new file mode 100644 index 0000000..0047e2f --- /dev/null +++ b/test/test_propEq.py @@ -0,0 +1,55 @@ + +import unittest + +import ramda as R + +from .helpers.Maybe import Just + +""" +https://github.com/ramda/ramda/blob/master/test/propEq.js +""" + +dict1 = {'name': 'Abby', 'age': 7, 'hair': 'blond'} +dict2 = {'name': 'Fred', 'age': 12, 'hair': 'brown'} + + +class TestPropEq(unittest.TestCase): + def test_has_R_equals_semantics(self): + # TODO: handle minus zero + self.assertEqual(True, R.propEq(float('nan'), 'value', {'value': float('nan')})) + self.assertEqual(True, R.propEq(Just([42]), 'value', {'value': Just([42])})) + + def test_returns_False_if_called_with_None(self): + self.assertEqual(False, R.propEq('Abby', 'name', None)) + +class TestPropEqForDict(unittest.TestCase): + def test_determines_whether_a_particular_property_matches_a_given_value_for_a_specific_object(self): + self.assertEqual(True, R.propEq('Abby', 'name', dict1)) + self.assertEqual(True, R.propEq('brown', 'hair', dict2)) + self.assertEqual(False, R.propEq('blond', 'hair', dict2)) + +class TestPropEqForObject(unittest.TestCase): + def test_determines_whether_a_particular_property_matches_a_given_value_for_a_specific_object(self): + class Person: + def __init__(self, name, age, hair): + self.name = name + self.age = age + self.hair = hair + abby = Person('Abby', 7, 'blond') + fred = Person('Fred', 12, 'brown') + self.assertEqual(True, R.propEq('Abby', 'name', abby)) + self.assertEqual(True, R.propEq('brown', 'hair', fred)) + self.assertEqual(False, R.propEq('blond', 'hair', fred)) + +class TestPropEqForList(unittest.TestCase): + def test_handles_number_as_property(self): + deities=['Cthulhu', 'Dagon', 'Yog-Sothoth'] + self.assertEqual(True, R.propEq('Cthulhu', 0, deities)) + self.assertEqual(True, R.propEq('Dagon', 1, deities)) + self.assertEqual(True, R.propEq('Yog-Sothoth', 2, deities)) + self.assertEqual(True, R.propEq('Yog-Sothoth', -1, deities)) + self.assertEqual(True, R.propEq(None, 3, deities)) + + +if __name__ == '__main__': + unittest.main()