Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,29 @@ a = A()
R.keys(a) # ['a', 'b']
```

```python
# keys include super class attributes
class A:
def __init__(self, a):
self.a = a

class B(A):
def __init__(self, a, b):
super().__init__(a)
self.b = b

class C(A):
def __init__(self, c):
self.c = c

a = A(1)
b = B(2, 3)
c = C(4)
R.keys(a) # ['a']
R.keys(b) # ['a', 'b']
R.keys(c) # ['c'], because c does not call super().__init__()
```

- [ ] keysIn
- [ ] last
- [x] 0.1.2 lastIndexOf
Expand Down Expand Up @@ -523,7 +546,23 @@ R.values({'a': 1, 'b': 2}) # [1, 2]
- [ ] valuesIn
- [ ] view
- [ ] when
- [ ] where
- [x] where

spec(first param) is prefer to be a dict.

method `where` supports both dict and object as second param.

```python
class Obj:
def __init__(self, x, y):
self.x = x
self.y = y

spec = {'x': R.equals(1)}
R.where(spec, {'x': 1, 'y': 2}) # True
R.where(spec, Obj(1, 2)) # True
```

- [ ] whereAny
- [ ] whereEq
- [ ] without
Expand Down
1 change: 1 addition & 0 deletions ramda/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
from .uniqWith import uniqWith
from .useWith import useWith
from .values import values
from .where import where
from .xprod import xprod
# pylint: disable=redefined-builtin
from .zip import zip
Expand Down
13 changes: 13 additions & 0 deletions ramda/where.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from .private._curry2 import _curry2
from .private._has import _has
from .private._helper import getAttribute


def inner_where(spec, testObj):
for prop in spec:
if _has(spec, prop) and not spec[prop](getAttribute(testObj, prop)):
return False
return True


where = _curry2(inner_where)
123 changes: 123 additions & 0 deletions test/test_where.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

import unittest

import ramda as R

"""
https://github.com/ramda/ramda/blob/master/test/where.js
"""


class TestWhereForDict(unittest.TestCase):
def test_returns_true_if_the_test_dict_satisfies_the_spec(self):
spec = {'x': R.equals(1), 'y': R.equals(2)}
test1 = {'x': 0, 'y': 200}
test2 = {'x': 0, 'y': 10}
test3 = {'x': 1, 'y': 101}
test4 = {'x': 1, 'y': 2}
self.assertEqual(False, R.where(spec, test1))
self.assertEqual(False, R.where(spec, test2))
self.assertEqual(False, R.where(spec, test3))
self.assertEqual(True, R.where(spec, test4))

def test_does_not_need_the_spec_and_the_test_object_to_have_the_same_interface(self):
spec = {'x': R.equals(100)}
test1 = {'x': 20, 'y': 100, 'z': 100}
test2 = {'w': 1, 'x': 100, 'y': 100, 'z': 100}

self.assertEqual(False, R.where(spec, test1))
self.assertEqual(True, R.where(spec, test2))

def test_matches_specs_that_have_None_properties(self):
spec = {'x': R.equals(None)}
test1 = {}
test2 = {'x': None}
test3 = {'x': 1}

self.assertEqual(True, R.where(spec, test1))
self.assertEqual(True, R.where(spec, test2))
self.assertEqual(False, R.where(spec, test3))

class TestWhereForObject(unittest.TestCase):
def test_returns_true_if_the_test_dict_satisfies_the_spec(self):
class Test:
def __init__(self, x, y):
self.x = x
self.y = y
spec = {'x': R.equals(1), 'y': R.equals(2)}
test1 = Test(0, 200)
test2 = Test(0, 10)
test3 = Test(1, 101)
test4 = Test(1, 2)
self.assertEqual(False, R.where(spec, test1))
self.assertEqual(False, R.where(spec, test2))
self.assertEqual(False, R.where(spec, test3))
self.assertEqual(True, R.where(spec, test4))

def test_does_not_need_the_spec_and_the_test_object_to_have_the_same_interface(self):
class Test1:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z

class Test2:
def __init__(self, w, x, y, z):
self.w = w
self.x = x
self.y = y
self.z = z

spec = {'x': R.equals(100)}
test1 = Test1(20, 100, 100)
test2 = Test2(1, 100, 100, 100)

self.assertEqual(False, R.where(spec, test1))
self.assertEqual(True, R.where(spec, test2))

def test_matches_specs_that_have_None_properties(self):
class Test1:
def __init__(self):
pass

class Test2:
def __init__(self, x):
self.x = x

spec = {'x': R.equals(None)}
test1 = Test1()
test2 = Test2(None)
test3 = Test2(1)

self.assertEqual(True, R.where(spec, test1))
self.assertEqual(True, R.where(spec, test2))
self.assertEqual(False, R.where(spec, test3))

def test_is_true_for_an_empty_spec(self):
class Test:
def __init__(self, a):
self.a = a

self.assertEqual(True, R.where({}, Test(1)))

def test_matches_super_class_property_if_super_init_called(self):
class Parent:
def __init__(self):
self.x = 1

class Child(Parent):
def __init__(self):
super().__init__()
self.y = 2

spec1 = {'x': R.equals(1)}
spec2 = {'y': R.equals(2)}

self.assertEqual(True, R.where(spec1, Child()))
self.assertEqual(True, R.where(spec1, Parent()))
self.assertEqual(True, R.where(spec2, Child()))
self.assertEqual(False, R.where(spec2, Parent()))


if __name__ == '__main__':
unittest.main()