activefacts-api 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +1 -0
- data/Gemfile +4 -2
- data/Rakefile +19 -1
- data/VERSION +1 -1
- data/activefacts-api.gemspec +7 -7
- data/lib/activefacts/api/constellation.rb +8 -1
- data/lib/activefacts/api/entity.rb +11 -3
- data/lib/activefacts/api/exceptions.rb +3 -3
- data/lib/activefacts/api/guid.rb +5 -1
- data/lib/activefacts/api/instance.rb +13 -7
- data/lib/activefacts/api/instance_index.rb +1 -0
- data/lib/activefacts/api/object_type.rb +7 -14
- data/lib/activefacts/api/role_values.rb +74 -23
- data/lib/activefacts/api/standard_types.rb +1 -1
- data/lib/activefacts/api/support.rb +1 -3
- data/lib/activefacts/api/value.rb +2 -2
- data/lib/activefacts/api/vocabulary.rb +7 -6
- data/lib/activefacts/tracer.rb +1 -1
- data/spec/constellation/constellation_spec.rb +11 -11
- data/spec/constellation/instance_spec.rb +4 -4
- data/spec/fact_type/roles_spec.rb +29 -0
- data/spec/identification_scheme/identification_spec.rb +5 -4
- data/spec/identification_scheme/identity_supertype_change_spec.rb +2 -2
- data/spec/object_type/entity_type/entity_type_spec.rb +13 -13
- data/spec/object_type/entity_type/multipart_identification_spec.rb +1 -1
- data/spec/object_type/value_type/autocounter_spec.rb +3 -3
- data/spec/object_type/value_type/guid_spec.rb +1 -1
- data/spec/object_type/value_type/value_type_spec.rb +1 -1
- metadata +26 -61
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dc17ae7a132478e2e4b591e19adf35d79627d70b
|
4
|
+
data.tar.gz: b6b63e83981a4ec466aa128b94fb7cfbf1370d0e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 916183df4492dab5a94c172d85f58b7f4a04f8407eb9decc301b07c8f137a5c6b3bfd4c80ce4f4d7b98e5ba9fe26d0483dd3a71b768159701b63d0c07b3a0b1e
|
7
|
+
data.tar.gz: 14858f846fe7c1fba970cd1b2cd6f890d21ae5247ce2107d73c49e75d919cf011814bd724e8b90ace9fdd524b262a3c83538b242137452d13eb8c0f454758323
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'rake', :group => [:development, :test]
|
3
|
+
gem 'rake', '>=10.1', :group => [:development, :test]
|
4
4
|
gem 'rbtree-pure'
|
5
5
|
|
6
6
|
group :development do
|
7
7
|
gem 'jeweler'
|
8
8
|
gem 'rspec', '~>2.6.0'
|
9
9
|
gem 'ruby-debug', :platforms => [:mri_18]
|
10
|
-
gem 'debugger', :platforms => [:mri_19
|
10
|
+
gem 'debugger', :platforms => [:mri_19,
|
11
|
+
(['1.8.7', '1.9.2'].include?(RUBY_VERSION) || RUBY_PLATFORM == 'java') ? nil : :mri_20
|
12
|
+
].compact
|
11
13
|
gem 'pry', :platforms => [:jruby, :rbx]
|
12
14
|
end
|
13
15
|
|
data/Rakefile
CHANGED
@@ -42,7 +42,7 @@ end
|
|
42
42
|
|
43
43
|
namespace :spec do
|
44
44
|
namespace :rubies do
|
45
|
-
SUPPORTED_RUBIES = %w{ 1.
|
45
|
+
SUPPORTED_RUBIES = %w{ 1.9.2 1.9.3 2.0.0 jruby-1.7.0 }
|
46
46
|
|
47
47
|
desc "Run Rspec tests on all supported rubies"
|
48
48
|
task :all_tasks => [:install_gems, :exec]
|
@@ -56,6 +56,19 @@ namespace :spec do
|
|
56
56
|
task :exec do
|
57
57
|
sh %{ rvm #{SUPPORTED_RUBIES.join(',')} exec bundle exec rake spec }
|
58
58
|
end
|
59
|
+
|
60
|
+
SUPPORTED_RUBIES.each do |ruby|
|
61
|
+
desc "Run `bundle install` on #{ruby}"
|
62
|
+
task :"install_gems_#{ruby}" do
|
63
|
+
sh %{ rvm #{ruby} exec bundle install }
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "Run `bundle exec rake` on #{ruby}"
|
67
|
+
task :"exec_#{ruby}" do
|
68
|
+
sh %{ rvm #{ruby} exec bundle exec rake spec }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
59
72
|
end
|
60
73
|
end
|
61
74
|
|
@@ -81,3 +94,8 @@ Rake::RDocTask.new do |rdoc|
|
|
81
94
|
rdoc.rdoc_files.include('README*')
|
82
95
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
83
96
|
end
|
97
|
+
|
98
|
+
task :wait do
|
99
|
+
print "Waiting for you to hit Enter"
|
100
|
+
$stdin.gets
|
101
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.8
|
data/activefacts-api.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "activefacts-api"
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Clifford Heath"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-11-13"
|
13
13
|
s.description = "\nThe ActiveFacts API is a Ruby DSL for managing constellations of elementary facts.\nEach fact is either existential (a value or an entity), characteristic (boolean) or\nbinary relational (A rel B). Relational facts are consistently co-referenced, so you\ncan traverse them efficiently in any direction. Each constellation maintains constraints\nover the fact population.\n"
|
14
14
|
s.email = "clifford.heath@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -68,15 +68,15 @@ Gem::Specification.new do |s|
|
|
68
68
|
s.homepage = "http://github.com/cjheath/activefacts-api"
|
69
69
|
s.licenses = ["MIT"]
|
70
70
|
s.require_paths = ["lib"]
|
71
|
-
s.rubygems_version = "
|
71
|
+
s.rubygems_version = "2.0.5"
|
72
72
|
s.summary = "A fact-based data model DSL and API"
|
73
73
|
|
74
74
|
if s.respond_to? :specification_version then
|
75
|
-
s.specification_version =
|
75
|
+
s.specification_version = 4
|
76
76
|
|
77
77
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
78
78
|
s.add_runtime_dependency(%q<rbtree-pure>, [">= 0"])
|
79
|
-
s.add_development_dependency(%q<rake>, [">=
|
79
|
+
s.add_development_dependency(%q<rake>, [">= 10.1"])
|
80
80
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
81
81
|
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
82
82
|
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
@@ -88,7 +88,7 @@ Gem::Specification.new do |s|
|
|
88
88
|
s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
|
89
89
|
else
|
90
90
|
s.add_dependency(%q<rbtree-pure>, [">= 0"])
|
91
|
-
s.add_dependency(%q<rake>, [">=
|
91
|
+
s.add_dependency(%q<rake>, [">= 10.1"])
|
92
92
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
93
93
|
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
94
94
|
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
@@ -101,7 +101,7 @@ Gem::Specification.new do |s|
|
|
101
101
|
end
|
102
102
|
else
|
103
103
|
s.add_dependency(%q<rbtree-pure>, [">= 0"])
|
104
|
-
s.add_dependency(%q<rake>, [">=
|
104
|
+
s.add_dependency(%q<rake>, [">= 10.1"])
|
105
105
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
106
106
|
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
107
107
|
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
@@ -139,8 +139,15 @@ module ActiveFacts
|
|
139
139
|
# This method removes the given instance from this constellation's indexes
|
140
140
|
# It must be called before the identifying roles get deleted or nullified.
|
141
141
|
def deindex_instance(instance) #:nodoc:
|
142
|
+
last_irns = nil
|
143
|
+
last_irvs = instance
|
142
144
|
([instance.class]+instance.class.supertypes_transitive).each do |klass|
|
143
|
-
|
145
|
+
if instance.is_a?(Entity) and last_irns != (n = klass.identifying_role_names)
|
146
|
+
# Build new identifying_role_values only when the identifying_role_names change:
|
147
|
+
last_irvs = instance.identifying_role_values(klass)
|
148
|
+
last_irns = n
|
149
|
+
end
|
150
|
+
instances[klass].delete(last_irvs)
|
144
151
|
end
|
145
152
|
# REVISIT: Need to nullify all the roles this object plays.
|
146
153
|
# If mandatory on the counterpart side, this may/must propagate the delete (without mutual recursion!)
|
@@ -45,7 +45,9 @@ module ActiveFacts
|
|
45
45
|
end
|
46
46
|
|
47
47
|
begin
|
48
|
+
@constellation.send(:instance_variable_set, :@suspend_duplicate_key_check, true)
|
48
49
|
send(role.setter, value)
|
50
|
+
@constellation.send(:instance_variable_set, :@suspend_duplicate_key_check, false)
|
49
51
|
# rescue NoMethodError => e
|
50
52
|
# raise settable_roles_exception(e, role_name)
|
51
53
|
end
|
@@ -99,8 +101,8 @@ module ActiveFacts
|
|
99
101
|
# When used as a hash key, the hash key of this entity instance is calculated
|
100
102
|
# by hashing the values of its identifying roles
|
101
103
|
def hash
|
102
|
-
self.class.
|
103
|
-
instance_variable_get(
|
104
|
+
self.class.identifying_roles.map{|role|
|
105
|
+
instance_variable_get(role.variable)
|
104
106
|
}.inject(0) { |h,v|
|
105
107
|
h ^= v.hash
|
106
108
|
h
|
@@ -391,6 +393,12 @@ module ActiveFacts
|
|
391
393
|
# which is a list of roles it plays. The identification scheme may be
|
392
394
|
# inherited from a superclass.
|
393
395
|
def identified_by(*args) #:nodoc:
|
396
|
+
options = (args[-1].is_a?(Hash) ? args.pop : {})
|
397
|
+
options.each do |key, value|
|
398
|
+
raise UnrecognisedOptionsException.new('EntityType', basename, key) unless respond_to?(key)
|
399
|
+
send(key, value)
|
400
|
+
end
|
401
|
+
|
394
402
|
raise MissingIdentificationException.new(self) unless args.size > 0
|
395
403
|
|
396
404
|
# Catch the case where we state the same identification as our superclass:
|
@@ -426,7 +434,7 @@ module ActiveFacts
|
|
426
434
|
|
427
435
|
def other.new_instance constellation, *args
|
428
436
|
instance = allocate
|
429
|
-
instance.instance_variable_set("@constellation", constellation)
|
437
|
+
instance.instance_variable_set(@@constellation_variable_name ||= "@constellation", constellation)
|
430
438
|
instance.send(:initialize, *args)
|
431
439
|
instance
|
432
440
|
end
|
@@ -33,7 +33,7 @@ module ActiveFacts
|
|
33
33
|
if is_single
|
34
34
|
"#{object_type} has a single identifying role '#{role}' which is has_one, but must be one_to_one"
|
35
35
|
else
|
36
|
-
|
36
|
+
"#{object_type} has an identifying role '#{role}' which is one_to_one, but must be has_one"
|
37
37
|
end
|
38
38
|
super msg
|
39
39
|
end
|
@@ -47,7 +47,7 @@ module ActiveFacts
|
|
47
47
|
|
48
48
|
class InvalidObjectType < SchemaException
|
49
49
|
def initialize vocabulary, klass, reason
|
50
|
-
|
50
|
+
super "A constellation over #{vocabulary.name} cannot index instances of #{klass} because it #{reason}"
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -59,7 +59,7 @@ module ActiveFacts
|
|
59
59
|
|
60
60
|
class UnrecognisedOptionsException < SchemaException
|
61
61
|
def initialize declaration, instance, option_names
|
62
|
-
|
62
|
+
super "Unrecognised options on declaration of #{declaration} #{instance}: #{option_names.inspect}"
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
data/lib/activefacts/api/guid.rb
CHANGED
@@ -4,7 +4,11 @@ require 'securerandom'
|
|
4
4
|
unless defined? SecureRandom.uuid
|
5
5
|
# I think this only applies to 1.8.6 (and JRuby/Rubinius in 1.8 mode) now:
|
6
6
|
def SecureRandom.uuid
|
7
|
-
hex(16).
|
7
|
+
hex(16).
|
8
|
+
sub(
|
9
|
+
@@format_pattern ||= /(........)(....)(....)(....)(............)/,
|
10
|
+
@@format_string ||= '\1-\2-\3-\4-\5'
|
11
|
+
)
|
8
12
|
end
|
9
13
|
end
|
10
14
|
|
@@ -4,8 +4,6 @@
|
|
4
4
|
#
|
5
5
|
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
6
6
|
#
|
7
|
-
# Instance methods are extended into all instances, whether of value or entity types.
|
8
|
-
#
|
9
7
|
module ActiveFacts
|
10
8
|
module API
|
11
9
|
# Every Instance of a ObjectType (A Value type or an Entity type) includes the methods of this module:
|
@@ -36,6 +34,7 @@ module ActiveFacts
|
|
36
34
|
# We need to check each superclass that has a different identification pattern
|
37
35
|
def check_identification_change_legality(role, value)
|
38
36
|
return unless @constellation && role.is_identifying
|
37
|
+
return if @constellation.send(:instance_variable_get, :@suspend_duplicate_key_check)
|
39
38
|
|
40
39
|
klasses = [self.class] + self.class.supertypes_transitive
|
41
40
|
last_identity = nil
|
@@ -83,6 +82,15 @@ module ActiveFacts
|
|
83
82
|
# Now, for all roles (from this class and all supertypes), assign nil to all functional roles
|
84
83
|
# The counterpart roles get cleared automatically.
|
85
84
|
klasses = [self.class]+self.class.supertypes_transitive
|
85
|
+
|
86
|
+
irvks = {} # identifying_role_values by class
|
87
|
+
klasses.each do |klass|
|
88
|
+
if !irvks[klass] and klass.roles.detect{|_, role| role.counterpart and !role.counterpart.unique and send(role.getter) }
|
89
|
+
# We will need the identifying_role_values for this role's object_type
|
90
|
+
irvks[klass] = identifying_role_values(klass)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
86
94
|
klasses.each do |klass|
|
87
95
|
klass.roles.each do |role_name, role|
|
88
96
|
next if role.unary?
|
@@ -94,13 +102,15 @@ module ActiveFacts
|
|
94
102
|
i = send(role.getter)
|
95
103
|
next unless i
|
96
104
|
if counterpart.is_identifying && counterpart.mandatory
|
105
|
+
# We play a mandatory identifying role in i; so retract that (it'll clear our instance variable)
|
97
106
|
i.retract
|
98
107
|
else
|
99
108
|
if (counterpart.unique)
|
100
109
|
# REVISIT: This will incorrectly fail to propagate a key change for a non-mandatory role
|
101
110
|
i.send(counterpart.setter, nil, false)
|
102
111
|
else
|
103
|
-
i.send(role.counterpart.getter)
|
112
|
+
rv = i.send(role.counterpart.getter)
|
113
|
+
rv.delete_instance(self, irvks[role.object_type])
|
104
114
|
end
|
105
115
|
end
|
106
116
|
instance_variable_set(role.variable, nil)
|
@@ -126,10 +136,6 @@ module ActiveFacts
|
|
126
136
|
include ObjectType
|
127
137
|
# Add Instance class methods here
|
128
138
|
end
|
129
|
-
|
130
|
-
def self.included other #:nodoc:
|
131
|
-
other.send :extend, ClassMethods
|
132
|
-
end
|
133
139
|
end
|
134
140
|
end
|
135
141
|
end
|
@@ -56,6 +56,7 @@ module ActiveFacts
|
|
56
56
|
# arguments (where ObjectType is the object_type name you're interested in)
|
57
57
|
#
|
58
58
|
class InstanceIndex
|
59
|
+
attr_reader :sort
|
59
60
|
|
60
61
|
# Should be in module ForwardableWithArityChecking
|
61
62
|
def self.def_single_delegator(accessor, method, *expected_arities)
|
@@ -18,7 +18,7 @@ module ActiveFacts
|
|
18
18
|
|
19
19
|
# Each ObjectType maintains a list of the Roles it plays:
|
20
20
|
def roles(role_name = nil)
|
21
|
-
unless instance_variable_defined? "@roles" # Avoid "instance variable not defined" warning from ||=
|
21
|
+
unless instance_variable_defined?(@@roles_name ||= "@roles") # Avoid "instance variable not defined" warning from ||=
|
22
22
|
@roles = RoleCollection.new
|
23
23
|
end
|
24
24
|
case role_name
|
@@ -58,7 +58,8 @@ module ActiveFacts
|
|
58
58
|
# Define a unary fact type attached to this object_type; in essence, a boolean attribute.
|
59
59
|
#
|
60
60
|
# Example: maybe :is_ceo
|
61
|
-
def maybe(role_name)
|
61
|
+
def maybe(role_name, options = {})
|
62
|
+
raise UnrecognisedOptionsException.new("role", role_name, options.keys) unless options.empty?
|
62
63
|
realise_role(roles[role_name] = Role.new(self, TrueClass, role_name))
|
63
64
|
end
|
64
65
|
|
@@ -319,14 +320,16 @@ module ActiveFacts
|
|
319
320
|
impacts = analyse_impacts(role)
|
320
321
|
end
|
321
322
|
|
323
|
+
old_key = identifying_role_values(role.object_type) if old && mutual_propagation
|
324
|
+
|
322
325
|
instance_variable_set(role_var, value)
|
323
326
|
|
324
327
|
# Remove "self" from the old counterpart:
|
325
|
-
old.send(getter = role.counterpart.getter).
|
328
|
+
old.send(getter = role.counterpart.getter).delete_instance(self, old_key) if old_key
|
326
329
|
|
327
330
|
@constellation.when_admitted do
|
328
331
|
# Add "self" into the counterpart
|
329
|
-
value.send(getter ||= role.counterpart.getter).
|
332
|
+
value.send(getter ||= role.counterpart.getter).add_instance(self, identifying_role_values(role.object_type)) if value
|
330
333
|
|
331
334
|
apply_impacts(impacts) if impacts # Propagate dependent key changes
|
332
335
|
end
|
@@ -350,7 +353,6 @@ module ActiveFacts
|
|
350
353
|
# :class => the related class (Class object or Symbol). Not allowed if role_name was a class.
|
351
354
|
# :mandatory => true. There must be a related object for this object to be valid.
|
352
355
|
# :counterpart => Symbol/String. The name of the counterpart role. Will be to_s.snakecase'd and maybe augmented with "all_" and/or "_as_<role_name>"
|
353
|
-
# :reading => "forward/reverse". Forward and reverse readings. Must include MARKERS for the player names. May include adjectives. REVISIT: define MARKERS!
|
354
356
|
# LATER:
|
355
357
|
# :order => :local_role OR lambda{} (for sort_by)
|
356
358
|
# :restrict => Range or Array of Range/value or respond_to?(include?)
|
@@ -413,11 +415,6 @@ module ActiveFacts
|
|
413
415
|
|
414
416
|
related_role_name = related_role_name.to_s if related_role_name = options.delete(:counterpart)
|
415
417
|
|
416
|
-
reading = options.delete(:reading) # REVISIT: Implement verbalisation
|
417
|
-
role_value_constraint = options.delete(:restrict) # REVISIT: Implement role value constraints
|
418
|
-
|
419
|
-
additional_role_options options
|
420
|
-
|
421
418
|
raise UnrecognisedOptionsException.new("role", role_name, options.keys) unless options.empty?
|
422
419
|
|
423
420
|
# If you have a role "supervisor" and a sub-class "Supervisor", this'll bitch.
|
@@ -447,10 +444,6 @@ module ActiveFacts
|
|
447
444
|
]
|
448
445
|
end
|
449
446
|
|
450
|
-
def additional_role_options options
|
451
|
-
# This is a hook for extensions to override. Any extension options should be deleted from the options hash.
|
452
|
-
end
|
453
|
-
|
454
447
|
def when_bound(object_type, *args, &block)
|
455
448
|
case object_type
|
456
449
|
when Class
|
@@ -8,6 +8,67 @@ module ActiveFacts
|
|
8
8
|
module API
|
9
9
|
|
10
10
|
class RoleValues #:nodoc:
|
11
|
+
attr_accessor :sort
|
12
|
+
|
13
|
+
def initialize sort = false
|
14
|
+
@sort = !!(sort || ENV[@@af_sort_name ||= "ACTIVEFACTS_SORT"])
|
15
|
+
@a = @sort ? RBTree.new : []
|
16
|
+
end
|
17
|
+
|
18
|
+
def +(a)
|
19
|
+
if @sort
|
20
|
+
@a.values.+(a.is_a?(RoleValues) ? [a] : a)
|
21
|
+
else
|
22
|
+
@a.+(a.is_a?(RoleValues) ? [a] : a)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_a
|
27
|
+
@sort ? @a.values : @a
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
@sort ? @a.keys : @a
|
32
|
+
end
|
33
|
+
|
34
|
+
def single
|
35
|
+
size > 1 ? nil : to_a[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def form_key a
|
39
|
+
KeyArray.new(Array(a))
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_instance(value, key)
|
43
|
+
if @sort
|
44
|
+
@a[form_key(key)] = value
|
45
|
+
else
|
46
|
+
@a << value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete_instance(value, key)
|
51
|
+
if @sort
|
52
|
+
deleted = @a.delete(form_key(key))
|
53
|
+
else
|
54
|
+
deleted = @a.delete(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Test code:
|
58
|
+
unless deleted
|
59
|
+
p @a
|
60
|
+
p value
|
61
|
+
debugger
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def verbalise
|
68
|
+
a = @sort ? @a.values : @a
|
69
|
+
"[#{a.map(&:verbalise).join(", ")}]"
|
70
|
+
end
|
71
|
+
|
11
72
|
# Paranoia. Because of changes in the implementation, I need to catch old code that calls these delegates incorrectly
|
12
73
|
def self.def_single_delegator(accessor, method, *expected_arities)
|
13
74
|
str = %{
|
@@ -15,12 +76,24 @@ module ActiveFacts
|
|
15
76
|
if #{expected_arities.size == 0 ? "block" : "!block || !#{expected_arities.inspect}.include?(block.arity)" }
|
16
77
|
raise ArgumentError.new("Arity mismatch on #{name}\##{method}, got \#{block ? block.arity : 'none'} want #{expected_arities.inspect} at \#{caller*"\n\t"})")
|
17
78
|
end
|
18
|
-
|
79
|
+
if @sort
|
80
|
+
#{accessor}.values.__send__(:#{method}, *args, &block)
|
81
|
+
else
|
82
|
+
#{accessor}.__send__(:#{method}, *args, &block)
|
83
|
+
end
|
19
84
|
end
|
20
85
|
}
|
21
86
|
eval(str)
|
22
87
|
end
|
23
88
|
|
89
|
+
def include? v
|
90
|
+
if @sort
|
91
|
+
@a.include?(form_key(v))
|
92
|
+
else
|
93
|
+
@a.include?(v)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
24
97
|
def_single_delegator :@a, :all?, 1
|
25
98
|
def_single_delegator :@a, :empty?
|
26
99
|
def_single_delegator :@a, :include?
|
@@ -35,28 +108,6 @@ module ActiveFacts
|
|
35
108
|
def_single_delegator :@a, :each, *([1] + Array(defined?(::RSpec) ? -2 : nil))
|
36
109
|
def_single_delegator :@a, :detect, 1, *([1] + Array(defined?(::RSpec) ? -2 : nil))
|
37
110
|
def_single_delegator :@a, :map, 1, -1
|
38
|
-
|
39
|
-
def initialize
|
40
|
-
@a = []
|
41
|
-
end
|
42
|
-
|
43
|
-
def +(a)
|
44
|
-
@a.+(a.is_a?(RoleValues) ? [a] : a)
|
45
|
-
end
|
46
|
-
|
47
|
-
def single
|
48
|
-
size > 1 ? nil : @a[0]
|
49
|
-
end
|
50
|
-
|
51
|
-
def update(old, value)
|
52
|
-
@a.delete(old) if old
|
53
|
-
@a << value if value
|
54
|
-
end
|
55
|
-
|
56
|
-
def verbalise
|
57
|
-
"[#{@a.map(&:verbalise).join(", ")}]"
|
58
|
-
end
|
59
111
|
end
|
60
|
-
|
61
112
|
end
|
62
113
|
end
|
@@ -59,7 +59,7 @@ class Class
|
|
59
59
|
# Make this Class into a ObjectType and if necessary its module into a Vocabulary.
|
60
60
|
# The parameters are the names (Symbols) of the identifying roles.
|
61
61
|
def identified_by *args, &b
|
62
|
-
raise InvalidEntityException(self) if respond_to? :value_type # Don't make a ValueType into an EntityType
|
62
|
+
raise ActiveFacts::API::InvalidEntityException.new(self) if respond_to? :value_type # Don't make a ValueType into an EntityType
|
63
63
|
|
64
64
|
# The inclusion of instance methods triggers ClassMethods to be included in the class too
|
65
65
|
include ActiveFacts::API::Entity
|
@@ -40,7 +40,7 @@ module ActiveFacts
|
|
40
40
|
# REVISIT: args could be a hash, with keys :length, :scale, :unit, :allow
|
41
41
|
options = (args[-1].is_a?(Hash) ? args.pop : {})
|
42
42
|
options.each do |key, value|
|
43
|
-
raise UnrecognisedOptionsException.new('
|
43
|
+
raise UnrecognisedOptionsException.new('ValueType', basename, key) unless respond_to?(key)
|
44
44
|
send(key, value)
|
45
45
|
end
|
46
46
|
end
|
@@ -141,7 +141,7 @@ module ActiveFacts
|
|
141
141
|
class << klass
|
142
142
|
def new_instance constellation, *args
|
143
143
|
instance = allocate
|
144
|
-
instance.instance_variable_set("@constellation", constellation)
|
144
|
+
instance.instance_variable_set(@@constellation_variable_name ||= "@constellation", constellation)
|
145
145
|
instance.send(:initialize, *args)
|
146
146
|
instance
|
147
147
|
end
|
@@ -32,7 +32,7 @@ module ActiveFacts
|
|
32
32
|
__bind(camel)
|
33
33
|
c
|
34
34
|
else
|
35
|
-
if
|
35
|
+
if const_defined?(camel)
|
36
36
|
begin
|
37
37
|
const_get(camel)
|
38
38
|
rescue NameError
|
@@ -55,11 +55,12 @@ module ActiveFacts
|
|
55
55
|
|
56
56
|
def verbalise
|
57
57
|
"Vocabulary #{name}:\n\t" +
|
58
|
-
@object_type.keys.sort.map
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
@object_type.keys.sort.map do |object_type|
|
59
|
+
c = @object_type[object_type]
|
60
|
+
__bind(c.basename)
|
61
|
+
c.verbalise + "\n\t\t// Roles played: " + c.roles.verbalise
|
62
|
+
end.
|
63
|
+
join("\n\t")
|
63
64
|
end
|
64
65
|
|
65
66
|
def __add_object_type(klass) #:nodoc:
|
data/lib/activefacts/tracer.rb
CHANGED
@@ -79,19 +79,19 @@ describe "A Constellation instance" do
|
|
79
79
|
|
80
80
|
it "should complain when accessing a non-class as a method" do
|
81
81
|
Mod::Foo = 23
|
82
|
-
lambda { @constellation.Foo }.should raise_error
|
82
|
+
lambda { @constellation.Foo }.should raise_error(NoMethodError)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should complain when accessing a class that isn't an object type" do
|
86
86
|
class Mod::Bar; end
|
87
|
-
proc { @constellation.Bar }.should raise_error
|
88
|
-
proc { @constellation.instances[Mod::Bar] }.should raise_error
|
87
|
+
proc { @constellation.Bar }.should raise_error(NoMethodError)
|
88
|
+
proc { @constellation.instances[Mod::Bar] }.should raise_error(ActiveFacts::API::InvalidObjectType)
|
89
89
|
end
|
90
90
|
|
91
91
|
it "should deny handling an object type defined outside the current module" do
|
92
92
|
class ::Bar; end
|
93
|
-
lambda { @constellation.Bar }.should raise_error
|
94
|
-
lambda { @constellation.instances[Bar] }.should raise_error
|
93
|
+
lambda { @constellation.Bar }.should raise_error(NoMethodError)
|
94
|
+
lambda { @constellation.instances[Bar] }.should raise_error(ActiveFacts::API::InvalidObjectType)
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should allow inspection" do
|
@@ -201,7 +201,7 @@ describe "A Constellation instance" do
|
|
201
201
|
it "Should raise an exception with assigning a role whose referent (object type) has not yet been defined" do
|
202
202
|
n = @constellation.Name("Fred")
|
203
203
|
# This does not raise the "settable_roles_exception". I'm no longer sure how I did this, so I can't get coverage on this code :(
|
204
|
-
proc { n.undefined_role = 'foo' }.should raise_error
|
204
|
+
proc { n.undefined_role = 'foo' }.should raise_error(NoMethodError)
|
205
205
|
end
|
206
206
|
|
207
207
|
# Maybe not complete yet
|
@@ -429,7 +429,7 @@ describe "A Constellation instance" do
|
|
429
429
|
has_one :thingummy, :class => Outside::Other
|
430
430
|
end
|
431
431
|
end
|
432
|
-
}.should raise_error
|
432
|
+
}.should raise_error(ActiveFacts::API::CrossVocabularyRoleException)
|
433
433
|
end
|
434
434
|
|
435
435
|
it "should disallow unrecognised supertypes" do
|
@@ -514,7 +514,7 @@ describe "A Constellation instance" do
|
|
514
514
|
supertypes :name
|
515
515
|
end
|
516
516
|
end
|
517
|
-
}.should raise_error
|
517
|
+
}.should raise_error(ActiveFacts::API::InvalidSupertypeException)
|
518
518
|
end
|
519
519
|
|
520
520
|
it "should error on invalid :class values" do
|
@@ -524,7 +524,7 @@ describe "A Constellation instance" do
|
|
524
524
|
has_one :Name, :class => 3
|
525
525
|
end
|
526
526
|
end
|
527
|
-
}.should raise_error
|
527
|
+
}.should raise_error(ArgumentError)
|
528
528
|
end
|
529
529
|
|
530
530
|
it "should error on misleading :class values" do
|
@@ -534,7 +534,7 @@ describe "A Constellation instance" do
|
|
534
534
|
has_one :Name, :class => Extra
|
535
535
|
end
|
536
536
|
end
|
537
|
-
}.should raise_error
|
537
|
+
}.should raise_error(NameError)
|
538
538
|
end
|
539
539
|
|
540
540
|
it "should allow assert using an object of the same type" do
|
@@ -572,6 +572,6 @@ describe "A Constellation instance" do
|
|
572
572
|
lambda {
|
573
573
|
# Disallowed because it re-assigns the auto_counter_val identification value
|
574
574
|
p.employer = [ "foo", {:auto_counter_val => :new}]
|
575
|
-
}.should raise_error
|
575
|
+
}.should raise_error(ActiveFacts::API::TypeConflictException)
|
576
576
|
end
|
577
577
|
end
|
@@ -364,7 +364,7 @@ describe "An instance of every type of ObjectType" do
|
|
364
364
|
a = c.AutoCounterVal(:new)
|
365
365
|
lambda {
|
366
366
|
b = 2 + a
|
367
|
-
}.should raise_error
|
367
|
+
}.should raise_error(TypeError)
|
368
368
|
a.assign(3)
|
369
369
|
lambda {
|
370
370
|
b = 2 + a
|
@@ -376,21 +376,21 @@ describe "An instance of every type of ObjectType" do
|
|
376
376
|
c = ActiveFacts::API::Constellation.new(Mod)
|
377
377
|
lambda {
|
378
378
|
c.TestByInt(:int_val => nil)
|
379
|
-
}.should raise_error
|
379
|
+
}.should raise_error(ActiveFacts::API::MissingMandatoryRoleValueException)
|
380
380
|
end
|
381
381
|
|
382
382
|
it "should complain when too many identifying values are provided for an entity" do
|
383
383
|
c = ActiveFacts::API::Constellation.new(Mod)
|
384
384
|
lambda {
|
385
385
|
c.TestByInt(2, 3)
|
386
|
-
}.should raise_error
|
386
|
+
}.should raise_error(ActiveFacts::API::UnexpectedIdentifyingValueException)
|
387
387
|
end
|
388
388
|
|
389
389
|
it "should complain when wrong type is used for an entity" do
|
390
390
|
c = ActiveFacts::API::Constellation.new(Mod)
|
391
391
|
lambda {
|
392
392
|
c.TestByInt("Not an Int")
|
393
|
-
}.should raise_error
|
393
|
+
}.should raise_error(ArgumentError)
|
394
394
|
end
|
395
395
|
|
396
396
|
it "should handle a non-mandatory missing identifying role" do
|
@@ -96,6 +96,35 @@ describe "Roles" do
|
|
96
96
|
}.should raise_error(ActiveFacts::API::CrossVocabularyRoleException)
|
97
97
|
end
|
98
98
|
|
99
|
+
it "should prevent usage of undefined options on a role" do
|
100
|
+
lambda {
|
101
|
+
module Mod
|
102
|
+
class Existing1 < String
|
103
|
+
value_type
|
104
|
+
has_one :name, :foo => :anything
|
105
|
+
end
|
106
|
+
end
|
107
|
+
}.should raise_error(ActiveFacts::API::UnrecognisedOptionsException)
|
108
|
+
|
109
|
+
lambda {
|
110
|
+
module Mod
|
111
|
+
class Existing1 < String
|
112
|
+
value_type
|
113
|
+
one_to_one :name, :foo => :anything
|
114
|
+
end
|
115
|
+
end
|
116
|
+
}.should raise_error(ActiveFacts::API::UnrecognisedOptionsException)
|
117
|
+
|
118
|
+
lambda {
|
119
|
+
module Mod
|
120
|
+
class Existing1 < String
|
121
|
+
value_type
|
122
|
+
maybe :is_broken, :foo => :anything
|
123
|
+
end
|
124
|
+
end
|
125
|
+
}.should raise_error(ActiveFacts::API::UnrecognisedOptionsException)
|
126
|
+
end
|
127
|
+
|
99
128
|
it "should provide value type metadata" do
|
100
129
|
Mod::Name.length.should == 40
|
101
130
|
Mod::Name.scale.should == 0
|
@@ -37,7 +37,7 @@ describe "An Entity Type" do
|
|
37
37
|
has_one :name
|
38
38
|
end
|
39
39
|
end
|
40
|
-
end.should raise_error
|
40
|
+
end.should raise_error(ActiveFacts::API::InvalidIdentificationException)
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "when asserted" do
|
@@ -84,7 +84,7 @@ describe "An Entity Type" do
|
|
84
84
|
it "should fail if the new value already exists" do
|
85
85
|
proc do
|
86
86
|
@fly.name = 'Acme'
|
87
|
-
end.should raise_error
|
87
|
+
end.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should not fail if the new value is self" do
|
@@ -234,7 +234,7 @@ describe "An Entity Type" do
|
|
234
234
|
one_to_one :number # Error, invalid identifier
|
235
235
|
end
|
236
236
|
end
|
237
|
-
end.should raise_error
|
237
|
+
end.should raise_error(ActiveFacts::API::InvalidIdentificationException)
|
238
238
|
end
|
239
239
|
|
240
240
|
describe "when asserted" do
|
@@ -294,7 +294,7 @@ describe "An Entity Type" do
|
|
294
294
|
|
295
295
|
it "should fail if the new value already exists" do
|
296
296
|
@c.Room(@b, 102)
|
297
|
-
lambda { @r.number = 102 }.should raise_error
|
297
|
+
lambda { @r.number = 102 }.should raise_error(ActiveFacts::API::DuplicateIdentifyingValueException)
|
298
298
|
end
|
299
299
|
|
300
300
|
describe "to a previously-nonexistent value" do
|
@@ -337,6 +337,7 @@ describe "An Entity Type" do
|
|
337
337
|
end
|
338
338
|
|
339
339
|
it "the old value's back-reference is set to nil" do
|
340
|
+
# @rn.all_room.should_not include @r
|
340
341
|
@rn.all_room.to_a.should_not include @r
|
341
342
|
end
|
342
343
|
|
@@ -30,7 +30,7 @@ describe 'identity change on subtype' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should fail if the value is the same" do
|
33
|
-
lambda { @b = @constellation.EntityB(123, 'abc') }.should raise_error
|
33
|
+
lambda { @b = @constellation.EntityB(123, 'abc') }.should raise_error(ActiveFacts::API::UnexpectedIdentifyingValueException)
|
34
34
|
end
|
35
35
|
|
36
36
|
context "on a deep-subtype" do
|
@@ -60,4 +60,4 @@ describe 'identity change on subtype' do
|
|
60
60
|
@c.value_a.should == 987
|
61
61
|
end
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
@@ -75,12 +75,12 @@ describe "Entity Type class definitions" do
|
|
75
75
|
Mod::Person.roles.include?(:name).should be_true
|
76
76
|
end
|
77
77
|
|
78
|
-
it "should fail on a
|
78
|
+
it "should fail on a ValueType" do
|
79
79
|
lambda{
|
80
80
|
class SomeClass < String
|
81
|
-
identified_by
|
81
|
+
identified_by :foo
|
82
82
|
end
|
83
|
-
}.should raise_error
|
83
|
+
}.should raise_error(ActiveFacts::API::InvalidEntityException)
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should return the identifying roles" do
|
@@ -88,15 +88,15 @@ describe "Entity Type class definitions" do
|
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should prevent a role name from matching a object_type that exists unless that object_type is the counterpart" do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
91
|
+
proc do
|
92
|
+
module Mod
|
93
|
+
class LegalEntity
|
94
|
+
end
|
95
|
+
class Bad
|
96
|
+
identified_by :name
|
97
|
+
has_one :name, :class => LegalEntity
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end.should raise_error(ActiveFacts::API::CrossVocabularyRoleException)
|
101
101
|
end
|
102
102
|
end
|
@@ -38,7 +38,7 @@ describe "Multi-part identifiers" do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should sort child keys in the instance index" do
|
41
|
-
pending "Key sorting is not supported
|
41
|
+
pending "Key sorting is not supported on this index" unless @c.Child.sort
|
42
42
|
@c.Child.keys.should == [[[@p.parent_id], 0], [[@p.parent_id], 1], [[@p.parent_id], 2]]
|
43
43
|
@c.Child.map{|k, c| c.position}.should == [@c0.position, @c1.position, @c2.position]
|
44
44
|
end
|
@@ -47,7 +47,7 @@ describe "AutoCounter Value Type instances" do
|
|
47
47
|
it "should allow prevent invalid role assignment" do
|
48
48
|
lambda {
|
49
49
|
@thing.thing_id = "foo"
|
50
|
-
}.should raise_error
|
50
|
+
}.should raise_error(ArgumentError)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should not allow its value to be re-assigned" do
|
@@ -57,7 +57,7 @@ describe "AutoCounter Value Type instances" do
|
|
57
57
|
lambda {
|
58
58
|
@thing.thing_id.assign(4)
|
59
59
|
#@thing.thing_id.assign(@thing_id)
|
60
|
-
}.should raise_error
|
60
|
+
}.should raise_error(ArgumentError)
|
61
61
|
end
|
62
62
|
|
63
63
|
it "should allow an existing counter to be re-used" do
|
@@ -72,7 +72,7 @@ describe "AutoCounter Value Type instances" do
|
|
72
72
|
it "should not allow a counter to be cloned" do
|
73
73
|
lambda {
|
74
74
|
@thing_id.clone
|
75
|
-
}.should raise_error
|
75
|
+
}.should raise_error(RuntimeError)
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should allow an existing counter-identified object to be re-used" do
|
@@ -47,7 +47,7 @@ describe "Guid Value Type instances" do
|
|
47
47
|
it "should allow prevent invalid role assignment" do
|
48
48
|
lambda {
|
49
49
|
@thing.thing_id = "foo"
|
50
|
-
}.should raise_error
|
50
|
+
}.should raise_error(ArgumentError)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should allow an existing guid to be re-used" do
|
metadata
CHANGED
@@ -1,68 +1,60 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activefacts-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
5
|
-
prerelease:
|
4
|
+
version: 0.9.8
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Clifford Heath
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-13 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rbtree-pure
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
33
|
+
version: '10.1'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
40
|
+
version: '10.1'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: jeweler
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rspec
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,55 +69,48 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: ruby-debug
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: debugger
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: pry
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: rspec
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ~>
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ~>
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,7 +125,6 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: bundler
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ~>
|
148
130
|
- !ruby/object:Gem::Version
|
@@ -150,7 +132,6 @@ dependencies:
|
|
150
132
|
type: :development
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ~>
|
156
137
|
- !ruby/object:Gem::Version
|
@@ -158,7 +139,6 @@ dependencies:
|
|
158
139
|
- !ruby/object:Gem::Dependency
|
159
140
|
name: jeweler
|
160
141
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
142
|
requirements:
|
163
143
|
- - ~>
|
164
144
|
- !ruby/object:Gem::Version
|
@@ -166,7 +146,6 @@ dependencies:
|
|
166
146
|
type: :development
|
167
147
|
prerelease: false
|
168
148
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
149
|
requirements:
|
171
150
|
- - ~>
|
172
151
|
- !ruby/object:Gem::Version
|
@@ -174,34 +153,24 @@ dependencies:
|
|
174
153
|
- !ruby/object:Gem::Dependency
|
175
154
|
name: rdoc
|
176
155
|
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
156
|
requirements:
|
179
|
-
- -
|
157
|
+
- - '>='
|
180
158
|
- !ruby/object:Gem::Version
|
181
159
|
version: 2.4.2
|
182
160
|
type: :development
|
183
161
|
prerelease: false
|
184
162
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
163
|
requirements:
|
187
|
-
- -
|
164
|
+
- - '>='
|
188
165
|
- !ruby/object:Gem::Version
|
189
166
|
version: 2.4.2
|
190
|
-
description:
|
167
|
+
description: |2
|
191
168
|
|
192
169
|
The ActiveFacts API is a Ruby DSL for managing constellations of elementary facts.
|
193
|
-
|
194
|
-
|
195
|
-
or
|
196
|
-
|
197
|
-
binary relational (A rel B). Relational facts are consistently co-referenced, so
|
198
|
-
you
|
199
|
-
|
170
|
+
Each fact is either existential (a value or an entity), characteristic (boolean) or
|
171
|
+
binary relational (A rel B). Relational facts are consistently co-referenced, so you
|
200
172
|
can traverse them efficiently in any direction. Each constellation maintains constraints
|
201
|
-
|
202
173
|
over the fact population.
|
203
|
-
|
204
|
-
'
|
205
174
|
email: clifford.heath@gmail.com
|
206
175
|
executables: []
|
207
176
|
extensions: []
|
@@ -260,29 +229,25 @@ files:
|
|
260
229
|
homepage: http://github.com/cjheath/activefacts-api
|
261
230
|
licenses:
|
262
231
|
- MIT
|
232
|
+
metadata: {}
|
263
233
|
post_install_message:
|
264
234
|
rdoc_options: []
|
265
235
|
require_paths:
|
266
236
|
- lib
|
267
237
|
required_ruby_version: !ruby/object:Gem::Requirement
|
268
|
-
none: false
|
269
238
|
requirements:
|
270
|
-
- -
|
239
|
+
- - '>='
|
271
240
|
- !ruby/object:Gem::Version
|
272
241
|
version: '0'
|
273
|
-
segments:
|
274
|
-
- 0
|
275
|
-
hash: -1550200325745257681
|
276
242
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
277
|
-
none: false
|
278
243
|
requirements:
|
279
|
-
- -
|
244
|
+
- - '>='
|
280
245
|
- !ruby/object:Gem::Version
|
281
246
|
version: '0'
|
282
247
|
requirements: []
|
283
248
|
rubyforge_project:
|
284
|
-
rubygems_version:
|
249
|
+
rubygems_version: 2.0.5
|
285
250
|
signing_key:
|
286
|
-
specification_version:
|
251
|
+
specification_version: 4
|
287
252
|
summary: A fact-based data model DSL and API
|
288
253
|
test_files: []
|