space_object 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile.lock +1 -1
- data/lib/space_object/base.rb +66 -0
- data/lib/space_object/core_ext/object/space_object.rb +100 -0
- data/lib/space_object/encode_error.rb +2 -0
- data/lib/space_object/encoder.rb +22 -0
- data/lib/space_object/parser.rb +4 -1
- data/lib/space_object/string_encodable.rb +19 -0
- data/lib/space_object/version.rb +1 -1
- data/lib/space_object.rb +6 -0
- data/spec/space_object/base_spec.rb +36 -2
- data/spec/space_object/encoder_spec.rb +24 -0
- data/spec/space_object/parser_spec.rb +6 -6
- data/spec/space_object_spec.rb +28 -4
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTU2ZjBhNWE0NWVhZGZhMzM1OTQxMTUzNjYyNDlhMzU1ZTk2ZGQxNQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDQ3OWFiOWIyMTIyZjFiODI2NmVlOGEzMGY1MWIyOGM0OTNjNGIyZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YzcxNWE1N2QxMzczNmEyMzk3M2Q4Yjg0M2EyZmM2OGE0MDI1NGRlZmE5MjZl
|
10
|
+
NGIzYTIzMWMzMTExYTc2NWU1ZGFmNjFkYmIzNTYyNTg5ZWY4N2Q1OTA4Yzc1
|
11
|
+
ODk5YjRjNGZkM2EyZDYzMjQzMzc1MGI3NzE2ZmQ2MGQ5ZDY5Mjg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MmNjNDY2YTRjMjZkOTY2NzQ1YmU5MmE5OTdlZWJiMWIwNGYwMWNlMmY4ODJi
|
14
|
+
ZGQ2Yzg0YTI3N2I2NmJjZDIwYjRlY2NhYTU5MzZkMGU1MjBiODc0NzY4M2Ey
|
15
|
+
MjViYjg1MDFmYTk2MmUyNjZkYWI4NTJkMTY5MTQ2ZjZlNDBjZmY=
|
data/Gemfile.lock
CHANGED
data/lib/space_object/base.rb
CHANGED
@@ -1,6 +1,72 @@
|
|
1
1
|
require 'active_support/ordered_hash'
|
2
|
+
require 'space_object/core_ext/object/space_object'
|
2
3
|
|
3
4
|
module SpaceObject
|
4
5
|
class Base < ActiveSupport::OrderedHash
|
6
|
+
def [](key)
|
7
|
+
key = convert_key!(key)
|
8
|
+
unless key[' ']
|
9
|
+
super(key)
|
10
|
+
else
|
11
|
+
first_key = key[/^[^ ]+/]
|
12
|
+
value = self[first_key]
|
13
|
+
|
14
|
+
return nil if hash.nil?
|
15
|
+
rest_keys = key[(first_key.length + 1)..-1]
|
16
|
+
value[rest_keys]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def []=(key, value)
|
21
|
+
key = convert_key!(key)
|
22
|
+
unless key[' ']
|
23
|
+
super(key, convert_value!(value))
|
24
|
+
else
|
25
|
+
first_key = key[/^[^ ]+/]
|
26
|
+
value = (self[first_key] ||= self.class.new)
|
27
|
+
value[(first_key.length + 1)..-1] = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :store, :[]=
|
32
|
+
|
33
|
+
def default(key = nil)
|
34
|
+
super(key ? convert_key!(key) : nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
def default=(val)
|
38
|
+
super(key ? convert_key!(key) : nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
def fetch(key, *extras)
|
42
|
+
key = convert_key!(key)
|
43
|
+
first_key = key[/^[^ ]+/]
|
44
|
+
|
45
|
+
value = self[first_key]
|
46
|
+
if key[' '].nil? || hash.nil?
|
47
|
+
super(key, *extras)
|
48
|
+
else
|
49
|
+
value.fetch(first_key, *extras)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def convert_key(key)
|
55
|
+
key.to_nested_space_key
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_key!(key)
|
59
|
+
raise(ArgumentError, "#{key.class} cannot be stored as a key in a #{self.class}") unless key.respond_to?(:to_nested_space_key)
|
60
|
+
convert_key(key)
|
61
|
+
end
|
62
|
+
|
63
|
+
def convert_value(val)
|
64
|
+
val.to_space_value
|
65
|
+
end
|
66
|
+
|
67
|
+
def convert_value!(val)
|
68
|
+
raise(ArgumentError, "#{val.class} cannot be stored as a key in a #{self.class}") unless val.respond_to?(:to_space_value)
|
69
|
+
convert_value(val)
|
70
|
+
end
|
5
71
|
end
|
6
72
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# List of classes to encode mirrors JSON encodable objects in ActiveSupport
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require 'space_object/string_encodable'
|
5
|
+
|
6
|
+
class Array
|
7
|
+
def to_space_object
|
8
|
+
each_with_index.map do |item, index|
|
9
|
+
{index => item}.to_space_object
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_space_value
|
14
|
+
to_space_object
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Date
|
19
|
+
include SpaceObject::StringEncodable
|
20
|
+
end
|
21
|
+
|
22
|
+
class DateTime
|
23
|
+
include SpaceObject::StringEncodable
|
24
|
+
end
|
25
|
+
|
26
|
+
module Enumerable
|
27
|
+
def to_space_object
|
28
|
+
to_a.to_space_object
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_space_value
|
32
|
+
to_space_object
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class FalseClass
|
37
|
+
include SpaceObject::StringEncodable
|
38
|
+
end
|
39
|
+
|
40
|
+
class Hash
|
41
|
+
def to_space_object
|
42
|
+
SpaceObject::Encoder.new(self).encode
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class NilClass
|
47
|
+
include SpaceObject::StringEncodable
|
48
|
+
end
|
49
|
+
|
50
|
+
class Numeric
|
51
|
+
include SpaceObject::StringEncodable
|
52
|
+
end
|
53
|
+
|
54
|
+
class Object
|
55
|
+
# Highly inspired by ActiveSupport
|
56
|
+
def to_space_object
|
57
|
+
hash = respond_to?(:to_hash) ? to_hash : insance_values
|
58
|
+
hash.to_space_object
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_space_value
|
62
|
+
to_space_object
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Process::Status
|
67
|
+
include SpaceObject::StringEncodable
|
68
|
+
end
|
69
|
+
|
70
|
+
class Regexp
|
71
|
+
include SpaceObject::StringEncodable
|
72
|
+
end
|
73
|
+
|
74
|
+
class String
|
75
|
+
include SpaceObject::StringEncodable
|
76
|
+
end
|
77
|
+
|
78
|
+
class Symbol
|
79
|
+
include SpaceObject::StringEncodable
|
80
|
+
end
|
81
|
+
|
82
|
+
class Struct
|
83
|
+
# Highly inspired by ActiveSupport
|
84
|
+
def to_space_object
|
85
|
+
hash = Hash[members.zip(values)]
|
86
|
+
hash.to_space_object
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_space_value
|
90
|
+
to_space_object
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Time
|
95
|
+
include SpaceObject::StringEncodable
|
96
|
+
end
|
97
|
+
|
98
|
+
class TrueClass
|
99
|
+
include SpaceObject::StringEncodable
|
100
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'space_object/base'
|
2
|
+
|
3
|
+
module SpaceObject
|
4
|
+
class Encoder
|
5
|
+
def initialize(object, options = {})
|
6
|
+
self.object = object
|
7
|
+
@as_key = !options.has_key?(:key) || options[:key]
|
8
|
+
end
|
9
|
+
|
10
|
+
def encode
|
11
|
+
raise(ArgumentError, "#{@object} is not a Hash") unless @object.is_a?(Hash)
|
12
|
+
@object.inject(Base.new) do |space, (key, val)|
|
13
|
+
space[key.to_space_key] = val.to_space_value
|
14
|
+
space
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def object=(object)
|
19
|
+
@object = object
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/space_object/parser.rb
CHANGED
@@ -19,6 +19,9 @@ module SpaceObject
|
|
19
19
|
@document = @document.strip.gsub(/(\r\n|\n\r|\n\n+)/, "\n")
|
20
20
|
end
|
21
21
|
|
22
|
+
def populate_space(space, str)
|
23
|
+
end
|
24
|
+
|
22
25
|
def parse_string(str)
|
23
26
|
str.split(DELIMITER).inject(Base.new) do |obj, space|
|
24
27
|
key, value = if matches = KEY_LINE.match(space)
|
@@ -28,7 +31,7 @@ module SpaceObject
|
|
28
31
|
offset = matches[1].length + 1
|
29
32
|
[matches[1], space[offset..-1].gsub(NEST_SPACING, "\n")]
|
30
33
|
end
|
31
|
-
key
|
34
|
+
(key.nil? || key.empty?) or obj[key] = value
|
32
35
|
obj
|
33
36
|
end
|
34
37
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'space_object/encode_error'
|
2
|
+
|
3
|
+
module SpaceObject
|
4
|
+
module StringEncodable
|
5
|
+
def to_nested_space_key
|
6
|
+
to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_space_key
|
10
|
+
str = to_nested_space_key
|
11
|
+
raise(EncodeError, "`#{str}' contains spaces and cannot be used as a key") if str[' ']
|
12
|
+
str
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_space_value
|
16
|
+
to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/space_object/version.rb
CHANGED
data/lib/space_object.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require 'space_object/version'
|
2
|
+
require 'space_object/encode_error'
|
2
3
|
require 'space_object/base'
|
3
4
|
require 'space_object/parser'
|
5
|
+
require 'space_object/encoder'
|
4
6
|
|
5
7
|
module SpaceObject
|
6
8
|
class << self
|
9
|
+
def encode(object)
|
10
|
+
Encoder.new(object).encode
|
11
|
+
end
|
12
|
+
|
7
13
|
def parse(document)
|
8
14
|
Parser.new(document).parse
|
9
15
|
end
|
@@ -1,7 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SpaceObject::Base do
|
4
|
-
|
5
|
-
|
4
|
+
let(:key) { 'foo' }
|
5
|
+
let(:not_contained) { 'baz' }
|
6
|
+
let(:value) { 'bar' }
|
7
|
+
|
8
|
+
it 'is an Enumerable' do
|
9
|
+
expect(subject).to be_an(Enumerable)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '[]' do
|
13
|
+
subject { SpaceObject.encode({key => value}) }
|
14
|
+
|
15
|
+
it 'returns nil if the key does not exist' do
|
16
|
+
expect(subject[not_contained]).to be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns the value for a key which exists' do
|
20
|
+
expect(subject[key]).to eq(value)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can query with a key which implements #to_s' do
|
24
|
+
expect(subject[key.to_sym]).to eq(subject[key])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '[]=' do
|
29
|
+
subject { SpaceObject::Base.new }
|
30
|
+
|
31
|
+
it 'can assign with a non-nested key' do
|
32
|
+
subject[key] = value
|
33
|
+
expect(subject[key]).to eq(value)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can assign with a key which implements #to_s' do
|
37
|
+
subject[key.to_sym] = value
|
38
|
+
expect(subject[key]).to eq(value)
|
39
|
+
end
|
6
40
|
end
|
7
41
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SpaceObject::Encoder do
|
4
|
+
let(:valid_example) { {:hello => 'world', 'foo' => :bar, 'foobar' => {'baz' => 'zip'}} }
|
5
|
+
let(:invalid_example) { { 'keys are not allowed' => 'value' } }
|
6
|
+
let(:wrong_class) { ['foo'] }
|
7
|
+
|
8
|
+
describe '#encode' do
|
9
|
+
it 'only encodes Hash objects' do
|
10
|
+
expect { SpaceObject::Encoder.new(wrong_class).encode }.to raise_error(ArgumentError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'encodes a compliant Hash as a SpaceObject::Base' do |variable|
|
14
|
+
space = SpaceObject::Encoder.new(valid_example).encode
|
15
|
+
expect(space['hello']).to eq('world')
|
16
|
+
expect(space['foo']).to eq('bar')
|
17
|
+
expect(space['foobar baz']).to eq('zip')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises a SpaceObject::EncodeError if an invalid key is present' do
|
21
|
+
expect { SpaceObject::Encoder.new(invalid_example).encode }.to raise_error(SpaceObject::EncodeError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -19,22 +19,22 @@ describe SpaceObject::Parser do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
context 'when given a key-value pair' do
|
22
|
-
it_has_behavior 'correctness', 'key value', SpaceObject
|
22
|
+
it_has_behavior 'correctness', 'key value', SpaceObject.encode({'key' => 'value'})
|
23
23
|
end
|
24
24
|
|
25
25
|
context 'when given multiple key-value pairs' do
|
26
|
-
it_has_behavior 'correctness', "1 2\na b", SpaceObject
|
26
|
+
it_has_behavior 'correctness', "1 2\na b", SpaceObject.encode({'1' => '2', 'a' => 'b'})
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'when given a nested space' do
|
30
30
|
document = "foo\n" +
|
31
31
|
" bar\n" +
|
32
32
|
" baz foobar"
|
33
|
-
expected = SpaceObject
|
34
|
-
'foo' =>
|
35
|
-
'bar' =>
|
33
|
+
expected = SpaceObject.encode({
|
34
|
+
'foo' => {
|
35
|
+
'bar' => {},
|
36
36
|
'baz' => 'foobar'
|
37
|
-
}
|
37
|
+
}
|
38
38
|
})
|
39
39
|
it_has_behavior 'correctness', document, expected
|
40
40
|
end
|
data/spec/space_object_spec.rb
CHANGED
@@ -5,21 +5,45 @@ describe SpaceObject do
|
|
5
5
|
expect(subject.const_get('VERSION')).not_to be_empty
|
6
6
|
end
|
7
7
|
|
8
|
+
describe(:encode) do
|
9
|
+
let(:hash) { {'foo' => 'bar'} }
|
10
|
+
let(:encoder) { SpaceObject::Encoder.new(hash) }
|
11
|
+
|
12
|
+
before(:each) {
|
13
|
+
@instance = encoder
|
14
|
+
@instance.stub(:encode)
|
15
|
+
SpaceObject::Encoder.stub(:new).and_return(@instance)
|
16
|
+
|
17
|
+
SpaceObject.encode(hash)
|
18
|
+
}
|
19
|
+
|
20
|
+
it "creates a new SpaceObject::Encoder" do
|
21
|
+
expect(SpaceObject::Encoder).to have_received(:new).with(hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "calls SpaceObject::Parser#encode" do
|
25
|
+
expect(@instance).to have_received(:encode)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
8
29
|
describe "::parse" do
|
9
30
|
let(:test_document) { 'foo bar' }
|
31
|
+
let(:parser) { SpaceObject::Parser.new(test_document) }
|
10
32
|
|
11
33
|
before(:each) {
|
12
|
-
@instance =
|
34
|
+
@instance = parser
|
35
|
+
@instance.stub(:parse)
|
13
36
|
SpaceObject::Parser.stub(:new).and_return(@instance)
|
37
|
+
|
38
|
+
SpaceObject.parse(test_document)
|
14
39
|
}
|
15
40
|
|
16
41
|
it "creates a new SpaceObject::Parser" do
|
17
|
-
|
42
|
+
expect(SpaceObject::Parser).to have_received(:new).with(test_document)
|
18
43
|
end
|
19
44
|
|
20
45
|
it "calls SpaceObject::Parser#parse" do
|
21
|
-
@instance.
|
22
|
-
SpaceObject.parse(test_document) and expect(@instance).to have_received(:parse)
|
46
|
+
expect(@instance).to have_received(:parse)
|
23
47
|
end
|
24
48
|
end
|
25
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: space_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Fruchtman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -83,10 +83,15 @@ files:
|
|
83
83
|
- Rakefile
|
84
84
|
- lib/space_object.rb
|
85
85
|
- lib/space_object/base.rb
|
86
|
+
- lib/space_object/core_ext/object/space_object.rb
|
87
|
+
- lib/space_object/encode_error.rb
|
88
|
+
- lib/space_object/encoder.rb
|
86
89
|
- lib/space_object/parser.rb
|
90
|
+
- lib/space_object/string_encodable.rb
|
87
91
|
- lib/space_object/version.rb
|
88
92
|
- space_object.gemspec
|
89
93
|
- spec/space_object/base_spec.rb
|
94
|
+
- spec/space_object/encoder_spec.rb
|
90
95
|
- spec/space_object/parser_spec.rb
|
91
96
|
- spec/space_object_spec.rb
|
92
97
|
- spec/spec_helper.rb
|
@@ -116,6 +121,7 @@ specification_version: 4
|
|
116
121
|
summary: A lightweight language for objects
|
117
122
|
test_files:
|
118
123
|
- spec/space_object/base_spec.rb
|
124
|
+
- spec/space_object/encoder_spec.rb
|
119
125
|
- spec/space_object/parser_spec.rb
|
120
126
|
- spec/space_object_spec.rb
|
121
127
|
- spec/spec_helper.rb
|