typed 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,12 +6,12 @@ module Typed
6
6
  :schema => true,
7
7
  }
8
8
 
9
- delegate :keys, :to=>"@hash"
9
+ delegate :keys, :size, :to=>"@hash"
10
10
  attr_reader :changes
11
11
  attr_reader :events
12
12
 
13
13
  def initialize(options = {})
14
- @hash = {}
14
+ @hash = ActiveSupport::OrderedHash.new
15
15
  @options = DEFAULT_OPTIONS.merge(options.must(::Hash))
16
16
  @schema = Schema.new
17
17
  @default = Default.new(self)
@@ -102,6 +102,13 @@ module Typed
102
102
  ######################################################################
103
103
  ### Hash compat
104
104
 
105
+ def each_pair(&block)
106
+ keys.each do |key|
107
+ val = self[key]
108
+ block.call(key,val)
109
+ end
110
+ end
111
+
105
112
  def each(&block)
106
113
  keys.each do |key|
107
114
  val = self[key]
@@ -109,6 +116,14 @@ module Typed
109
116
  end
110
117
  end
111
118
 
119
+ def each_key(&block)
120
+ keys.each(&block)
121
+ end
122
+
123
+ def each_value(&block)
124
+ each_pair{|k,v| block.call(v)}
125
+ end
126
+
112
127
  def values
113
128
  keys.map{|key| self[key]}
114
129
  end
@@ -1,114 +1,12 @@
1
1
  module Typed
2
2
  module Scala
3
+ autoload :Accessors, "typed/scala/accessors"
4
+ autoload :Variables, "typed/scala/variables"
5
+ autoload :Parser , "typed/scala/parser"
6
+ autoload :Builder , "typed/scala/builder"
7
+ autoload :Reflect , "typed/scala/reflect"
3
8
 
4
- ######################################################################
5
- ### instance methods
6
-
7
- def attrs
8
- @attrs ||= Typed::Scala::Variables.build_attrs(self.class)
9
- end
10
-
11
- def [](key)
12
- if attrs.schema.exist?(key)
13
- attrs[key.to_s]
14
- else
15
- raise Typed::NotDefined, "#{key} is not a member of #{self.class}"
16
- end
17
- end
18
-
19
- def []=(key, val)
20
- if attrs.schema.exist?(key)
21
- if self.class.vals[key.to_s] and attrs.exist?(key)
22
- raise Typed::FixedValue, "reassignment to #{key}"
23
- end
24
- attrs[key.to_s] = val
25
- else
26
- raise Typed::NotDefined, "#{key} is not a member of #{self.class}"
27
- end
28
- end
29
-
30
- ######################################################################
31
- ### provided api
32
-
33
- module Val
34
- def vals
35
- @typed_scala_vals ||= Typed::Scala::Variables.build_variables(self, :val)
36
- end
37
-
38
- def val(obj)
39
- Typed::Scala::Variables.apply(self, :val, caller[0], obj)
40
- end
41
- end
42
-
43
- module Var
44
- def vars
45
- @typed_scala_vars ||= Typed::Scala::Variables.build_variables(self, :var)
46
- end
47
-
48
- def var(obj)
49
- Typed::Scala::Variables.apply(self, :var, caller[0], obj)
50
- end
51
- end
52
-
53
- ######################################################################
54
- ### class schema
55
-
56
- module Variables
57
- ParseError = Class.new(SyntaxError)
58
-
59
- def self.apply(klass, type, caller, obj)
60
- name = parse(klass, type, caller)
61
- define(klass, type, name, obj)
62
- end
63
-
64
- def self.define(klass, type, name, obj)
65
- vars = klass.__send__("#{type}s")
66
- vars[name] = obj
67
-
68
- klass.class_eval do
69
- define_method(name) { self[name.to_s] }
70
- define_method("#{name}=") {|v| self[name.to_s] = v }
71
- end
72
- end
73
-
74
- def self.parse(klass, type, caller)
75
- # "/tmp/adsvr/dsl.rb:23"
76
- case caller
77
- when %r{^(.*?):(\d+)}o
78
- file = $1
79
- lineno = $2.to_i
80
-
81
- lines = (@lines ||= {})[klass] ||= File.readlines(file)
82
- case lines[lineno-1].to_s
83
- when /^\s*#{type}\s+(\S+)\s+=/
84
- return $1
85
- else
86
- raise ParseError, "#{self} from #{caller}"
87
- end
88
- else
89
- raise ParseError, "#{self} from caller:#{caller}"
90
- end
91
- end
92
-
93
- def self.build_attrs(klass)
94
- attrs = Typed::Hash.new
95
- klass.vals.each_pair{|name, obj| attrs[name] = obj}
96
- klass.vars.each_pair{|name, obj| attrs[name] = obj}
97
- return attrs
98
- end
99
-
100
- def self.build_variables(klass, type)
101
- variables = ActiveSupport::OrderedHash.new
102
-
103
- klass.ancestors[1 .. -1].select{|k| k < Typed::Scala}.reverse.each do |k|
104
- k.instance_eval("[@typed_scala_#{type}s].compact").each do |hash|
105
- variables.merge!(hash)
106
- end
107
- end
108
-
109
- return variables
110
- end
111
- end
9
+ include Accessors
112
10
 
113
11
  ######################################################################
114
12
  ### module
@@ -116,8 +14,9 @@ module Typed
116
14
  def self.included(klass)
117
15
  super
118
16
 
119
- klass.extend Scala::Val
120
- klass.extend Scala::Var
17
+ klass.extend Scala::Reflect
18
+ klass.extend Scala::Parser
19
+ klass.extend Scala::Builder
121
20
  end
122
21
  end
123
22
  end
@@ -0,0 +1,37 @@
1
+ module Typed
2
+ module Scala
3
+ ######################################################################
4
+ ### instance methods
5
+
6
+ module Accessors
7
+ include Enumerable
8
+
9
+ def each(&block)
10
+ __attrs__.each_pair(&block)
11
+ end
12
+
13
+ def __attrs__
14
+ @__attrs__ ||= Typed::Scala::Variables.build_attrs(self.class)
15
+ end
16
+
17
+ def [](key)
18
+ if __attrs__.schema.exist?(key)
19
+ __attrs__[key.to_s]
20
+ else
21
+ raise Typed::NotDefined, "#{key} is not a member of #{self.class}"
22
+ end
23
+ end
24
+
25
+ def []=(key, val)
26
+ if __attrs__.schema.exist?(key)
27
+ if self.class.vals[key.to_s] and __attrs__.exist?(key)
28
+ raise Typed::FixedValue, "reassignment to #{key}"
29
+ end
30
+ __attrs__[key.to_s] = val
31
+ else
32
+ raise Typed::NotDefined, "#{key} is not a member of #{self.class}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ module Typed
2
+ module Scala
3
+
4
+ ######################################################################
5
+ ### Builder
6
+ module Builder
7
+ # Build instance from hash
8
+ def build(hash = {})
9
+ obj = new
10
+ hash.each_pair do |k,v|
11
+ obj[k] = v
12
+ end
13
+ return obj
14
+ end
15
+
16
+ # Build instance from array
17
+ def apply(*args)
18
+ if args.size > variables.size
19
+ raise "#{self}.apply expect #{variables.size} args, but got #{args.size}"
20
+ end
21
+
22
+ obj = new
23
+ variables.each_key do |name|
24
+ val = args.shift or next
25
+ obj[name] = val
26
+ end
27
+ return obj
28
+ end
29
+
30
+ # Build instance from array strictly. Raised when args size is differ.
31
+ def apply!(*args)
32
+ if args.size != variables.size
33
+ raise "#{self}.apply expect #{variables.size} args, but got #{args.size}"
34
+ end
35
+
36
+ obj = new
37
+ variables.each_key do |name|
38
+ obj[name] = args.shift
39
+ end
40
+ return obj
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ module Typed
2
+ module Scala
3
+
4
+ ######################################################################
5
+ ### Parser
6
+ module Parser
7
+ # Modifiers
8
+ def override(*args)
9
+ end
10
+
11
+ def lazy(*args)
12
+ end
13
+
14
+ # Declarations
15
+ def val(obj)
16
+ Typed::Scala::Variables.apply(self, :val, caller[0], obj)
17
+ end
18
+
19
+ def var(obj)
20
+ Typed::Scala::Variables.apply(self, :var, caller[0], obj)
21
+ return :var
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Typed
2
+ module Scala
3
+
4
+ ######################################################################
5
+ ### Reflect
6
+
7
+ module Reflect
8
+ # variable synthesis
9
+ def variables
10
+ @variables ||= Typed::Scala::Variables.build(self)
11
+ end
12
+
13
+ def vals
14
+ @typed_scala_vals ||= Typed::Scala::Variables.build_variables(self, :val)
15
+ end
16
+
17
+ def vars
18
+ @typed_scala_vars ||= Typed::Scala::Variables.build_variables(self, :var)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,98 @@
1
+ module Typed
2
+ module Scala
3
+ ######################################################################
4
+ ### class schema
5
+
6
+ module Variables
7
+ ParseError = Class.new(SyntaxError)
8
+
9
+ Declaration = Struct.new(:klass, :name, :type, :mods, :value)
10
+
11
+ def apply(klass, type, caller, obj)
12
+ dcl = parse(klass, type, caller)
13
+ dcl.value = obj
14
+
15
+ define_schema(dcl)
16
+ define_method(dcl)
17
+ end
18
+
19
+ def define_schema(dcl)
20
+ vars = dcl.klass.__send__("#{dcl.type}s")
21
+ vars[dcl.name] = dcl.value
22
+
23
+ # new feature
24
+ dcl.klass.variables[dcl.name] = dcl.value
25
+ end
26
+
27
+ def define_method(dcl)
28
+ name = dcl.name
29
+ dcl.klass.class_eval <<-STR, __FILE__, __LINE__ + 1
30
+ def #{name}
31
+ self['#{name}']
32
+ end
33
+
34
+ def #{name}=(v)
35
+ self['#{name}'] = v
36
+ end
37
+ STR
38
+ end
39
+
40
+ def parse(klass, type, caller)
41
+ # "/tmp/adsvr/dsl.rb:23"
42
+ case caller
43
+ when %r{^(.*?):(\d+)}o
44
+ file = $1
45
+ lineno = $2.to_i
46
+
47
+ lines = (@lines ||= {})[klass] ||= File.readlines(file)
48
+ case lines[lineno-1].to_s
49
+ when /^\s*(override\s+)?(lazy\s+)?(val|var)\s+(\S+)\s+=/
50
+ mods = [$1, $2].compact.map(&:strip)
51
+ type = $3
52
+ name = $4
53
+ return Declaration.new(klass, name, type, mods)
54
+ else
55
+ raise ParseError, "#{self} from #{caller}"
56
+ end
57
+ else
58
+ raise ParseError, "#{self} from caller:#{caller}"
59
+ end
60
+ end
61
+
62
+ def build_attrs(klass)
63
+ attrs = Typed::Hash.new
64
+ klass.vals.each_pair{|name, obj| attrs[name] = obj}
65
+ klass.vars.each_pair{|name, obj| attrs[name] = obj}
66
+ return attrs
67
+ end
68
+
69
+ def build(klass)
70
+ variables = ActiveSupport::OrderedHash.new
71
+
72
+ klass.ancestors[1 .. -1].select{|k| k < Typed::Scala}.reverse.each do |k|
73
+ k.instance_eval("[@variables].compact").each do |hash|
74
+ variables.merge!(hash)
75
+ end
76
+ end
77
+
78
+ return variables
79
+ end
80
+
81
+ def build_variables(klass, type)
82
+ # variables = Typed::Hash.new
83
+ variables = ActiveSupport::OrderedHash.new
84
+
85
+ klass.ancestors[1 .. -1].select{|k| k < Typed::Scala}.reverse.each do |k|
86
+ k.instance_eval("[@typed_scala_#{type}s].compact").each do |hash|
87
+ variables.merge!(hash)
88
+ end
89
+ end
90
+
91
+ return variables
92
+ end
93
+
94
+ extend self
95
+ end
96
+
97
+ end
98
+ end
@@ -1,3 +1,3 @@
1
1
  module Typed
2
- VERSION = "0.2.7"
2
+ VERSION = "0.2.8"
3
3
  end
@@ -29,6 +29,13 @@ describe Typed::Hash do
29
29
  data["a"].should == 2
30
30
  end
31
31
 
32
+ describe "enumerable" do
33
+ it { should respond_to(:each) }
34
+ it { should respond_to(:each_pair) }
35
+ it { should respond_to(:each_key) }
36
+ it { should respond_to(:each_value) }
37
+ end
38
+
32
39
  describe "#[]" do
33
40
  it "should raise NotDefined if value not exists" do
34
41
  lambda {
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Column names
8
+
9
+ context "(attrs)" do
10
+ before { scala_source("A", <<-EOF)
11
+ class A
12
+ include Typed::Scala
13
+ val key = String
14
+ var attrs = Hash
15
+ end
16
+ EOF
17
+ }
18
+
19
+ describe "#attrs, #attrs=" do
20
+ subject { A.new }
21
+
22
+ specify do
23
+ a = A.new
24
+ a.attrs = {:x=>1}
25
+ a.attrs.should == {:x=>1}
26
+ end
27
+ end
28
+
29
+ describe ".build" do
30
+ context "()" do
31
+ subject { A.build }
32
+ specify { lambda { subject.key }.should raise_error(Typed::NotDefined) }
33
+ specify { lambda { subject.attrs }.should raise_error(Typed::NotDefined) }
34
+ end
35
+
36
+ context '(:key=>"x", :attrs=>{:a=>1})' do
37
+ subject { A.build(:key=>"x", :attrs=>{:a=>1}) }
38
+ its(:key) { should == "x" }
39
+ its(:attrs) { should == {:a=>1} }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Basic usage
8
+
9
+ describe "User" do
10
+ before { scala_source("User", <<-EOF)
11
+ class User
12
+ include Typed::Scala
13
+
14
+ val key = String
15
+ var name = String
16
+ var age = Fixnum
17
+ end
18
+ EOF
19
+ }
20
+
21
+ subject { User }
22
+
23
+ its(:vals) { should be_kind_of ActiveSupport::OrderedHash }
24
+ its(:vals) { should == { "key" => String } }
25
+ its(:vars) { should be_kind_of ActiveSupport::OrderedHash }
26
+ its(:vars) { should == { "name" => String, "age" => Fixnum } }
27
+
28
+ describe ".apply" do
29
+ specify "less args" do
30
+ user = User.apply("001", "aya")
31
+ user.key .should == "001"
32
+ user.name.should == "aya"
33
+ lambda { user.age}.should raise_error(Typed::NotDefined)
34
+ end
35
+
36
+ specify "exact args" do
37
+ user = User.apply("001", "aya", 12)
38
+ user.key .should == "001"
39
+ user.name.should == "aya"
40
+ user.age .should == 12
41
+ end
42
+
43
+ specify "more args" do
44
+ lambda { User.apply("001", "aya", 12, "!") }.should raise_error(/expect 3 args/)
45
+ end
46
+ end
47
+
48
+ describe ".apply!" do
49
+ specify "less args" do
50
+ lambda { User.apply!("001", "aya") }.should raise_error(/expect 3 args/)
51
+ end
52
+
53
+ specify "exact args" do
54
+ user = User.apply!("001", "aya", 12)
55
+ user.key .should == "001"
56
+ user.name.should == "aya"
57
+ user.age .should == 12
58
+ end
59
+
60
+ specify "more args" do
61
+ lambda { User.apply!("001", "aya", 12, "!") }.should raise_error(/expect 3 args/)
62
+ end
63
+ end
64
+
65
+ describe ".build" do
66
+ # "creates a new instance"
67
+ its(:build) { should be_kind_of User }
68
+
69
+ specify "ok" do
70
+ User.build.should be_kind_of(User)
71
+ User.build(:name=>"foo").name.should == "foo"
72
+
73
+ user = User.build(:key=>"x", :age=>12)
74
+ user.key.should == "x"
75
+ user.age.should == 12
76
+ end
77
+
78
+ specify "not member" do
79
+ lambda { User.build(:foo => "!") }.should raise_error(Typed::NotDefined)
80
+ end
81
+
82
+ specify "type error" do
83
+ lambda { User.build(:age => "!") }.should raise_error(TypeError)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Basic usage
8
+
9
+ describe "User" do
10
+ before { scala_source("User", <<-EOF)
11
+ class User
12
+ include Typed::Scala
13
+
14
+ val key = String
15
+ var name = String
16
+ var age = Fixnum
17
+ end
18
+ EOF
19
+ }
20
+
21
+ let(:user) { User.new }
22
+ subject { user}
23
+
24
+ describe ".variables" do
25
+ subject { User.variables }
26
+ its(:keys) { should == %w( key name age ) }
27
+ its(["key" ]) { should == String }
28
+ its(["name"]) { should == String }
29
+ its(["age" ]) { should == Fixnum }
30
+
31
+ specify "#each_pair" do
32
+ hash = {}
33
+ subject.each_pair do |name, type|
34
+ hash[name] = type
35
+ end
36
+ hash.should == {
37
+ "key" => String,
38
+ "name" => String,
39
+ "age" => Fixnum,
40
+ }
41
+ end
42
+ end
43
+
44
+ describe "attributes" do
45
+ it { should respond_to(:key) }
46
+ it { should respond_to(:name) }
47
+ it { should respond_to(:age) }
48
+ it { should respond_to(:[]) }
49
+ it { should respond_to(:[]=) }
50
+ it { should_not respond_to(:xxx) }
51
+ end
52
+
53
+ describe "#name=" do
54
+ specify "accept 'maiha'" do
55
+ (user.name = 'maiha').should == 'maiha'
56
+ end
57
+
58
+ specify "reject 100" do
59
+ lambda { user.name = 100 }.should raise_error(TypeError)
60
+ end
61
+ end
62
+
63
+ describe "enumerable" do
64
+ it { should respond_to(:each) }
65
+ it { should respond_to(:map) }
66
+ end
67
+
68
+ describe "#__attrs__" do
69
+ subject { User.apply!("001", "aya", 12).__attrs__ }
70
+
71
+ its(:size ) { should == 3 }
72
+ its(:keys ) { should == %w( key name age ) }
73
+ its(:values) { should == ["001", "aya", 12] }
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,77 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Inheritance
8
+
9
+ context "(Point3D < Point2D)" do
10
+ before { scala_source("Point2D", <<-EOF)
11
+ class Point2D
12
+ include Typed::Scala
13
+ val x = Fixnum
14
+ val y = Fixnum
15
+ end
16
+ EOF
17
+ }
18
+
19
+ before { scala_source("Point3D", <<-EOF)
20
+ class Point3D < Point2D
21
+ val z = Fixnum
22
+ end
23
+ EOF
24
+ }
25
+
26
+ context "Point2D" do
27
+ specify "contains x,y" do
28
+ Point2D.vals.keys.should == %w( x y )
29
+ end
30
+
31
+ describe "#x, #x=" do
32
+ specify "exist" do
33
+ p = Point2D.new
34
+ p.x = 1
35
+ p.x.should == 1
36
+ lambda { p.x = 2 }.should raise_error(Typed::FixedValue)
37
+ end
38
+ end
39
+
40
+ describe "#z" do
41
+ specify "not exist" do
42
+ p = Point2D.new
43
+ lambda { p["z"] = 3 }.should raise_error(Typed::NotDefined)
44
+ lambda { p.z = 3 }.should raise_error(NoMethodError)
45
+ end
46
+ end
47
+ end
48
+
49
+ context "Point3D" do
50
+ specify "contains x,y,z" do
51
+ Point3D.vals.keys.should == %w( x y z )
52
+ end
53
+
54
+ describe "#x, #x=, [x], [x]=" do
55
+ specify "exist" do
56
+ p = Point3D.new
57
+ p.x = 1
58
+ p.x.should == 1
59
+ p["x"].should == 1
60
+ lambda { p.x = 2 }.should raise_error(Typed::FixedValue)
61
+ lambda { p["x"] = 2 }.should raise_error(Typed::FixedValue)
62
+ end
63
+ end
64
+
65
+ describe "#z, #z=, [z], [z]=" do
66
+ specify "exist" do
67
+ p = Point3D.new
68
+ p.z = 1
69
+ p.z.should == 1
70
+ p["z"].should == 1
71
+ lambda { p.z = 2 }.should raise_error(Typed::FixedValue)
72
+ lambda { p["z"] = 2 }.should raise_error(Typed::FixedValue)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Modifiers: OVERRIDE | LAZY
8
+
9
+ # def isModifier: Boolean = in.token match {
10
+ # case ABSTRACT | FINAL | SEALED | PRIVATE |
11
+ # PROTECTED | OVERRIDE | IMPLICIT | LAZY => true
12
+
13
+ # modifiers : def isLocalModifier: Boolean = in.token match {
14
+ # case ABSTRACT | FINAL | SEALED | IMPLICIT | LAZY => true
15
+
16
+ # def isDclIntro: Boolean = in.token match {
17
+ # case VAL | VAR | DEF | TYPE => true
18
+
19
+ # describe "conflicted variable names" do
20
+ pending "conflicted variable names" do
21
+ context "(without override modifier)"
22
+
23
+ let(:source) { <<-EOF
24
+ class T
25
+ include Typed::Scala
26
+
27
+ val t = String
28
+ end
29
+
30
+ class U < T
31
+ val t = Fixnum
32
+ end
33
+ EOF
34
+ }
35
+
36
+ specify do
37
+ lambda { scala_source("User", source) }.should raise_error(TypeError)
38
+ end
39
+
40
+ specify do
41
+ scala_source("User", source)
42
+ T.vals.should == {}
43
+ end
44
+
45
+ context "(with override modifier)" do
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ ######################################################################
5
+ ### TODO
6
+
7
+ describe "check method conflictions like [], []=" do
8
+ specify do
9
+ pending "will be implemented in version 0.3.0"
10
+ end
11
+ end
12
+
13
+ context "when val or var are overridden in same context" do
14
+ specify do
15
+ pending "will be implemented in version 0.3.0"
16
+ end
17
+ end
18
+
19
+ context "when val or var are overridden in subclass" do
20
+ specify do
21
+ pending "will be implemented in version 0.3.0"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,94 @@
1
+ require "spec_helper"
2
+
3
+ describe Typed::Scala do
4
+ include_context "scala_source"
5
+
6
+ ######################################################################
7
+ ### Two files at same time
8
+
9
+ context "(two files)" do
10
+ before { scala_source("A", <<-EOF)
11
+ class A
12
+ include Typed::Scala
13
+ val key = String
14
+ var val = String
15
+ end
16
+ EOF
17
+ }
18
+
19
+ before { scala_source("B", <<-EOF)
20
+ class B
21
+ include Typed::Scala
22
+ val key = Fixnum
23
+ var url = String
24
+ end
25
+ EOF
26
+ }
27
+
28
+ specify "should be independent" do
29
+ A.vals.should == { "key" => String }
30
+ A.vars.should == { "val" => String }
31
+ B.vals.should == { "key" => Fixnum }
32
+ B.vars.should == { "url" => String }
33
+ end
34
+
35
+ specify "accessors" do
36
+ a = A.new
37
+ b = B.new
38
+
39
+ a.key = "foo"
40
+ a.val = "xyz"
41
+ b.key = 10000
42
+ b.url = "http"
43
+
44
+ a.key.should == "foo"
45
+ a.val.should == "xyz"
46
+ a["key"].should == "foo"
47
+ a["val"].should == "xyz"
48
+
49
+ b.key.should == 10000
50
+ b.url.should == "http"
51
+ b["key"].should == 10000
52
+ b["url"].should == "http"
53
+ end
54
+
55
+ context "read non defined field" do
56
+ subject { lambda { A.new["xxx"] } }
57
+ it { should raise_error(Typed::NotDefined) }
58
+ it { should raise_error(/xxx is not a member of A/) }
59
+ end
60
+
61
+ context "read defined but not initiaized field" do
62
+ context "[key]" do
63
+ subject { lambda { A.new["key"] } }
64
+ it { should raise_error(Typed::NotDefined) }
65
+ it { should raise_error(/'key' is not initialized/) }
66
+ end
67
+
68
+ context "#key" do
69
+ subject { lambda { A.new.key } }
70
+ it { should raise_error(Typed::NotDefined) }
71
+ it { should raise_error(/'key' is not initialized/) }
72
+ end
73
+ end
74
+
75
+ context "write non defined field" do
76
+ subject { lambda { A.new["xxx"] = 1 } }
77
+ it { should raise_error(Typed::NotDefined) }
78
+ it { should raise_error(/xxx is not a member of A/) }
79
+ end
80
+
81
+ describe "write twice" do
82
+ context "val" do
83
+ subject { lambda { b = B.new; b.key = 0; b.key = 1 } }
84
+ it { should raise_error(Typed::FixedValue) }
85
+ it { should raise_error(/reassignment to key/) }
86
+ end
87
+
88
+ context "var" do
89
+ subject { lambda { b = B.new; b.url = "x"; b.url = "y" } }
90
+ it { should_not raise_error }
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,8 +1,11 @@
1
1
  $:.unshift File.expand_path('../../lib', __FILE__)
2
2
 
3
+ require 'rubygems'
3
4
  require 'rspec'
4
5
  require 'typed'
5
6
 
7
+ root = Pathname(File.dirname(__FILE__)) + ".."
8
+ Dir[root + "spec/support/**/*.rb"].each {|f| require f}
6
9
 
7
10
  RSpec.configure do |config|
8
11
  # == Mock Framework
@@ -18,7 +21,6 @@ RSpec.configure do |config|
18
21
  config.run_all_when_everything_filtered = true
19
22
  end
20
23
 
21
-
22
24
  def tmp_path(file)
23
25
  Pathname(File.dirname(__FILE__)) + "../tmp" + file
24
26
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ shared_context "scala_source" do
4
+ before { @loaded = [] }
5
+ after { @loaded.each{|klass| Object.__send__(:remove_const, klass) if Object.const_defined?(klass) } }
6
+
7
+ def scala_source(klass, code)
8
+ path = tmp_path("scala/source.rb")
9
+ path.parent.mkpath
10
+ path.open("w+"){|f| f.puts(code) }
11
+ load(path.to_s)
12
+ @loaded << klass
13
+ end
14
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typed
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 7
10
- version: 0.2.7
9
+ - 8
10
+ version: 0.2.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - maiha
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-08-28 00:00:00 Z
18
+ date: 2013-09-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport
@@ -81,6 +81,11 @@ files:
81
81
  - lib/typed/events.rb
82
82
  - lib/typed/hash.rb
83
83
  - lib/typed/scala.rb
84
+ - lib/typed/scala/accessors.rb
85
+ - lib/typed/scala/builder.rb
86
+ - lib/typed/scala/parser.rb
87
+ - lib/typed/scala/reflect.rb
88
+ - lib/typed/scala/variables.rb
84
89
  - lib/typed/schema.rb
85
90
  - lib/typed/version.rb
86
91
  - spec/changes_spec.rb
@@ -90,9 +95,16 @@ files:
90
95
  - spec/hash_spec.rb
91
96
  - spec/merge_spec.rb
92
97
  - spec/path_spec.rb
93
- - spec/scala_spec.rb
98
+ - spec/scala/attrs_spec.rb
99
+ - spec/scala/build_spec.rb
100
+ - spec/scala/core_spec.rb
101
+ - spec/scala/inherit_spec.rb
102
+ - spec/scala/modifier_spec.rb
103
+ - spec/scala/todo_spec.rb
104
+ - spec/scala/two_files_spec.rb
94
105
  - spec/schema_spec.rb
95
106
  - spec/spec_helper.rb
107
+ - spec/support/scala.rb
96
108
  - spec/time_spec.rb
97
109
  - typed.gemspec
98
110
  homepage: https://github.com/maiha/typed
@@ -1,243 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Typed::Scala do
4
- before { @loaded = [] }
5
- after { @loaded.each{|klass| Object.__send__(:remove_const, klass) if Object.const_defined?(klass) } }
6
-
7
- def source(klass, code)
8
- path = tmp_path("scala/inline.rb")
9
- path.parent.mkpath
10
- path.open("w+"){|f| f.puts(code) }
11
- load(path.to_s)
12
- @loaded << klass
13
- end
14
-
15
- ######################################################################
16
- ### Basic usage
17
-
18
- describe "User" do
19
- before { source("User", <<-EOF)
20
- class User
21
- include Typed::Scala
22
-
23
- val key = String
24
- var name = String
25
- var age = Fixnum
26
- end
27
- EOF
28
- }
29
-
30
- context "(class)" do
31
- subject { User }
32
- its(:vals) { should be_kind_of ActiveSupport::OrderedHash }
33
- its(:vals) { should == { "key" => String } }
34
- its(:vars) { should be_kind_of ActiveSupport::OrderedHash }
35
- its(:vars) { should == { "name" => String, "age" => Fixnum } }
36
- end
37
-
38
- context "(instance)" do
39
- let(:user) { User.new }
40
- subject { user}
41
-
42
- it { should respond_to(:key) }
43
- it { should respond_to(:name) }
44
- it { should respond_to(:age) }
45
- it { should_not respond_to(:xxx) }
46
- it { should respond_to(:attrs) }
47
- it { should respond_to(:[]) }
48
- it { should respond_to(:[]=) }
49
-
50
- describe "#name=" do
51
- specify "accept 'maiha'" do
52
- (user.name = 'maiha').should == 'maiha'
53
- end
54
-
55
- specify "reject 100" do
56
- lambda { user.name = 100 }.should raise_error(TypeError)
57
- end
58
- end
59
- end
60
- end
61
-
62
- ######################################################################
63
- ### Two files at same time
64
-
65
- context "(two files)" do
66
- before { source("A", <<-EOF)
67
- class A
68
- include Typed::Scala
69
- val key = String
70
- var val = String
71
- end
72
- EOF
73
- }
74
-
75
- before { source("B", <<-EOF)
76
- class B
77
- include Typed::Scala
78
- val key = Fixnum
79
- var url = String
80
- end
81
- EOF
82
- }
83
-
84
- specify "should be independent" do
85
- A.vals.should == { "key" => String }
86
- A.vars.should == { "val" => String }
87
- B.vals.should == { "key" => Fixnum }
88
- B.vars.should == { "url" => String }
89
- end
90
-
91
- specify "accessors" do
92
- a = A.new
93
- b = B.new
94
-
95
- a.key = "foo"
96
- a.val = "xyz"
97
- b.key = 10000
98
- b.url = "http"
99
-
100
- a.key.should == "foo"
101
- a.val.should == "xyz"
102
- a["key"].should == "foo"
103
- a["val"].should == "xyz"
104
-
105
- b.key.should == 10000
106
- b.url.should == "http"
107
- b["key"].should == 10000
108
- b["url"].should == "http"
109
- end
110
-
111
- context "read non defined field" do
112
- subject { lambda { A.new["xxx"] } }
113
- it { should raise_error(Typed::NotDefined) }
114
- it { should raise_error(/xxx is not a member of A/) }
115
- end
116
-
117
- context "read defined but not initiaized field" do
118
- context "[key]" do
119
- subject { lambda { A.new["key"] } }
120
- it { should raise_error(Typed::NotDefined) }
121
- it { should raise_error(/'key' is not initialized/) }
122
- end
123
-
124
- context "#key" do
125
- subject { lambda { A.new.key } }
126
- it { should raise_error(Typed::NotDefined) }
127
- it { should raise_error(/'key' is not initialized/) }
128
- end
129
- end
130
-
131
- context "write non defined field" do
132
- subject { lambda { A.new["xxx"] = 1 } }
133
- it { should raise_error(Typed::NotDefined) }
134
- it { should raise_error(/xxx is not a member of A/) }
135
- end
136
-
137
- describe "write twice" do
138
- context "val" do
139
- subject { lambda { b = B.new; b.key = 0; b.key = 1 } }
140
- it { should raise_error(Typed::FixedValue) }
141
- it { should raise_error(/reassignment to key/) }
142
- end
143
-
144
- context "var" do
145
- subject { lambda { b = B.new; b.url = "x"; b.url = "y" } }
146
- it { should_not raise_error }
147
- end
148
- end
149
- end
150
-
151
- ######################################################################
152
- ### Inheritance
153
-
154
- context "(Point3D < Point2D)" do
155
- before { source("Point2D", <<-EOF)
156
- class Point2D
157
- include Typed::Scala
158
- val x = Fixnum
159
- val y = Fixnum
160
- end
161
- EOF
162
- }
163
-
164
- before { source("Point3D", <<-EOF)
165
- class Point3D < Point2D
166
- val z = Fixnum
167
- end
168
- EOF
169
- }
170
-
171
- context "Point2D" do
172
- specify "contains x,y" do
173
- Point2D.vals.keys.should == %w( x y )
174
- end
175
-
176
- describe "#x, #x=" do
177
- specify "exist" do
178
- p = Point2D.new
179
- p.x = 1
180
- p.x.should == 1
181
- lambda { p.x = 2 }.should raise_error(Typed::FixedValue)
182
- end
183
- end
184
-
185
- describe "#z" do
186
- specify "not exist" do
187
- p = Point2D.new
188
- lambda { p["z"] = 3 }.should raise_error(Typed::NotDefined)
189
- lambda { p.z = 3 }.should raise_error(NoMethodError)
190
- end
191
- end
192
- end
193
-
194
- context "Point3D" do
195
- specify "contains x,y,z" do
196
- Point3D.vals.keys.should == %w( x y z )
197
- end
198
-
199
- describe "#x, #x=, [x], [x]=" do
200
- specify "exist" do
201
- p = Point3D.new
202
- p.x = 1
203
- p.x.should == 1
204
- p["x"].should == 1
205
- lambda { p.x = 2 }.should raise_error(Typed::FixedValue)
206
- lambda { p["x"] = 2 }.should raise_error(Typed::FixedValue)
207
- end
208
- end
209
-
210
- describe "#z, #z=, [z], [z]=" do
211
- specify "exist" do
212
- p = Point3D.new
213
- p.z = 1
214
- p.z.should == 1
215
- p["z"].should == 1
216
- lambda { p.z = 2 }.should raise_error(Typed::FixedValue)
217
- lambda { p["z"] = 2 }.should raise_error(Typed::FixedValue)
218
- end
219
- end
220
- end
221
- end
222
-
223
- ######################################################################
224
- ### TODO
225
-
226
- describe "check method conflictions like [], []=" do
227
- specify do
228
- pending "will be implemented in version 0.3.0"
229
- end
230
- end
231
-
232
- context "when val or var are overridden in same context" do
233
- specify do
234
- pending "will be implemented in version 0.3.0"
235
- end
236
- end
237
-
238
- context "when val or var are overridden in subclass" do
239
- specify do
240
- pending "will be implemented in version 0.3.0"
241
- end
242
- end
243
- end