typed 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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