schema 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Daniel Kirsch
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Schema
2
+
3
+ Schema is a mechanism for enforcing schemas for ruby hashes. Type conversions are specified in a schema-hash and applied to a hash that shall be transformed.
4
+
5
+ ### SYNOPSIS
6
+
7
+ Schema.transform({:float => '42', :array_of_strings => 23}, {:float => Float, :array_of_strings => [String]})
8
+ # => {:float => 42.0, :array_of_strings => ['23']}
9
+
10
+ ### Schemas
11
+
12
+ A Schema is either a type that implements `#from` or a hash of schemas or an array with a schema as it's singgle element.
13
+
14
+ Float # is a schema
15
+ [Float] # is a schema
16
+ { :string => String } # is a schema
17
+ { :foo => [{ :bar => DateTime }]} # is a schema
18
+
19
+ ### Note on Patches/Pull Requests
20
+
21
+ * Fork the project.
22
+ * Make your feature addition or bug fix.
23
+ * Add tests for it. This is important so I don't break it in a
24
+ future version unintentionally.
25
+ * Commit, do not mess with rakefile, version, or history.
26
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
27
+ * Send me a pull request. Bonus points for topic branches.
28
+
29
+ ### Copyright
30
+
31
+ Copyright (c) 2010 Daniel Kirsch. See LICENSE for details.
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ require './lib/schema/version'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "schema"
9
+ gem.summary = %Q{Schemas for hashes}
10
+ gem.description = %Q{Deep type conversion through schemas for hashes}
11
+ gem.email = "danishkirel@gmail.com"
12
+ gem.homepage = "http://github.com/kirel/schema"
13
+ gem.authors = ["Daniel Kirsch"]
14
+ gem.add_development_dependency "rspec", "~> 2.2"
15
+ gem.add_development_dependency "yard", ">= 0"
16
+ gem.version = Schema::VERSION
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rspec/core/rake_task'
25
+
26
+ RSpec::Core::RakeTask.new(:spec)
27
+
28
+ task :spec => :check_dependencies
29
+ task :default => :spec
30
+
31
+ begin
32
+ require 'yard'
33
+ YARD::Rake::YardocTask.new
34
+ rescue LoadError
35
+ task :yardoc do
36
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
37
+ end
38
+ end
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,4 @@
1
+ require 'schema/version'
2
+ require 'schema/schema'
3
+ require 'schema/core_ext'
4
+ require 'schema/include'
@@ -0,0 +1,31 @@
1
+ require 'date'
2
+
3
+ class Float
4
+ def self.from val
5
+ val.to_f
6
+ end
7
+ end
8
+
9
+ class Integer
10
+ def self.from val
11
+ val.to_i
12
+ end
13
+ end
14
+
15
+ class String
16
+ def self.from val
17
+ val.to_s
18
+ end
19
+ end
20
+
21
+ class Date
22
+ def self.from val
23
+ parse val
24
+ end
25
+ end
26
+
27
+ class DateTime
28
+ def self.from val
29
+ parse val
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Schema
2
+ module Include
3
+ # Include this module into Object to have a handy #transform on every object.
4
+ # Then object.transform(schema) is like calling Schema.transform(object, schema).
5
+ def transform schema
6
+ Schema.transform self, schema
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Schema
2
+ # transform
3
+ # @param object The object to be transformed.
4
+ # @param schema A valid schema. For hashes only hashes and for arrays only arrays are valid schemas.
5
+ # For everything else either a type (e.g. <tt>Float</tt>)
6
+ # or an Array with a single type element (e.g. <tt>[String]</tt>) is a valid Schema.
7
+ def self.transform object, schema
8
+ case schema
9
+ when Array
10
+ raise ArgumentError, "An empty Array is not a valid schema." unless schema.first
11
+ # for now we only transform into the first schema-array element
12
+ case object
13
+ when nil
14
+ []
15
+ when Array
16
+ object.map { |e| e.transform(schema.first) }
17
+ else
18
+ [object.transform(schema.first)]
19
+ end
20
+ when Hash
21
+ raise ArgumentError, "A #{schema.class} is no valid schema for a #{object.class}." unless object.is_a?(Hash)
22
+ schema.inject({}) do |h, (key, subschema)|
23
+ h.update(key => object[key].transform(subschema))
24
+ end
25
+ else
26
+ schema.from(object)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Schema
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ Object.send :include, Schema::Include
4
+
5
+ describe "Schema" do
6
+
7
+ it "should cast simple types" do
8
+ 42.transform(String).should == '42'
9
+ 42.transform(String).should be_kind_of(String)
10
+ '42'.transform(Float).should == 42.0
11
+ '42'.transform(Float).should be_kind_of(Float)
12
+ '42'.transform(Integer).should == 42
13
+ '42'.transform(Integer).should be_kind_of(Integer)
14
+ end
15
+
16
+ it "should cast dates" do
17
+ '2010-12-01T12:00:00+01:00'.transform(DateTime).should == DateTime.parse('2010-12-01T12:00:00+01:00')
18
+ '2010-12-01'.transform(Date).should == Date.parse('2010-12-01')
19
+ end
20
+
21
+ it "should cast hashes of simple types" do
22
+ {:string => 'string'}.transform({:string => String}).should == {:string => 'string'}
23
+ {:float => '42'}.transform({:float => Float}).should == {:float => 42.0}
24
+ {:integer => '42'}.transform({:integer => Integer}).should == {:integer => 42}
25
+ end
26
+
27
+ it "should cast arrays" do
28
+ {}.transform({:float => [Float]}).should == {:float => []}
29
+ {:float => '42'}.transform({:float => [Float]}).should == {:float => [42.0]}
30
+ {:float => ['42']}.transform({:float => [Float]}).should == {:float => [42.0]}
31
+ {:float => ['42','13']}.transform({:float => [Float]}).should == {:float => [42.0, 13.0]}
32
+ end
33
+
34
+ it "should cast nested hashes" do
35
+ { :nested => { :hash => '42' } }.transform({ :nested => { :hash => Integer } }).should ==
36
+ { :nested => { :hash => 42 } }
37
+ end
38
+
39
+ it "should cast nested arrays of simple types" do
40
+ { :nested => { :hash => '42' } }.transform({ :nested => { :hash => [Integer] } }).should ==
41
+ { :nested => { :hash => [42] } }
42
+ end
43
+
44
+ it "should cast nested arrays of hashes" do
45
+ { :nested => { :hash => '42' } }.transform({ :nested => [{ :hash => Integer }] }).should ==
46
+ { :nested => [{ :hash => 42 }] }
47
+ end
48
+
49
+ it "should erase keys not present in the schema" do
50
+ {:not => 'present'}.transform({}).should == {}
51
+ end
52
+
53
+ ### misuse
54
+
55
+ it "should not allow non hash transform with hash" do
56
+ lambda { 42.transform({}) }.should raise_error(ArgumentError)
57
+ end
58
+
59
+ it "should not allow an empty array as schema" do
60
+ lambda { 42.transform([]) }.should raise_error(ArgumentError)
61
+ end
62
+
63
+ # it "should not cast arrays to simple types" do
64
+ # lambda { [].transform([]) }.should raise_error(ArgumentError)
65
+ # end
66
+
67
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'schema'
4
+ require 'rspec'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schema
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Daniel Kirsch
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-01 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 2
31
+ version: "2.2"
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: yard
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :development
46
+ version_requirements: *id002
47
+ description: Deep type conversion through schemas for hashes
48
+ email: danishkirel@gmail.com
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files:
54
+ - LICENSE
55
+ - README.md
56
+ files:
57
+ - .document
58
+ - LICENSE
59
+ - README.md
60
+ - Rakefile
61
+ - autotest/discover.rb
62
+ - lib/schema.rb
63
+ - lib/schema/core_ext.rb
64
+ - lib/schema/include.rb
65
+ - lib/schema/schema.rb
66
+ - lib/schema/version.rb
67
+ - spec/schema_spec.rb
68
+ - spec/spec_helper.rb
69
+ has_rdoc: true
70
+ homepage: http://github.com/kirel/schema
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.3.7
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Schemas for hashes
101
+ test_files:
102
+ - spec/schema_spec.rb
103
+ - spec/spec_helper.rb