Repository: thegetty/crom

Issue:
Allow ident="" to create blank nodes

WISOTT

Discussion:

Patch:
diff --git a/README.md b/README.md
index 73b4a2a..bab3576 100644
--- a/README.md
+++ b/README.md
@@ -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
@@ -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.  
diff --git a/cromulent/model.py b/cromulent/model.py
index f5ab3ae..05e9034 100644
--- a/cromulent/model.py
+++ b/cromulent/model.py
@@ -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'):
@@ -378,6 +378,9 @@ class ExternalResource(object):
 					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)
@@ -386,10 +389,10 @@ class ExternalResource(object):
 					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):
@@ -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)
 


Test patch:
diff --git a/tests/test_model.py b/tests/test_model.py
index 5500935..657899b 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -210,17 +210,20 @@ class TestBuildClass(unittest.TestCase):
 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()
@@ -229,6 +232,7 @@ class TestAutoIdentifiers(unittest.TestCase):
 		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
@@ -239,6 +243,7 @@ class TestAutoIdentifiers(unittest.TestCase):
 		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:'))		
@@ -254,6 +259,31 @@ class TestAutoIdentifiers(unittest.TestCase):
 		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):