hyperdoc 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  hyperdoc
2
2
  ========
3
3
 
4
- hypertextual documents using plain old data structures
4
+ This library helps build hypertextual documents using plain old data structures which are designed for use in a REST friendly ecosystem. I'll be adding more here as I port the ideas over from the old repo. This is also part of a the upcoming open sourced General Assembly platform.
5
+
6
+ NOTE: This release is completely unoptimized! Work is being done to reduce the complexity of the behaviors Hyperdoc's exhibit before things are tuned.
5
7
 
6
8
  License
7
9
  -------
8
10
 
11
+ Thanks goes out to constantcontact/dash for allowing me to open source an *very early* prototype of these ideas. While it has evolved quite a bit since then, the core ideas have remained the same.
12
+
9
13
  While it might be controversial, I'm going to give CC a shot for code. The [CC FAQ](http://wiki.creativecommons.org/Frequently_Asked_Questions#Can_I_apply_a_Creative_Commons_license_to_software.3F) does not usually recommend it, though their reasons seem based around problems that a similar MIT style license does not address either. GPL compatibility is not a concern here either since I'd rather not see this relicensed under a more viral contract.
10
14
 
11
- <a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">hyperdoc</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://generalassemb.ly/" property="cc:attributionName" rel="cc:attributionURL">General Assembly</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.
15
+ <a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">hyperdoc</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://generalassemb.ly/" property="cc:attributionName" rel="cc:attributionURL">General Assembly</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.
File without changes
@@ -0,0 +1,154 @@
1
+ require_relative '../setup'
2
+
3
+ class ArrayTest < TestCase
4
+
5
+ def test_compact
6
+ obj = Hyperdoc.new('arr' => [1, nil, 2, nil, 3])
7
+ arr = obj.arr
8
+ compacted = arr.compact
9
+ assert_equal [1,2,3], compacted.meta.value
10
+ assert_equal arr.meta.parent, compacted.meta.parent
11
+ assert_equal arr.meta.key, compacted.meta.key
12
+ end
13
+
14
+ def test_compact_bang
15
+ arr = Hyperdoc.new([nil, 1, Hyperdoc.new(nil), 2, nil])
16
+ assert_equal arr, arr.compact!
17
+ assert_equal [1,2], arr.meta.value
18
+ end
19
+
20
+ def test_each
21
+ arr = Hyperdoc.new([{'a' => 'b'}, [3, 4]])
22
+ arr.each do |obj|
23
+ assert Hyperdoc::Type === obj
24
+ end
25
+ arr = Hyperdoc.new([0, 1])
26
+ arr.each do |obj|
27
+ assert !(Hyperdoc::Type === obj)
28
+ end
29
+ end
30
+
31
+ def test_first
32
+ arr = Hyperdoc.new([{'a' => 42}])
33
+ assert_equal 42, arr.first.a
34
+ end
35
+
36
+ def test_last
37
+ arr = Hyperdoc.new([0, 1, 2, 42])
38
+ assert_equal 42, arr.last
39
+ arr = Hyperdoc.new([0, 1, {}])
40
+ assert_equal 2, arr.last.meta.key
41
+ end
42
+
43
+ def test_map
44
+ arr = Hyperdoc.new([1,2,3])
45
+ assert_equal [-1,-2,-3], arr.map {|x| -x}.meta.value
46
+ arr = Hyperdoc.new([{'a' => 'b'}])
47
+ assert_equal ['a=b'], arr.map {|x| "a=#{x.a}"}.meta.value
48
+ obj = Hyperdoc.new({'arr' => [1,2,3]})
49
+ mapped_array = obj.arr.map {|x| -x}
50
+ assert_equal obj, mapped_array.meta.parent.box
51
+ assert_equal 'arr', mapped_array.meta.key
52
+ end
53
+
54
+ def test_map_bang
55
+ arr = Hyperdoc.new([{'a' => 1}, {'a' => 2}])
56
+ assert_equal arr, arr.map! {|x| x.a}
57
+ assert_equal [1,2], arr.meta.value
58
+ end
59
+
60
+ def test_push
61
+ arr = Hyperdoc.new([1,2,3])
62
+ arr.push(4)
63
+ arr << 5 << 6
64
+ assert_equal [1,2,3,4,5,6], arr.meta.value
65
+ end
66
+
67
+ def test_reduce
68
+ arr = Hyperdoc.new([0,1,2])
69
+ assert_equal 3, arr.reduce(:+)
70
+ assert_equal 3, arr.inject(:+)
71
+ assert_equal 0, arr.reduce(-3, :+)
72
+ assert_equal 3, arr.reduce {|x,y| x + y}
73
+ assert_equal 0, arr.reduce(-3) {|x,y| x + y}
74
+ assert_raise(ArgumentError) {arr.inject}
75
+ end
76
+
77
+ def test_reject
78
+ obj = Hyperdoc.new('arr' => (1..10).to_a)
79
+ arr = obj.arr
80
+ odds = arr.reject {|x| x % 2 == 0}
81
+ assert_equal [1,3,5,7,9], odds.meta.value
82
+ assert_equal arr.meta.parent, odds.meta.parent
83
+ assert_equal arr.meta.key, odds.meta.key
84
+ end
85
+
86
+ def test_reject_bang
87
+ arr = Hyperdoc.new([1,2,3,4])
88
+ assert_equal arr, arr.reject! {|x| x % 2 == 0}
89
+ assert_equal [1,3], arr.meta.value
90
+ end
91
+
92
+ def test_select
93
+ obj = Hyperdoc.new('arr' => (1..10).to_a)
94
+ arr = obj.arr
95
+ evens = arr.select {|x| x % 2 == 0}
96
+ assert_equal [2,4,6,8,10], evens.meta.value
97
+ assert_equal arr.meta.parent, evens.meta.parent
98
+ assert_equal arr.meta.key, evens.meta.key
99
+ end
100
+
101
+ def test_select_bang
102
+ arr = Hyperdoc.new([1,2,3,4])
103
+ assert_equal arr, arr.select! {|x| x % 2 == 0}
104
+ assert_equal [2,4], arr.meta.value
105
+ end
106
+
107
+ def test_sort
108
+ obj = Hyperdoc.new('arr' => [1,3,2,5,4])
109
+ arr = obj.arr
110
+ sorted = arr.sort
111
+ assert_equal [1,2,3,4,5], sorted.meta.value
112
+ assert_equal arr.meta.parent, sorted.meta.parent
113
+ assert_equal arr.meta.key, sorted.meta.key
114
+ sorted = arr.sort {|x, y| y <=> x}
115
+ assert_equal [5,4,3,2,1], sorted.meta.value
116
+ end
117
+
118
+ def test_sort_bang
119
+ arr = Hyperdoc.new([3,4,1,2])
120
+ assert_equal arr, arr.sort!
121
+ assert_equal [1,2,3,4], arr.meta.value
122
+ end
123
+
124
+ def test_sort_by
125
+ obj = Hyperdoc.new('arr' => [1,2,3,4])
126
+ arr = obj.arr
127
+ sorted = arr.sort_by {|x| -x}
128
+ assert_equal [4,3,2,1], sorted.meta.value
129
+ assert_equal arr.meta.parent, sorted.meta.parent
130
+ assert_equal arr.meta.key, sorted.meta.key
131
+ end
132
+
133
+ def test_sort_by_bang
134
+ arr = Hyperdoc.new([1,2,3,4])
135
+ assert_equal arr, arr.sort_by! {|x| -x}
136
+ assert_equal [4,3,2,1], arr.meta.value
137
+ end
138
+
139
+ def test_uniq
140
+ obj = Hyperdoc.new('arr' => [1,1,2,2,3,3])
141
+ arr = obj.arr
142
+ uniq = arr.uniq
143
+ assert_equal [1,2,3], uniq.meta.value
144
+ assert_equal arr.meta.parent, uniq.meta.parent
145
+ assert_equal arr.meta.key, uniq.meta.key
146
+ end
147
+
148
+ def test_uniq_bang
149
+ arr = Hyperdoc.new([1, 1, 2, 1, 1])
150
+ assert_equal arr, arr.uniq!
151
+ assert_equal [1,2], arr.meta.value
152
+ end
153
+
154
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../setup'
2
+
3
+ class BoxTest < TestCase
4
+
5
+ def test_match_delegation
6
+ assert Hyperdoc.new('abc') =~ /abc/
7
+ assert Hyperdoc.new('abc') !~ /xyz/
8
+ end
9
+
10
+ def test_to_s_delegation
11
+ assert_equal '?'.to_s, Hyperdoc.new('?').to_s
12
+ end
13
+
14
+ def test_comparison
15
+ assert Hyperdoc.new(a: 42) == {a: 42}
16
+ assert Hyperdoc.new(42) > 41
17
+ assert_equal 0, Hyperdoc.new(42) <=> Hyperdoc.new(42)
18
+ end
19
+
20
+ def test_value_extraction
21
+ assert_equal [42], Hyperdoc.new([42]).meta.value
22
+ assert_equal 42, Hyperdoc.new(42)
23
+ end
24
+
25
+ end
26
+
27
+ class CustomBaseTest < TestCase
28
+
29
+ class X
30
+ include Hyperdoc::Type
31
+ end
32
+
33
+ def test_hash_construction
34
+ obj = X.new(a: 42)
35
+ assert Hyperdoc::Type === obj
36
+ assert_equal 42, obj.a
37
+ end
38
+
39
+ def test_array_construciton
40
+ obj = X.new([42])
41
+ assert Hyperdoc::Type === obj
42
+ assert_equal 42, obj.first
43
+ end
44
+
45
+ def test_value_construction
46
+ assert_equal 42, X.new(42)
47
+ assert_equal nil, X.new(nil)
48
+ assert_equal "42", X.new("42")
49
+ end
50
+
51
+ end
@@ -0,0 +1,50 @@
1
+ require_relative '../setup'
2
+
3
+ class AccessBehaviorTest < TestCase
4
+
5
+ def setup
6
+ @hash = Hyperdoc.new('a' => 42, b: 43)
7
+ end
8
+
9
+ def test_accessor_synthesis
10
+ assert @hash.a == 42
11
+ assert @hash.respond_to?(:a)
12
+ assert @hash.b == 43
13
+ assert @hash.respond_to?(:b)
14
+ end
15
+
16
+ def test_missing_accessor_synthesis
17
+ assert @hash.blahblah.nil?
18
+ assert @hash.respond_to?(:blahblah)
19
+ end
20
+
21
+ def test_query_synthesis
22
+ assert @hash.a?
23
+ assert @hash.respond_to?(:a?)
24
+ assert @hash.b?
25
+ end
26
+
27
+ def test_missing_query_synthesis
28
+ assert !@hash.blahblah?
29
+ assert @hash.respond_to?(:blahblah?)
30
+ end
31
+
32
+ def test_assignment_synthesis
33
+ @hash.answer = 42
34
+ assert_equal 42, @hash.answer
35
+ assert @hash.respond_to?(:answer=)
36
+ end
37
+
38
+ end
39
+
40
+ class BoxingBehaviorTest < TestCase
41
+
42
+ def test_assignment_should_unbox
43
+ hash = {'b' => 42}
44
+ object = Hyperdoc.new({})
45
+ object.a = Hyperdoc.new(hash)
46
+ object.a = object.a # assign a boxed value which should become unboxed
47
+ assert_equal hash.class, object.a.meta.value.class
48
+ end
49
+
50
+ end
@@ -1,3 +1,5 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../library'
2
2
  require 'hyperdoc'
3
3
  require 'test/unit'
4
+
5
+ TestCase = Test::Unit::TestCase
data/hyperdoc.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'hyperdoc'
3
- gem.version = '0.1.0'
3
+ gem.version = '0.1.1'
4
4
  gem.date = '2012-05-18'
5
5
  gem.summary = "hypertextual documents using plain old data structures"
6
- gem.authors = ['strmpnk (Brian Mitchell)', 'John Paul Ashenfelter']
6
+ gem.authors = ['strmpnk (Brian Mitchell)', 'John Paul Ashenfelter', 'Robert Gleeson']
7
7
  gem.email = 'brian@generalassemb.ly'
8
8
  gem.homepage = 'https://github.com/generalassembly/hyperdoc'
9
9
  gem.require_paths = %w[library]
data/library/hyperdoc.rb CHANGED
@@ -0,0 +1,21 @@
1
+ module Hyperdoc
2
+
3
+ # value model
4
+ autoload :Array, 'hyperdoc/array'
5
+ autoload :Box, 'hyperdoc/box'
6
+ autoload :Factory, 'hyperdoc/factory'
7
+ autoload :Hash, 'hyperdoc/hash'
8
+ autoload :Type, 'hyperdoc/type'
9
+
10
+ # document model
11
+ autoload :Agent, 'hyperdoc/agent'
12
+ autoload :Meta, 'hyperdoc/meta'
13
+
14
+ # drivers
15
+ autoload :Couch, 'hyperdoc/couch'
16
+
17
+ def self.new(value)
18
+ Hyperdoc::Box.new(value)
19
+ end
20
+
21
+ end
File without changes
@@ -0,0 +1,158 @@
1
+ module Hyperdoc::Array
2
+
3
+ def [](key)
4
+ box(key, meta.value[key])
5
+ end
6
+
7
+ def []=(key, value)
8
+ value = unbox(value)
9
+ meta.value[key] = unbox(value)
10
+ end
11
+
12
+ def compact
13
+ rebox meta.value.compact
14
+ end
15
+
16
+ def compact!
17
+ meta.value.reject! {|x| x.nil?}
18
+ self
19
+ end
20
+
21
+ def each
22
+ meta.value.each_with_index do |value, i|
23
+ yield box(i, value)
24
+ end
25
+ self
26
+ end
27
+
28
+ def first
29
+ box(0, meta.value.first)
30
+ end
31
+
32
+ def last
33
+ box(meta.value.size - 1, meta.value.last)
34
+ end
35
+
36
+ def map
37
+ arr = []
38
+ each do |box|
39
+ arr << unbox(yield(box))
40
+ end
41
+ rebox(arr)
42
+ end
43
+
44
+ def map!
45
+ meta.value.map!.with_index do |x, i|
46
+ unbox(yield box(i, x))
47
+ end
48
+ self
49
+ end
50
+
51
+ def push(item)
52
+ meta.value.push unbox(item)
53
+ self
54
+ end
55
+ alias_method :<<, :push
56
+
57
+ def reduce(*args, &block)
58
+ case args.size
59
+ when 0
60
+ initial = false
61
+ block_given? or raise ArgumentError,
62
+ "no block given"
63
+ when 1
64
+ initial = block_given?
65
+ block = args[0].to_proc unless initial
66
+ when 2
67
+ initial = true
68
+ block = args[1].to_proc
69
+ else
70
+ raise ArgumentError,
71
+ "Too many arguments: #{args.size} for 0 to 2"
72
+ end
73
+ memo = initial ? args[0] : nil
74
+ meta.value.each_with_index do |value, i|
75
+ # set an initial memo on first loop unless we were passed one
76
+ memo = (!initial && i == 0) ?
77
+ box(i, value) :
78
+ block.call(memo, box(i, value))
79
+ end
80
+ memo
81
+ end
82
+ alias inject reduce
83
+
84
+ def reject
85
+ selected = meta.value.reject.with_index do |x, i|
86
+ yield box(i, x)
87
+ end
88
+ rebox(selected)
89
+ end
90
+
91
+ def reject!
92
+ meta.value.reject!.with_index do |x, i|
93
+ yield box(i, x)
94
+ end
95
+ self
96
+ end
97
+
98
+ def size
99
+ meta.value.size
100
+ end
101
+
102
+ def select
103
+ selected = meta.value.select.with_index do |x, i|
104
+ yield box(i, x)
105
+ end
106
+ rebox(selected)
107
+ end
108
+
109
+ def select!
110
+ meta.value.select!.with_index do |x, i|
111
+ yield box(i, x)
112
+ end
113
+ self
114
+ end
115
+
116
+ def sort
117
+ if block_given?
118
+ # box everything once and then sort the boxes
119
+ sorted = meta.value.map.with_index do |v, i|
120
+ box(i, v)
121
+ end.sort do |a,b|
122
+ yield a,b
123
+ end
124
+ else
125
+ sorted = meta.value.sort
126
+ end
127
+ rebox(sorted)
128
+ end
129
+
130
+ def sort!
131
+ meta.value.sort!
132
+ self
133
+ end
134
+
135
+ def sort_by
136
+ sorted = meta.value.sort_by.with_index do |x, i|
137
+ yield box(i, x)
138
+ end
139
+ rebox(sorted)
140
+ end
141
+
142
+ def sort_by!
143
+ meta.value.sort_by!.with_index do |x, i|
144
+ yield box(i, x)
145
+ end
146
+ self
147
+ end
148
+
149
+ def uniq
150
+ rebox meta.value.uniq
151
+ end
152
+
153
+ def uniq!
154
+ meta.value.uniq!
155
+ self
156
+ end
157
+
158
+ end
@@ -0,0 +1,5 @@
1
+ # Empty box subclass for generated nodes
2
+ class Hyperdoc::Box
3
+ include Hyperdoc::Type
4
+
5
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,68 @@
1
+ class Hyperdoc::Document
2
+ include Comparable
3
+ include Hyperdoc::Generator
4
+
5
+ def self.generate(types)
6
+ return self if types.empty?
7
+ @cache[types]
8
+ end
9
+
10
+ def self.inherited(subclass)
11
+ # inherit schema
12
+ # setup caches for subclass
13
+ end
14
+
15
+ def self.inspect
16
+ return name if name
17
+ base = self
18
+ base = base.superclass until base.name
19
+ behaviors = ancestors[1..-1] - base.ancestors
20
+ behaviors.empty? ?
21
+ "#{base}":
22
+ "#{base}(#{behaviors.join(',')})"
23
+ end
24
+
25
+ def self.on(selectors)
26
+ selectors.each do |code, type|
27
+ schema.register(code, type)
28
+ end
29
+ end
30
+
31
+ public
32
+
33
+ undef_method :=~
34
+ undef_method :nil?
35
+ undef_method :to_s
36
+
37
+ def <=>(other)
38
+ value <=> unbox(other)
39
+ end
40
+
41
+ def inspect
42
+ key ?
43
+ "#<#{self.class.inxpect}##{full_path.join('.')}: #{value.inspect}>":
44
+ "#<#{self.class.inspect}: #{value.inspect}>"
45
+ end
46
+
47
+ private
48
+
49
+ attr_accessor :key, :parent, :schema
50
+ attr_reader :value
51
+
52
+ def box()
53
+
54
+ end
55
+
56
+ def initialize(value)
57
+ @value = value
58
+ end
59
+
60
+ def rebox()
61
+
62
+ end
63
+
64
+ def unbox()
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,44 @@
1
+ module Hyperdoc::Factory
2
+
3
+ def inspect
4
+ return name if name
5
+ base = self
6
+ base = base.superclass until base.name
7
+ behaviors = ancestors[1..-1] - base.ancestors
8
+ behaviors.empty? ?
9
+ "#{base}":
10
+ "#{base}(#{behaviors.join(',')})"
11
+ end
12
+
13
+ def new(value)
14
+ # NOTE: this is unoptimized. Specialization will get more complex
15
+ # once selectors are added back. We'll delay optimizing this till
16
+ # after that feature is complete.
17
+ sub = Class.new(self)
18
+ type = value_type(value)
19
+ return value if type.nil?
20
+ sub.class_eval do
21
+ include type
22
+ undef_method :=~
23
+ end
24
+ sub.allocate.tap {|inst|
25
+ inst.meta.value = inst.send(:unbox, value)
26
+ inst.meta.box = inst
27
+ yield inst if block_given?
28
+ inst.send(:initialize)}
29
+ end
30
+
31
+ private
32
+
33
+ def value_type(value)
34
+ case value
35
+ when ::Hash
36
+ Hyperdoc::Hash
37
+ when ::Array
38
+ Hyperdoc::Array
39
+ else
40
+ nil
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,69 @@
1
+ module Hyperdoc::Hash
2
+
3
+ def [](key)
4
+ if meta.value.has_key?(key)
5
+ # Check natural type
6
+ box(key, meta.value[key])
7
+ elsif String === key
8
+ # Check symbol form
9
+ sym_key = key.to_sym
10
+ box(key, meta.value[sym_key])
11
+ else
12
+ # Check string form
13
+ str_key = key.to_s
14
+ box(key, meta.value[str_key])
15
+ end
16
+ end
17
+
18
+ def []=(key, value)
19
+ str_key = key.to_s
20
+ sym_key = key.to_sym
21
+ if meta.value.has_key?(sym_key)
22
+ if meta.value.has_key?(str_key)
23
+ meta.value[key] = unbox(value)
24
+ else
25
+ meta.value[sym_key] = unbox(value)
26
+ end
27
+ else
28
+ meta.value[str_key] = unbox(value)
29
+ end
30
+ end
31
+
32
+ def has_key?(key)
33
+ return true if meta.value.has_key?(key)
34
+ if String === key
35
+ meta.value.has_key?(key.to_sym)
36
+ else
37
+ meta.value.has_key?(key.to_s)
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def access_call(symbol, key)
44
+ cached_call(symbol) {box(key, self[key])}
45
+ end
46
+
47
+ def assign_call(symbol, key)
48
+ cached_call(symbol) {|v| self[key] = v}
49
+ end
50
+
51
+ def method_missing(symbol, *args, &blk)
52
+ case symbol
53
+ when /(.*)=$/
54
+ key = $1
55
+ assign_call(symbol, key).call(*args, &blk)
56
+ when /(.*)\?$/
57
+ key = $1
58
+ query_call(symbol, key).call(*args, &blk)
59
+ else
60
+ key = symbol.to_s
61
+ access_call(symbol, key).call(*args, &blk)
62
+ end
63
+ end
64
+
65
+ def query_call(symbol, key)
66
+ cached_call(symbol) {has_key?(key) && !!box(key, self[key])}
67
+ end
68
+
69
+ end
@@ -0,0 +1,14 @@
1
+ class Hyperdoc::Meta
2
+ attr_accessor :key, :value, :box, :parent
3
+
4
+ def inspect
5
+ "value=#{value.inspect}"
6
+ end
7
+
8
+ def path
9
+ path = parent ? (parent.path << key) : []
10
+ return if path.empty?
11
+ path.join('.')
12
+ end
13
+
14
+ end
@@ -0,0 +1,86 @@
1
+ =begin
2
+ # Overview
3
+
4
+ Hyperdoc::Type is included in classes which intend on constructing
5
+ document instances. It transforms the new() interface into a sort of
6
+ factory which generates a class with the appropriate sort of
7
+ combination of modules based on what it's wrapping. This is don't
8
+ rather than subclassing for precisely that sort of late-bound behavior.
9
+
10
+ ## Why Hyperdoc::Type and not some other name?
11
+
12
+ While it was originally going to be implemented directly on the
13
+ Hyperdoc module itself, this was a problem for constant lookup since
14
+ Hyperdoc implements many common constant names like Array and Hash, which
15
+ leads to a sort of ambiguity. This protects us somewhat by not creating
16
+ unintended ambiguity for those that include Hyperdoc::Type.
17
+
18
+ Type itself was chosen because it helps describe what it is. It's a sort of
19
+ Hyperdoc and will read well: Hyperdoc::Type === … Though we'll probably add
20
+ a simple implementation for Hyperdoc.=== which will delegate to
21
+ Hyperdoc::Type
22
+
23
+ =end
24
+
25
+ module Hyperdoc::Type
26
+ include Comparable
27
+
28
+ def self.append_features(_class)
29
+ Class === _class or raise ArgumentError,
30
+ "Hyperdoc::Type can only be included directly into a class, not a module"
31
+ super
32
+ _class.extend Hyperdoc::Factory
33
+ end
34
+
35
+ public
36
+
37
+ def <=>(other)
38
+ meta.value <=> unbox(other)
39
+ end
40
+
41
+ def inspect
42
+ meta.path ?
43
+ "#<#{self.class.inspect}##{meta.path}: #{meta.inspect}>":
44
+ "#<#{self.class.inspect}: #{meta.inspect}>"
45
+ end
46
+
47
+ def meta
48
+ @hyperdoc_meta ||= Hyperdoc::Meta.new
49
+ end
50
+
51
+ def to_s(*a)
52
+ meta.value.to_s(*a)
53
+ end
54
+
55
+ private
56
+
57
+ def box(key, value)
58
+ Hyperdoc::Box.new(value) { |box|
59
+ box.meta.key = key
60
+ box.meta.parent = meta
61
+ }
62
+ end
63
+
64
+ def rebox(value)
65
+ self.dup.tap { |box|
66
+ box.meta.value = value
67
+ box.meta.box = box
68
+ }
69
+ end
70
+
71
+ def unbox(object)
72
+ Hyperdoc::Type === object ? unbox(object.meta.value) : object
73
+ end
74
+
75
+ def cached_call(symbol, &proc)
76
+ unless self.respond_to?(symbol, true)
77
+ self.class.class_eval {define_method(symbol, &proc)}
78
+ end
79
+ proc
80
+ end
81
+
82
+ def scrub_call(symbol)
83
+ self.class.class_eval {undef_method symbol}
84
+ end
85
+
86
+ end
data/rakefile CHANGED
@@ -1,23 +1,16 @@
1
1
  task default: [:test, :build]
2
2
 
3
- task compile: 'lib/dash/selector.kpeg.rb'
4
-
5
3
  desc "check tests"
6
- task :test => :compile do
7
- ruby ENV['ONLY'] || 'test/check_all.rb'
4
+ task :test do
5
+ ruby ENV['ONLY'] || 'checks/all.rb'
8
6
  end
9
7
 
10
8
  desc "build dash gem"
11
- task :build => :compile do
12
- sh 'gem build dash.gemspec'
9
+ task :build do
10
+ sh 'gem build hyperdoc.gemspec'
13
11
  end
14
12
 
15
13
  desc "clean build artifacts"
16
14
  task :clean do
17
- rm 'lib/dash/selector.kpeg.rb'
18
- rm 'dash-*.gem'
19
- end
20
-
21
- file 'lib/dash/selector.kpeg.rb' => 'lib/dash/selector.kpeg' do
22
- sh "kpeg --stand-alone --force --output lib/dash/selector.kpeg.rb lib/dash/selector.kpeg"
23
- end
15
+ rm 'hyperdoc-*.gem'
16
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperdoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - strmpnk (Brian Mitchell)
9
9
  - John Paul Ashenfelter
10
+ - Robert Gleeson
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
@@ -14,7 +15,7 @@ date: 2012-05-18 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: celluloid
17
- requirement: &70332263351580 !ruby/object:Gem::Requirement
18
+ requirement: &70245880712420 !ruby/object:Gem::Requirement
18
19
  none: false
19
20
  requirements:
20
21
  - - ! '>='
@@ -22,10 +23,10 @@ dependencies:
22
23
  version: '0'
23
24
  type: :runtime
24
25
  prerelease: false
25
- version_requirements: *70332263351580
26
+ version_requirements: *70245880712420
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: excon
28
- requirement: &70332263350860 !ruby/object:Gem::Requirement
29
+ requirement: &70245880711820 !ruby/object:Gem::Requirement
29
30
  none: false
30
31
  requirements:
31
32
  - - ! '>='
@@ -33,10 +34,10 @@ dependencies:
33
34
  version: '0'
34
35
  type: :runtime
35
36
  prerelease: false
36
- version_requirements: *70332263350860
37
+ version_requirements: *70245880711820
37
38
  - !ruby/object:Gem::Dependency
38
39
  name: yajl-ruby
39
- requirement: &70332263350020 !ruby/object:Gem::Requirement
40
+ requirement: &70245880711180 !ruby/object:Gem::Requirement
40
41
  none: false
41
42
  requirements:
42
43
  - - ! '>='
@@ -44,10 +45,10 @@ dependencies:
44
45
  version: '0'
45
46
  type: :runtime
46
47
  prerelease: false
47
- version_requirements: *70332263350020
48
+ version_requirements: *70245880711180
48
49
  - !ruby/object:Gem::Dependency
49
50
  name: kpeg
50
- requirement: &70332263349300 !ruby/object:Gem::Requirement
51
+ requirement: &70245880710740 !ruby/object:Gem::Requirement
51
52
  none: false
52
53
  requirements:
53
54
  - - ! '>='
@@ -55,29 +56,34 @@ dependencies:
55
56
  version: '0'
56
57
  type: :development
57
58
  prerelease: false
58
- version_requirements: *70332263349300
59
+ version_requirements: *70245880710740
59
60
  description:
60
61
  email: brian@generalassemb.ly
61
62
  executables: []
62
63
  extensions: []
63
64
  extra_rdoc_files: []
64
65
  files:
66
+ - checks/all.rb
67
+ - checks/core/check_array.rb
68
+ - checks/core/check_document.rb
69
+ - checks/core/check_hash.rb
70
+ - checks/setup.rb
65
71
  - hyperdoc.gemspec
72
+ - library/hyperdoc/agent.rb
66
73
  - library/hyperdoc/array.rb
67
74
  - library/hyperdoc/box.rb
75
+ - library/hyperdoc/couch/database.rb
76
+ - library/hyperdoc/couch/document.rb
77
+ - library/hyperdoc/couch/view.rb
68
78
  - library/hyperdoc/couch.rb
79
+ - library/hyperdoc/document.rb
80
+ - library/hyperdoc/factory.rb
69
81
  - library/hyperdoc/hash.rb
70
- - library/hyperdoc/link.rb
71
82
  - library/hyperdoc/meta.rb
72
- - library/hyperdoc/nop.rb
73
- - library/hyperdoc/schema.rb
74
- - library/hyperdoc/selector.rb
75
- - library/hyperdoc/value.rb
83
+ - library/hyperdoc/type.rb
76
84
  - library/hyperdoc.rb
77
85
  - rakefile
78
86
  - README.md
79
- - test/check_all.rb
80
- - test/setup.rb
81
87
  homepage: https://github.com/generalassembly/hyperdoc
82
88
  licenses: []
83
89
  post_install_message:
File without changes