boundy 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/boundy.rb +19 -0
- data/lib/boundy/bound.rb +65 -0
- data/lib/boundy/bound/comparator.rb +67 -0
- data/lib/boundy/bound/constrainer.rb +29 -0
- data/lib/boundy/bound/infinite.rb +46 -0
- data/lib/boundy/bound/infinite/above.rb +12 -0
- data/lib/boundy/bound/infinite/below.rb +13 -0
- data/lib/boundy/comparator.rb +19 -0
- data/lib/boundy/comparators.rb +28 -0
- data/lib/boundy/domain.rb +115 -0
- data/lib/boundy/domain/anterior.rb +45 -0
- data/lib/boundy/domain/builder.rb +31 -0
- data/lib/boundy/domain/comparator.rb +26 -0
- data/lib/boundy/domain/constrainer.rb +21 -0
- data/lib/boundy/domain/finite.rb +64 -0
- data/lib/boundy/domain/posterior.rb +43 -0
- data/lib/boundy/formatter.rb +9 -0
- data/lib/boundy/formatter/sql.rb +26 -0
- data/lib/boundy/formatter/sql/domain.rb +20 -0
- data/lib/boundy/formatter/sql/domain/plugin.rb +22 -0
- data/lib/boundy/formatter/sql/factory.rb +14 -0
- data/lib/boundy/formatter/sql/plugin.rb +38 -0
- data/lib/boundy/formatters/bound.rb +16 -0
- data/lib/boundy/formatters/domain.rb +12 -0
- data/lib/boundy/formatters/fixnum.rb +20 -0
- data/lib/boundy/formatters/sql/bound.rb +22 -0
- data/lib/boundy/formatters/sql/domain.rb +28 -0
- data/lib/boundy/formatters/sql/domain/anterior.rb +23 -0
- data/lib/boundy/formatters/sql/domain/finite.rb +24 -0
- data/lib/boundy/formatters/sql/domain/posterior.rb +23 -0
- data/lib/boundy/formatters/time.rb +42 -0
- data/lib/boundy/range/comparator.rb +38 -0
- data/lib/boundy/range/constrainer.rb +17 -0
- data/lib/boundy/time/comparator.rb +37 -0
- data/test/integration/boundy_test.rb +37 -0
- data/test/integration/domain_test.rb +18 -0
- data/test/integration/formatter/sql_test.rb +21 -0
- data/test/integration/test_helper.rb +14 -0
- data/test/unit/boundy/bound/comparator_test.rb +37 -0
- data/test/unit/boundy/bound/constrainer_test.rb +123 -0
- data/test/unit/boundy/bound/infinite/above_test.rb +36 -0
- data/test/unit/boundy/bound/infinite/below_test.rb +36 -0
- data/test/unit/boundy/bound/infinite_test.rb +0 -0
- data/test/unit/boundy/bound_test.rb +86 -0
- data/test/unit/boundy/comparator_test.rb +0 -0
- data/test/unit/boundy/domain/anterior_test.rb +103 -0
- data/test/unit/boundy/domain/comparator_test.rb +75 -0
- data/test/unit/boundy/domain/constrainer_test.rb +11 -0
- data/test/unit/boundy/domain/posterior_test.rb +75 -0
- data/test/unit/boundy/domain_test.rb +50 -0
- data/test/unit/boundy/formatter/sql/domain/plugin_test.rb +16 -0
- data/test/unit/boundy/formatter/sql/plugin_test.rb +50 -0
- data/test/unit/boundy/formatter/sql_test.rb +26 -0
- data/test/unit/boundy/formatters/bound_test.rb +43 -0
- data/test/unit/boundy/formatters/domain_test.rb +12 -0
- data/test/unit/boundy/formatters/sql/domain/anterior_test.rb +29 -0
- data/test/unit/boundy/formatters/sql/domain/finite_test.rb +35 -0
- data/test/unit/boundy/formatters/sql/domain/posterior_test.rb +30 -0
- data/test/unit/boundy/formatters/time_test.rb +27 -0
- data/test/unit/boundy/range/comparator_test.rb +44 -0
- data/test/unit/boundy/range/constrainer_test.rb +11 -0
- data/test/unit/boundy/time/comparator_test.rb +40 -0
- data/test/unit/test_helper.rb +14 -0
- metadata +154 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Boundy
|
2
|
+
module Domain
|
3
|
+
module Builder
|
4
|
+
def self.builders
|
5
|
+
[
|
6
|
+
{
|
7
|
+
bounds: {
|
8
|
+
from: Boundy::Bound::Infinite::Below,
|
9
|
+
to: Boundy::Bound
|
10
|
+
},
|
11
|
+
builder: Proc.new {|b,e| Boundy::Domain::Anterior.new(e) }
|
12
|
+
},
|
13
|
+
{
|
14
|
+
bounds: {
|
15
|
+
from: Boundy::Bound,
|
16
|
+
to: Boundy::Bound
|
17
|
+
},
|
18
|
+
builder: Proc.new {|b,e| Boundy::Domain::Finite.new(b,e) }
|
19
|
+
},
|
20
|
+
{
|
21
|
+
bounds: {
|
22
|
+
from: Boundy::Bound,
|
23
|
+
to: Boundy::Bound::Infinite::Above
|
24
|
+
},
|
25
|
+
builder: Proc.new {|b,e| Boundy::Domain::Posterior.new(b) }
|
26
|
+
}
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'boundy/comparator'
|
2
|
+
|
3
|
+
module Boundy
|
4
|
+
module Domain
|
5
|
+
class Comparator
|
6
|
+
include Boundy::Comparator
|
7
|
+
|
8
|
+
def initialize(datum, subject)
|
9
|
+
@datum = datum
|
10
|
+
@subject = subject
|
11
|
+
end
|
12
|
+
|
13
|
+
def after?
|
14
|
+
@subject.from > @datum && @subject.to >= @datum
|
15
|
+
end
|
16
|
+
|
17
|
+
def before?
|
18
|
+
@subject.from <= @datum && @subject.to < @datum
|
19
|
+
end
|
20
|
+
|
21
|
+
def within?
|
22
|
+
@subject.from <= @datum && @subject.to >= @datum
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'boundy/bound/constrainer'
|
2
|
+
require 'boundy/domain'
|
3
|
+
|
4
|
+
module Boundy
|
5
|
+
module Domain
|
6
|
+
class Constrainer
|
7
|
+
def initialize(me, other)
|
8
|
+
@me = me
|
9
|
+
@other = other
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def constrain
|
14
|
+
from = Boundy::Bound::Constrainer.new(@me.from, @other.from)
|
15
|
+
to = Boundy::Bound::Constrainer.new(@me.to, @other.to)
|
16
|
+
|
17
|
+
Boundy::Domain.new(from.max, to.min)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'boundy/domain'
|
2
|
+
|
3
|
+
module Boundy
|
4
|
+
module Domain
|
5
|
+
class Finite
|
6
|
+
def self.builder
|
7
|
+
{
|
8
|
+
bounds: {
|
9
|
+
from: Boundy::Bound,
|
10
|
+
to: Boundy::Bound
|
11
|
+
},
|
12
|
+
builder: Proc.new {|b,e| self.new(b,e) }
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
include Domain::Plugin
|
17
|
+
|
18
|
+
def initialize(b,e)
|
19
|
+
case b
|
20
|
+
when Boundy::Bound
|
21
|
+
@from = b
|
22
|
+
@to = e
|
23
|
+
else
|
24
|
+
raise "I can't convert #{b.class.name} into a Boundy::Domain::Finite"
|
25
|
+
end
|
26
|
+
unless valid?
|
27
|
+
raise "Backlooking ranges aren't allowed.\n\nFROM: #{@from.inspect}\nTO: #{@to.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid?
|
32
|
+
raise if from.nil?
|
33
|
+
raise if to.nil?
|
34
|
+
raise if from.class < Boundy::Bound::Infinite
|
35
|
+
raise if to.class < Boundy::Bound::Infinite
|
36
|
+
|
37
|
+
from <= to
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def strictly_earlier?(subject)
|
42
|
+
@from.before?(subject)
|
43
|
+
end
|
44
|
+
|
45
|
+
def strictly_after?(subject)
|
46
|
+
@to.after?(subject)
|
47
|
+
end
|
48
|
+
|
49
|
+
def partially_after?(subject)
|
50
|
+
@from.after?(subject) && @to.within?(subject)
|
51
|
+
end
|
52
|
+
|
53
|
+
def partially_before?(subject)
|
54
|
+
@from.within?(subject) && @to.before?(subject)
|
55
|
+
end
|
56
|
+
|
57
|
+
def partially_within?(subject)
|
58
|
+
[:within?, :partially_before?, :partially_after?].any? do |m|
|
59
|
+
send(m, subject)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'boundy/domain'
|
2
|
+
require 'boundy/bound'
|
3
|
+
require 'boundy/bound/infinite/below'
|
4
|
+
|
5
|
+
module Boundy
|
6
|
+
module Domain
|
7
|
+
class Posterior
|
8
|
+
def self.builder
|
9
|
+
{
|
10
|
+
bounds: {
|
11
|
+
from: Boundy::Bound::Infinite::Below,
|
12
|
+
to: Boundy::Bound
|
13
|
+
},
|
14
|
+
builder: Proc.new {|b,e| self.new(e)}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
include Domain::Plugin
|
19
|
+
|
20
|
+
def initialize(datum)
|
21
|
+
if datum.nil?
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
|
25
|
+
@from = Boundy::Bound::Infinite::Below.new
|
26
|
+
@to = case datum
|
27
|
+
when Boundy::Bound
|
28
|
+
datum
|
29
|
+
else
|
30
|
+
Boundy::Bound.new(datum)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def cute
|
35
|
+
"[-infinity, #{@to.datum}]"
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
"#<#{self.class.name} bounded above by #{@to.inspect}>"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'boundy'
|
2
|
+
require 'boundy/formatter/sql/plugin'
|
3
|
+
|
4
|
+
require 'punchout'
|
5
|
+
|
6
|
+
require 'boundy/formatter/sql/factory'
|
7
|
+
|
8
|
+
module Boundy
|
9
|
+
module Formatter
|
10
|
+
class Sql
|
11
|
+
def initialize(obj, name)
|
12
|
+
formatter_factory = Plugin.for(obj)
|
13
|
+
if formatter_factory.nil?
|
14
|
+
raise "No formatter registered for #{obj.class}: #{obj.inspect}"
|
15
|
+
end
|
16
|
+
@formatter = formatter_factory.build(obj, name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@formatter.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'boundy/formatters/sql/domain'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'boundy/formatter/sql/domain/plugin'
|
2
|
+
|
3
|
+
module Boundy
|
4
|
+
module Formatter
|
5
|
+
class Sql
|
6
|
+
class Domain
|
7
|
+
def initialize(obj, name)
|
8
|
+
@formatter = Plugin.for(obj).new(obj,name)
|
9
|
+
if @formatter.nil?
|
10
|
+
raise "No formatter registered for #{obj.inspect}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
@formatter.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Boundy
|
2
|
+
module Formatter
|
3
|
+
class Sql
|
4
|
+
class Domain
|
5
|
+
module Plugin
|
6
|
+
extend Punchout::Punchable
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
Boundy.logger.info "REGISTERING #{base} AS DOMAIN FORMATTER FOR #{base.type}"
|
10
|
+
matchable = Punchout::Matcher::Ancestry.new(base.type).punches(base)
|
11
|
+
puncher.add(matchable)
|
12
|
+
end
|
13
|
+
|
14
|
+
def for(obj)
|
15
|
+
punch(obj)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'boundy'
|
2
|
+
|
3
|
+
require 'punchout'
|
4
|
+
require 'boundy/formatter/sql/factory'
|
5
|
+
|
6
|
+
module Boundy
|
7
|
+
module Formatter
|
8
|
+
class Sql
|
9
|
+
module Plugin
|
10
|
+
extend Punchout::Punchable
|
11
|
+
class << self
|
12
|
+
|
13
|
+
module FactoryMethods
|
14
|
+
def factory
|
15
|
+
@factory ||= Factory.new(self)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def included(base)
|
20
|
+
# XXX: This should really become an explicit include.
|
21
|
+
unless base.respond_to?(:factory)
|
22
|
+
base.instance_exec do
|
23
|
+
extend FactoryMethods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Boundy.logger.info "REGISTERING #{base} AS FORMATTER FOR #{base.type}"
|
27
|
+
matchable = Punchout::Matcher::Ancestry.new(base.type).punches(base.factory)
|
28
|
+
puncher.add(matchable)
|
29
|
+
end
|
30
|
+
|
31
|
+
def for(obj)
|
32
|
+
punch(obj)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Boundy
|
2
|
+
module Formatters
|
3
|
+
class Fixnum
|
4
|
+
def initialize(num, name)
|
5
|
+
@num = num
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.type
|
9
|
+
::Fixnum
|
10
|
+
end
|
11
|
+
|
12
|
+
include Boundy::Formatters::Bound
|
13
|
+
include Boundy::Formatter::Sql::Plugin
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
@num
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'boundy/bound'
|
2
|
+
|
3
|
+
require 'boundy/formatter/sql/plugin'
|
4
|
+
|
5
|
+
require 'boundy/formatters/bound'
|
6
|
+
|
7
|
+
module Boundy::Formatters::Sql
|
8
|
+
class Bound
|
9
|
+
def self.type
|
10
|
+
Boundy::Bound
|
11
|
+
end
|
12
|
+
|
13
|
+
include Boundy::Formatters::Bound
|
14
|
+
include Boundy::Formatter::Sql::Plugin
|
15
|
+
|
16
|
+
def initialize(bound, name)
|
17
|
+
@formatter = Boundy::Formatter::Sql.new(bound.datum, name)
|
18
|
+
super(bound)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'boundy/formatter/sql/domain/plugin'
|
2
|
+
|
3
|
+
require 'boundy/formatters/domain'
|
4
|
+
|
5
|
+
module Boundy::Formatters::Sql
|
6
|
+
class Domain
|
7
|
+
def self.type
|
8
|
+
Boundy::Domain::Plugin
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(domain, name)
|
12
|
+
@formatter = Boundy::Formatter::Sql::Domain::Plugin.for(domain).new(domain,name)
|
13
|
+
if @formatter.nil?
|
14
|
+
raise "No formatter registered for #{obj.inspect}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
include Boundy::Formatter::Sql::Plugin
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
@formatter.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'boundy/formatters/sql/domain/anterior'
|
27
|
+
require 'boundy/formatters/sql/domain/finite'
|
28
|
+
require 'boundy/formatters/sql/domain/posterior'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'boundy/formatter/sql/domain/plugin'
|
2
|
+
require 'boundy/domain/anterior'
|
3
|
+
|
4
|
+
module Boundy::Formatters::Sql
|
5
|
+
class Domain
|
6
|
+
class Anterior
|
7
|
+
def self.type
|
8
|
+
Boundy::Domain::Anterior
|
9
|
+
end
|
10
|
+
|
11
|
+
include Boundy::Formatter::Sql::Domain::Plugin
|
12
|
+
|
13
|
+
def initialize(domain, name)
|
14
|
+
@name = name
|
15
|
+
@formatter = Boundy::Formatter::Sql.new(domain.from, name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{@name} >= '#{@formatter.to_s}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|