# Copyright (C) 2018 Lars Wirzenius # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import unittest import muck class MemoryStoreTests(unittest.TestCase): def setUp(self): self.ms = muck.MemoryStore() self.meta1 = { 'id': 'id-1', 'rev': 'rev-1', } self.res1 = { 'foo': 'bar', } def test_is_initially_empty(self): self.assertEqual(len(self.ms), 0) self.assertEqual(self.ms.as_dict(), {}) self.assertFalse('foo' in self.ms) def test_creates_resource(self): chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] self.assertEqual(len(self.ms), 1) self.assertTrue(rid in self.ms) self.assertEqual(self.ms[rid], (self.meta1, self.res1)) self.assertEqual( self.ms.as_dict(), { rid: (self.meta1, self.res1), }) def test_wont_create_resource_with_conflicting_id(self): chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) with self.assertRaises(muck.Error): self.ms.change(chg) def test_updates_resource(self): meta2 = dict(self.meta1) meta2['rev'] = 'rev-2' res2 = dict(self.res1) res2['foo'] = 'yo' create = muck.CreateChange(meta=self.meta1, res=self.res1) update = muck.UpdateChange(meta=meta2, res=res2) rid = self.meta1['id'] self.ms.change(create) self.ms.change(update) self.assertEqual(len(self.ms), 1) self.assertEqual( self.ms.as_dict(), { rid: (meta2, res2), }) def test_refuses_to_update_resource_that_didnt_exist(self): update = muck.UpdateChange(meta=self.meta1, res=self.res1) with self.assertRaises(muck.Error): self.ms.change(update) def test_deletes_resource(self): create = muck.CreateChange(meta=self.meta1, res=self.res1) delete = muck.DeleteChange(meta=self.meta1) self.ms.change(create) self.ms.change(delete) self.assertEqual(len(self.ms), 0) self.assertEqual(self.ms.as_dict(), {}) def test_refuses_to_delete_resource_that_doesnt_exist(self): delete = muck.DeleteChange(meta=self.meta1) with self.assertRaises(muck.Error): self.ms.change(delete) def test_finds_nothing_for_impossible_condition(self): chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) cond = [ { 'where': 'meta', 'field': 'id', 'pattern': 'does-not-exist', 'op': '==', }, ] hits = self.ms.search(cond) self.assertEqual(hits, []) def test_finds_matching_resources_in_meta(self): chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] cond = [ { 'where': 'meta', 'field': 'id', 'pattern': rid, 'op': '==', }, ] hits = self.ms.search(cond) self.assertEqual(hits, [rid]) def test_finds_matching_resources_in_data(self): chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] cond = [ { 'where': 'data', 'field': 'foo', 'pattern': self.res1['foo'], 'op': '==', }, ] hits = self.ms.search(cond) self.assertEqual(hits, [rid]) def test_finds_matches_in_list(self): self.res1['foo'] = ['bar', 'yo'] chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] cond = [ { 'where': 'data', 'field': 'foo', 'pattern': 'yo', 'op': '==', }, ] hits = self.ms.search(cond) self.assertEqual(hits, [rid]) def test_finds_ge(self): self.res1['foo'] = ['bar', 'yo'] chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] cond = [ { 'where': 'data', 'field': 'foo', 'pattern': 'yo', 'op': '>=', }, ] hits = self.ms.search(cond) self.assertEqual(hits, [rid]) def test_finds_le(self): self.res1['foo'] = ['bar', 'yo'] chg = muck.CreateChange(meta=self.meta1, res=self.res1) self.ms.change(chg) rid = self.meta1['id'] cond = [ { 'where': 'data', 'field': 'foo', 'pattern': 'bar', 'op': '<=', }, ] hits = self.ms.search(cond) self.assertEqual(hits, [rid])