rubiks 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.rspec +4 -0
  2. data/.travis.yml +6 -0
  3. data/Gemfile +17 -2
  4. data/Guardfile +4 -4
  5. data/LICENSE.txt +1 -1
  6. data/README.md +9 -4
  7. data/Rakefile +3 -8
  8. data/lib/rubiks/nodes/annotated_node.rb +20 -0
  9. data/lib/rubiks/nodes/cube.rb +77 -0
  10. data/lib/rubiks/nodes/dimension.rb +54 -0
  11. data/lib/rubiks/nodes/hierarchy.rb +55 -0
  12. data/lib/rubiks/nodes/level.rb +29 -0
  13. data/lib/rubiks/nodes/measure.rb +66 -0
  14. data/lib/rubiks/nodes/schema.rb +61 -0
  15. data/lib/rubiks/nodes/validated_node.rb +47 -0
  16. data/lib/rubiks/version.rb +2 -2
  17. data/lib/rubiks.rb +6 -8
  18. data/rubiks.gemspec +5 -13
  19. data/spec/examples/mondrian_xml_example_spec.rb +91 -0
  20. data/spec/rubiks/nodes/annotated_node_spec.rb +24 -0
  21. data/spec/rubiks/nodes/cube_spec.rb +39 -0
  22. data/spec/rubiks/nodes/dimension_spec.rb +26 -0
  23. data/spec/rubiks/nodes/hierarchy_spec.rb +27 -0
  24. data/spec/rubiks/nodes/level_spec.rb +26 -0
  25. data/spec/rubiks/nodes/measure_spec.rb +31 -0
  26. data/spec/rubiks/nodes/schema_spec.rb +59 -0
  27. data/spec/rubiks/nodes/validated_node_spec.rb +49 -0
  28. data/spec/spec_helper.rb +22 -0
  29. data/spec/support/matchers/be_like.rb +24 -0
  30. data/spec/support/schema_context.rb +46 -0
  31. metadata +45 -144
  32. data/.simplecov +0 -6
  33. data/examples/finance/.rvmrc +0 -1
  34. data/examples/finance/Gemfile +0 -11
  35. data/examples/finance/app.rb +0 -14
  36. data/examples/finance/database.yml +0 -5
  37. data/examples/finance/domain.rb +0 -44
  38. data/examples/finance/setup +0 -46
  39. data/lib/rubiks/cube.rb +0 -95
  40. data/lib/rubiks/dimension.rb +0 -23
  41. data/lib/rubiks/hierarchy.rb +0 -15
  42. data/lib/rubiks/transformers/lookup_transformer.rb +0 -101
  43. data/test/rubiks/test_cube.rb +0 -15
  44. data/test/rubiks/test_dimension.rb +0 -11
  45. data/test/test_helper.rb +0 -6
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --order rand
2
+ --colour
3
+ --tty
4
+ --require rspec/pride --format RSpec::Pride
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ rvm:
4
+ - '1.9.2'
5
+ notifications:
6
+ email: false
data/Gemfile CHANGED
@@ -1,4 +1,19 @@
1
- source 'https://rubygems.org'
1
+ source 'http://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in rubiks.gemspec
3
+ # rubiks.gemspec defines the runtime dependencies
4
4
  gemspec
5
+
6
+ # Test and development dependencies are defined here
7
+ # so CI can include just test dependencies
8
+ group :test do
9
+ gem 'rake'
10
+ gem 'rspec'
11
+ gem 'rspec-pride'
12
+ end
13
+
14
+ group :development do
15
+ gem 'awesome_print'
16
+ gem 'pry'
17
+ gem 'pry-nav'
18
+ gem 'simplecov'
19
+ end
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
- guard 'minitest' do
2
- watch(%r|^test/(.*)\/?test_(.*)\.rb|)
3
- watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
4
- watch(%r|^test/test_helper\.rb|) { "test" }
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
5
  end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 MoneyDesktop Inc.
1
+ Copyright 2013 MoneyDesktop Inc.
2
2
  Copyright Rubiks contributors https://github.com/moneydesktop/rubiks/contributors
3
3
 
4
4
  MIT License
data/README.md CHANGED
@@ -1,13 +1,18 @@
1
1
  # Rubiks
2
2
 
3
- A Ruby OLAP Cube layer.
3
+ [![Gem Version](https://badge.fury.io/rb/rubiks.png)](http://badge.fury.io/rb/rubiks)
4
+ [![Build Status](https://secure.travis-ci.org/moneydesktop/rubiks.png?branch=master)](https://travis-ci.org/moneydesktop/rubiks)
5
+ [![Code Climate](https://codeclimate.com/github/moneydesktop/rubiks.png)](https://codeclimate.com/github/moneydesktop/rubiks)
4
6
 
5
- ## Usage
7
+ Rubiks is a Ruby gem that defines an OLAP schema with `#to_xml` to generate a Mondrian XML schema and `#to_json` for everything else.
6
8
 
7
- Add this line to your application's Gemfile:
9
+ ## Installation
8
10
 
9
- gem 'rubiks'
11
+ Run `gem install rubiks` to install the gem on its own.
12
+
13
+ Or you can add the following to your Gemfile and run the `bundle` command to install it.
10
14
 
15
+ gem 'rubiks'
11
16
 
12
17
  ## Contributing
13
18
 
data/Rakefile CHANGED
@@ -1,10 +1,5 @@
1
- require 'bundler/gem_tasks'
2
- require 'rake'
3
- require 'rake/testtask'
1
+ require 'rspec/core/rake_task'
4
2
 
5
- Rake::TestTask.new do |t|
6
- t.pattern = 'test/**/test_*.rb'
7
- t.libs.push 'test'
8
- end
3
+ RSpec::Core::RakeTask.new(:spec)
9
4
 
10
- task :default => :test
5
+ task :default => :spec
@@ -0,0 +1,20 @@
1
+ require 'rubiks/nodes/validated_node'
2
+
3
+ module ::Rubiks
4
+ class AnnotatedNode < ::Rubiks::ValidatedNode
5
+ value :name, String
6
+
7
+ validates :name_present
8
+
9
+ def name_present
10
+ errors << "Name required on #{self.class.name.split('::').last}" if self.name.blank?
11
+ end
12
+
13
+ def parse_name(name_value)
14
+ return if name_value.nil?
15
+
16
+ self.name = name_value.to_s
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,77 @@
1
+ require 'rubiks/nodes/annotated_node'
2
+ require 'rubiks/nodes/dimension'
3
+ require 'rubiks/nodes/measure'
4
+
5
+ module ::Rubiks
6
+
7
+ class Cube < ::Rubiks::AnnotatedNode
8
+ child :dimensions, [::Rubiks::Dimension]
9
+ child :measures, [::Rubiks::Measure]
10
+
11
+ validates :dimensions_present, :measures_present
12
+
13
+ def self.new_from_hash(hash={})
14
+ new_instance = new('',[],[])
15
+ return new_instance.from_hash(hash)
16
+ end
17
+
18
+ def from_hash(working_hash)
19
+ return self if working_hash.nil?
20
+ working_hash.stringify_keys!
21
+
22
+ parse_name(working_hash.delete('name'))
23
+ parse_dimensions(working_hash.delete('dimensions'))
24
+ parse_measures(working_hash.delete('measures'))
25
+ return self
26
+ end
27
+
28
+ def measures_present
29
+ if self.measures.present?
30
+ self.measures.each do |measure|
31
+ measure.validate
32
+ errors.push(*measure.errors)
33
+ end
34
+ else
35
+ errors << 'Measures Required for Cube'
36
+ end
37
+ end
38
+
39
+ def parse_measures(measures_array)
40
+ return if measures_array.nil? || measures_array.empty?
41
+
42
+ measures_array.each do |measure_hash|
43
+ self.measures << ::Rubiks::Measure.new_from_hash(measure_hash)
44
+ end
45
+ end
46
+
47
+ def dimensions_present
48
+ if self.dimensions.present?
49
+ self.dimensions.each do |dimension|
50
+ dimension.validate
51
+ errors.push(*dimension.errors)
52
+ end
53
+ else
54
+ errors << 'Dimensions Required for Cube'
55
+ end
56
+ end
57
+
58
+ def parse_dimensions(dimensions_array)
59
+ return if dimensions_array.nil? || dimensions_array.empty?
60
+
61
+ dimensions_array.each do |dimension_hash|
62
+ self.dimensions << ::Rubiks::Dimension.new_from_hash(dimension_hash)
63
+ end
64
+ end
65
+
66
+ def to_hash
67
+ hash = {}
68
+
69
+ hash['name'] = self.name.to_s if self.name.present?
70
+ hash['dimensions'] = self.dimensions.map(&:to_hash) if self.dimensions.present?
71
+ hash['measures'] = self.measures.map(&:to_hash) if self.measures.present?
72
+
73
+ return hash
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,54 @@
1
+ require 'rubiks/nodes/validated_node'
2
+ require 'rubiks/nodes/hierarchy'
3
+
4
+ module ::Rubiks
5
+
6
+ class Dimension < ::Rubiks::AnnotatedNode
7
+ child :hierarchies, [::Rubiks::Hierarchy]
8
+
9
+ validates :hierarchies_present
10
+
11
+ def self.new_from_hash(hash={})
12
+ new_instance = new('',[])
13
+ return new_instance.from_hash(hash)
14
+ end
15
+
16
+ def hierarchies_present
17
+ if self.hierarchies.present?
18
+ self.hierarchies.each do |hierarchy|
19
+ hierarchy.validate
20
+ errors.push(*hierarchy.errors)
21
+ end
22
+ else
23
+ errors << 'Hierarchies Required for Dimension'
24
+ end
25
+ end
26
+
27
+ def from_hash(working_hash)
28
+ return self if working_hash.nil?
29
+ working_hash.stringify_keys!
30
+
31
+ parse_name(working_hash.delete('name'))
32
+ parse_hierarchies(working_hash.delete('hierarchies'))
33
+ return self
34
+ end
35
+
36
+ def parse_hierarchies(hierarchies_array)
37
+ return if hierarchies_array.nil? || hierarchies_array.empty?
38
+
39
+ hierarchies_array.each do |hierarchy_hash|
40
+ self.hierarchies << ::Rubiks::Hierarchy.new_from_hash(hierarchy_hash)
41
+ end
42
+ end
43
+
44
+ def to_hash
45
+ hash = {}
46
+
47
+ hash['name'] = self.name.to_s if self.name.present?
48
+ hash['hierarchies'] = self.hierarchies.map(&:to_hash) if self.hierarchies.present?
49
+
50
+ return hash
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,55 @@
1
+ require 'rubiks/nodes/annotated_node'
2
+ require 'rubiks/nodes/level'
3
+
4
+ module ::Rubiks
5
+
6
+ class Hierarchy < ::Rubiks::AnnotatedNode
7
+ child :levels, [::Rubiks::Level]
8
+
9
+ validates :levels_present
10
+
11
+ def self.new_from_hash(hash={})
12
+ new_instance = new('',[])
13
+ return new_instance.from_hash(hash)
14
+ end
15
+
16
+ def levels_present
17
+ if self.levels.present?
18
+ self.levels.each do |level|
19
+ level.validate
20
+ errors.push(*level.errors)
21
+ end
22
+ else
23
+ errors << 'Levels Required for Hierarchy'
24
+ end
25
+ end
26
+
27
+ def from_hash(working_hash)
28
+ return self if working_hash.nil?
29
+ working_hash.stringify_keys!
30
+
31
+ parse_name(working_hash.delete('name'))
32
+ parse_levels(working_hash.delete('levels'))
33
+ return self
34
+ end
35
+
36
+ def parse_levels(levels_array)
37
+ return if levels_array.nil? || levels_array.empty?
38
+
39
+ levels_array.each do |level_hash|
40
+ self.levels << ::Rubiks::Level.new_from_hash(level_hash)
41
+ end
42
+ end
43
+
44
+ def to_hash
45
+ hash = {}
46
+
47
+ hash['name'] = self.name.to_s if self.name.present?
48
+ hash['levels'] = self.levels.map(&:to_hash) if self.levels.present?
49
+
50
+ return hash
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubiks/nodes/annotated_node'
2
+ require 'rubiks/nodes/hierarchy'
3
+
4
+ module ::Rubiks
5
+
6
+ class Level < ::Rubiks::AnnotatedNode
7
+ def self.new_from_hash(hash={})
8
+ new_instance = new
9
+ return new_instance.from_hash(hash)
10
+ end
11
+
12
+ def from_hash(working_hash)
13
+ return self if working_hash.nil?
14
+ working_hash.stringify_keys!
15
+
16
+ parse_name(working_hash.delete('name'))
17
+ return self
18
+ end
19
+
20
+ def to_hash
21
+ hash = {}
22
+
23
+ hash['name'] = self.name.to_s if self.name.present?
24
+
25
+ return hash
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,66 @@
1
+ require 'rubiks/nodes/validated_node'
2
+
3
+ module ::Rubiks
4
+
5
+ class Measure < ::Rubiks::AnnotatedNode
6
+ value :column, String
7
+ value :aggregator, String
8
+ value :format_string, String
9
+
10
+ validates :column_present, :aggregator_present
11
+
12
+ def self.new_from_hash(hash={})
13
+ new_instance = new
14
+ return new_instance.from_hash(hash)
15
+ end
16
+
17
+ def from_hash(working_hash)
18
+ return self if working_hash.nil?
19
+ working_hash.stringify_keys!
20
+
21
+ parse_name(working_hash.delete('name'))
22
+ parse_column(working_hash.delete('column'))
23
+ parse_aggregator(working_hash.delete('aggregator'))
24
+ parse_format_string(working_hash.delete('format_string'))
25
+ return self
26
+ end
27
+
28
+ def to_hash
29
+ hash = {}
30
+
31
+ hash['name'] = self.name.to_s if self.name.present?
32
+ hash['column'] = self.column.to_s if self.column.present?
33
+ hash['aggregator'] = self.aggregator.to_s if self.aggregator.present?
34
+ hash['format_string'] = self.format_string.to_s if self.format_string.present?
35
+
36
+ return hash
37
+ end
38
+
39
+ def column_present
40
+ errors << 'Column required on Measure' if self.column.blank?
41
+ end
42
+
43
+ def parse_column(column_value)
44
+ return if column_value.nil?
45
+
46
+ self.column = column_value.to_s
47
+ end
48
+
49
+ def aggregator_present
50
+ errors << 'Aggregator required on Measure' if self.aggregator.blank?
51
+ end
52
+
53
+ def parse_aggregator(aggregator_value)
54
+ return if aggregator_value.nil?
55
+
56
+ self.aggregator = aggregator_value.to_s
57
+ end
58
+
59
+ def parse_format_string(format_string_value)
60
+ return if format_string_value.nil?
61
+
62
+ self.format_string = format_string_value.to_s
63
+ end
64
+ end
65
+
66
+ end
@@ -0,0 +1,61 @@
1
+ require 'rubiks/nodes/validated_node'
2
+ require 'rubiks/nodes/cube'
3
+ require 'multi_json'
4
+
5
+ module ::Rubiks
6
+
7
+ class Schema < ::Rubiks::ValidatedNode
8
+ child :cubes, [::Rubiks::Cube]
9
+
10
+ validates :cubes_present
11
+
12
+ def self.new_from_hash(hash={})
13
+ new_instance = new([])
14
+ return new_instance.from_hash(hash)
15
+ end
16
+
17
+ def cubes_present
18
+ if self.cubes.present?
19
+ self.cubes.each do |cube|
20
+ cube.validate
21
+ errors.push(*cube.errors)
22
+ end
23
+ else
24
+ errors << 'Cubes Required for Schema'
25
+ end
26
+ end
27
+
28
+ def from_hash(working_hash)
29
+ return self if working_hash.nil?
30
+ working_hash.stringify_keys!
31
+
32
+ parse_cubes(working_hash.delete('cubes'))
33
+ return self
34
+ end
35
+
36
+ def parse_cubes(cubes_array)
37
+ return if cubes_array.nil? || cubes_array.empty?
38
+
39
+ cubes_array.each do |cube_hash|
40
+ self.cubes << ::Rubiks::Cube.new_from_hash(cube_hash)
41
+ end
42
+ end
43
+
44
+ def to_hash
45
+ hash = {}
46
+
47
+ hash['cubes'] = self.cubes.map(&:to_hash) if self.cubes.present?
48
+
49
+ return hash
50
+ end
51
+
52
+ def to_json
53
+ MultiJson.dump(to_hash)
54
+ end
55
+
56
+ def to_xml
57
+ to_hash.to_xml(:root => 'Schema')
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,47 @@
1
+ require 'rltk'
2
+ require 'rltk/ast'
3
+
4
+ module ::Rubiks
5
+ class ValidatedNode < ::RLTK::ASTNode
6
+
7
+ class << self
8
+ attr_accessor :validators
9
+
10
+ alias_method :validator_methods, :validators
11
+ end
12
+
13
+ def self.validates(*validator_symbols)
14
+ @validators ||= []
15
+ @validators << validator_symbols.flatten
16
+ @validators.flatten!
17
+ @validators.compact!
18
+ @validators.uniq!
19
+
20
+ return @validators
21
+ end
22
+
23
+ def self.inherited(klass)
24
+ super
25
+ klass.validators = self.validators.nil? ?
26
+ [] :
27
+ self.validators.dup
28
+ end
29
+
30
+ def errors
31
+ @errors ||= []
32
+ end
33
+
34
+ def valid?
35
+ validate if errors.empty?
36
+
37
+ return errors.empty?
38
+ end
39
+
40
+ def validate
41
+ self.class.validator_methods.each do |validator_method|
42
+ self.__send__(validator_method) if respond_to?(validator_method)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
- module Rubiks
2
- VERSION = '0.0.3'
1
+ module ::Rubiks
2
+ VERSION = '0.0.4'
3
3
  end
data/lib/rubiks.rb CHANGED
@@ -1,11 +1,9 @@
1
1
  require 'rubiks/version'
2
2
 
3
- module Rubiks
4
- autoload :Cube, 'rubiks/cube'
5
- autoload :Dimension, 'rubiks/dimension'
6
- autoload :Hierarchy, 'rubiks/hierarchy'
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'active_support/core_ext/hash/deep_dup'
5
+ require 'active_support/core_ext/hash/keys'
6
+ require 'active_support/core_ext/hash/conversions'
7
7
 
8
- module Transformers
9
- autoload :LookupTransformer, 'rubiks/transformers/lookup_transformer'
10
- end
11
- end
8
+ nodes_directory = File.expand_path('../rubiks/nodes', __FILE__)
9
+ Dir["#{nodes_directory}/*.rb"].each { |file| require file }
data/rubiks.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Rubiks::VERSION
9
9
  gem.authors = ['JohnnyT']
10
10
  gem.email = ['johnnyt@moneydesktop.com']
11
- gem.description = %q{A Ruby OLAP Cube library}
12
- gem.summary = gem.description
11
+ gem.description = %q{Define an OLAP schema}
12
+ gem.summary = 'Rubiks is a Ruby gem that defines an OLAP schema and can output the schema as XML and JSON.'
13
13
  gem.homepage = 'https://github.com/moneydesktop/rubiks'
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -17,15 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ['lib']
19
19
 
20
- gem.add_dependency 'arel'
21
-
22
- gem.add_development_dependency 'awesome_print'
23
- gem.add_development_dependency 'guard'
24
- gem.add_development_dependency 'guard-minitest'
25
- gem.add_development_dependency 'minitest'
26
- gem.add_development_dependency 'pry'
27
- gem.add_development_dependency 'rake'
28
- gem.add_development_dependency 'rb-fsevent'
29
- gem.add_development_dependency 'simplecov'
30
- gem.add_development_dependency 'simplecov-gem-adapter'
20
+ gem.add_dependency 'rltk'
21
+ gem.add_dependency 'activesupport'
22
+ gem.add_dependency 'builder'
31
23
  end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ # This example is taken from the Mondrian documentation:
4
+ # http://mondrian.pentaho.com/documentation/schema.php#Cubes_and_dimensions
5
+ # and then modified to use Rails/Rubiks conventions
6
+ #
7
+ # We want the output to be:
8
+ #
9
+ # <Schema>
10
+ # <Cube name="Sales">
11
+ # <Table name="view_sales"/>
12
+ #
13
+ # <Dimension name="Gender" foreignKey="customer_id">
14
+ # <Hierarchy hasAll="true" allMemberName="All Genders" primaryKey="id">
15
+ # <Table name="customers"/>
16
+ # <Level name="Gender" column="gender" uniqueMembers="true"/>
17
+ # </Hierarchy>
18
+ # </Dimension>
19
+ #
20
+ # <Dimension name="Date" foreignKey="date_id">
21
+ # <Hierarchy hasAll="false" primaryKey="id">
22
+ # <Table name="view_dates"/>
23
+ # <Level name="Year" column="year" type="Numeric" uniqueMembers="true"/>
24
+ # <Level name="Quarter" column="quarter" uniqueMembers="false"/>
25
+ # <Level name="Month" column="month_of_year" type="Numeric" uniqueMembers="false"/>
26
+ # </Hierarchy>
27
+ # </Dimension>
28
+ #
29
+ # <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="#,###"/>
30
+ # <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.##"/>
31
+ # <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
32
+ #
33
+ # <CalculatedMember name="Profit" dimension="Measures" formula="[Measures].[Store Sales] - [Measures].[Store Cost]">
34
+ # <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
35
+ # </CalculatedMember>
36
+ # </Cube>
37
+ # </Schema>
38
+
39
+ describe 'A basic Mondrian XML Schema' do
40
+ let(:described_class) { ::Rubiks::Schema }
41
+ let(:schema_hash) {
42
+ {
43
+ 'cubes' => [{
44
+ 'name' => 'sales',
45
+ 'measures' => [
46
+ {
47
+ 'name' => 'unit_sales',
48
+ 'aggregator' => 'sum',
49
+ 'format_string' => '#,###'
50
+ },
51
+ {
52
+ 'name' => 'store_sales',
53
+ 'aggregator' => 'sum',
54
+ 'format_string' => '#,###.##'
55
+ },
56
+ {
57
+ 'name' => 'store_cost',
58
+ 'aggregator' => 'sum',
59
+ 'format_string' => '#,###.00'
60
+ }
61
+ ],
62
+ 'dimensions' => [
63
+ {
64
+ 'name' => 'date',
65
+ 'hierarchies' => [{
66
+ 'name' => 'day_of_week',
67
+ 'levels' => [{
68
+ 'name' => 'day_of_week'
69
+ }]
70
+ }]
71
+ }
72
+ ]
73
+ }]
74
+ }
75
+ }
76
+
77
+ # subject { described_class.new_from_hash(schema_hash) }
78
+
79
+ # describe '#to_json' do
80
+ # it 'generates a JSON string' do
81
+ # subject.to_json.should be_kind_of String
82
+ # end
83
+
84
+ # it 'generates a valid JSON string' do
85
+ # lambda {
86
+ # MultiJson.load(subject.to_json)
87
+ # }.should_not raise_error MultiJson::LoadError
88
+ # end
89
+ # end
90
+
91
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ # describe ::Rubiks::AnnotatedNode do
4
+ # # API
5
+ # specify { subject.respond_to?(:from_hash) }
6
+ # specify { subject.respond_to?(:to_hash) }
7
+ #
8
+ # context 'when parsed from a valid hash' do
9
+ # subject { described_class.new.from_hash('name' => 'some_name') }
10
+ #
11
+ # its(:name) { should eq('some_name') }
12
+ #
13
+ # its(:to_hash) { should have_key('name') }
14
+ #
15
+ # it { should be_valid }
16
+ # end
17
+ #
18
+ # context 'when parsed from an invalid (empty) hash' do
19
+ # subject { described_class.new.from_hash({}) }
20
+ #
21
+ # it { should_not be_valid }
22
+ # end
23
+ #
24
+ # end