Skip to content

Commit

Permalink
Allow explicit bnodes
Browse files Browse the repository at this point in the history
  • Loading branch information
azaroth42 committed May 16, 2019
1 parent 5c812f1 commit a45903d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ Import the classes from the model module. As the classes are dynamically generat

```python
from cromulent.model import factory, Group
g1 = Group("Organization")
g2 = Group("Department")
g1 = Group(ident="Organization")
g2 = Group(ident="Department")
g1.member = g2
print factory.toString(g1, compact=False)
```

The constructor for the classes takes the following parameters:

* `ident` - an identifier to use for this instance. If specified, it should be a URI represented as a string. If it is the empty string, it will result in no identifier. If not specified, or specified as `None`, then it will be auto-generated by the factory if `auto_assign_id` is true, or if `auto_assign_id` is false, then it will result in no identifier.
* `label` - a human readable label for the resource, to act as internal documentation for the data
* `value` or `content` - a data value for the class. Dimensions and MonetaryAmounts use `value` which must be a number, and Name, Identifier, LinguisticObject and similar use `content` which must be a string.
* Additional keywords may be passed in, and will be sent to class-specific initialization code.


### Vocabulary

```python
Expand All @@ -38,6 +46,7 @@ print factory.toString(h, compact=False)

* Assigning to the same property repeatedly does NOT overwrite the value, instead it appends. To overwrite a value, instead set it to a false value first.


### Factory settings

There are quite a few settings for how the module works, which are managed by a `factory` object.
Expand Down
11 changes: 7 additions & 4 deletions cromulent/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,9 @@ class ExternalResource(object):
_type = ""
_embed = True

def __init__(self, ident=""):
def __init__(self, ident=None):
self._factory = factory
if ident:
if ident is not None:
if ident.startswith('urn:uuid'):
self.id = ident
elif ident.startswith('http'):
Expand All @@ -378,6 +378,9 @@ def __init__(self, ident=""):
ident = "%s:%s" % (self._factory.prefixes_rev[pref], rest)

self.id = ident
elif ident == "":
# Allow explicit setting of empty string
self.id = ""
else:
# Allow for prefixed term
curied = ident.split(':', 1)
Expand All @@ -386,10 +389,10 @@ def __init__(self, ident=""):
self._full_id = self._factory.prefixes[curied[0]] + curied[1]
else:
self.id = factory.base_url + self.__class__._uri_segment + "/" + ident

elif factory.auto_assign_id:
self.id = factory.generate_id(self)
else:
# Not auto assigning, and not submitted = blank node
self.id = ""

def _toJSON(self, done, top=None):
Expand All @@ -408,7 +411,7 @@ class BaseResource(ExternalResource):
_classification = ""
_classhier = []

def __init__(self, ident="", label="", value="", content="", **kw):
def __init__(self, ident=None, label="", value="", content="", **kw):
"""Initialize BaseObject."""
super(BaseResource, self).__init__(ident)

Expand Down
30 changes: 30 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,20 @@ def test_build_class(self):
class TestAutoIdentifiers(unittest.TestCase):

def test_bad_autoid(self):
model.factory.auto_assign_id = True
model.factory.auto_id_type = "broken"
self.assertRaises(model.ConfigurationError, model.factory.generate_id,
"irrelevant")

def test_int(self):
model.factory.auto_assign_id = True
model.factory.auto_id_type = "int"
p = model.Person()
p2 = model.Activity()
self.assertEqual(int(p.id[-1]), int(p2.id[-1])-1)

def test_int_per_type(self):
model.factory.auto_assign_id = True
model.factory.auto_id_type = "int-per-type"
p = model.Person()
p2 = model.Person()
Expand All @@ -229,6 +232,7 @@ def test_int_per_type(self):
self.assertEqual(int(p.id[-1]), int(p3.id[-1]))

def test_int_per_segment(self):
model.factory.auto_assign_id = True
model.factory._auto_id_segments = {}
model.factory.auto_id_type = "int-per-segment"
model.Activity._uri_segment = model.Person._uri_segment
Expand All @@ -239,6 +243,7 @@ def test_int_per_segment(self):
self.assertEqual(int(p.id[-1]), int(p3.id[-1]))

def test_uuid(self):
model.factory.auto_assign_id = True
model.factory.auto_id_type = "uuid"
p = model.Person()
self.assertTrue(p.id.startswith('urn:uuid:'))
Expand All @@ -254,6 +259,31 @@ def test_prefixes(self):
p4 = model.Person('fish:4')
self.assertTrue(p4.id.startswith(model.factory.base_url))

def test_no_ident(self):

model.factory.auto_assign_id = True
p1 = model.Person() # auto assigned
p2 = model.Person(ident=None) # auto assigned
p3 = model.Person(ident="") # bnode explicitly

self.assertTrue(p1.id.startswith('http'))
self.assertTrue(p2.id.startswith('http'))
self.assertEqual(p3.id, '')

model.factory.auto_assign_id = False
p4 = model.Person() # bnode is default
p5 = model.Person(ident=None) # bnode is default
p6 = model.Person(ident="") # bnode explicitly

self.assertEqual(p4.id, '')
self.assertEqual(p5.id, '')
self.assertEqual(p6.id, '')







class TestBaseResource(unittest.TestCase):

Expand Down

0 comments on commit a45903d

Please sign in to comment.