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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGZkZTdlNzAxMjA1YjIxOTA5YTk2NGY0MjY1ZjUzOWMxYTg0N2EyNA==
4
+ MTU2ZjBhNWE0NWVhZGZhMzM1OTQxMTUzNjYyNDlhMzU1ZTk2ZGQxNQ==
5
5
  data.tar.gz: !binary |-
6
- ZjBmZWI0OGQxZjRiMzEzNjNjMzliNDRjOTE4Mzk5NTAzNmYwOGU3YQ==
6
+ MDQ3OWFiOWIyMTIyZjFiODI2NmVlOGEzMGY1MWIyOGM0OTNjNGIyZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTc1ZmY5ZjY2MjcyOGQ5N2IwOWNkMzg4Zjc3OTU5ZDYwZDY1NTJkMjk3MDE4
10
- MGIzNmQ0NGNiMmNlYzAxMGU0MmYwN2E1ZGU4MjFjZWFiZjFiMTY3NzNmMjMw
11
- OTIzMmNhY2JkNjc3YjRhOThmZDNkNmJkY2JlMTAzNmUwZWUxNDY=
9
+ YzcxNWE1N2QxMzczNmEyMzk3M2Q4Yjg0M2EyZmM2OGE0MDI1NGRlZmE5MjZl
10
+ NGIzYTIzMWMzMTExYTc2NWU1ZGFmNjFkYmIzNTYyNTg5ZWY4N2Q1OTA4Yzc1
11
+ ODk5YjRjNGZkM2EyZDYzMjQzMzc1MGI3NzE2ZmQ2MGQ5ZDY5Mjg=
12
12
  data.tar.gz: !binary |-
13
- MWEwM2E4YmJiM2I1MzZhNjE3MWY0ZjhiNThkMjZlNzBkZjgyMjZkZTg5MDk0
14
- NjViN2JhMjU2NzU3MDczOGFlZmU2N2RjODk3NzU3MGM1MWI2NTVmNjc2MTg3
15
- NWI2NWU2NGViMjBlYTNmMmE2ZDMzNDMxY2FiYzdhMzA3OWIwMzU=
13
+ MmNjNDY2YTRjMjZkOTY2NzQ1YmU5MmE5OTdlZWJiMWIwNGYwMWNlMmY4ODJi
14
+ ZGQ2Yzg0YTI3N2I2NmJjZDIwYjRlY2NhYTU5MzZkMGU1MjBiODc0NzY4M2Ey
15
+ MjViYjg1MDFmYTk2MmUyNjZkYWI4NTJkMTY5MTQ2ZjZlNDBjZmY=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- space_object (0.0.1)
4
+ space_object (0.1.3)
5
5
  activesupport (~> 4.0)
6
6
 
7
7
  GEM
@@ -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,2 @@
1
+ class SpaceObject::EncodeError < StandardError
2
+ 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
@@ -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 and obj[key] = value
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
@@ -1,4 +1,4 @@
1
1
  module SpaceObject
2
2
  # space_object version
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.3"
4
4
  end
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
- it 'is an ActiveSupport::OrderedHash' do
5
- expect(subject).to be_an(ActiveSupport::OrderedHash)
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::Base.try_convert({'key' => 'value'})
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::Base.try_convert({'1' => '2', 'a' => 'b'})
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::Base.try_convert({
34
- 'foo' => SpaceObject::Base.try_convert({
35
- 'bar' => SpaceObject::Base.new,
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
@@ -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 = SpaceObject::Parser.new(test_document)
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
- SpaceObject.parse(test_document) and expect(SpaceObject::Parser).to have_received(:new).with(test_document)
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.stub(:parse)
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.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-06 00:00:00.000000000 Z
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