require 'moosex' require 'moosex/types' class Point include MooseX has x: { is: :rw, # read-write (mandatory) isa: Integer, # should be Integer default: 0, # default value is 0 (constant) } has y: { is: :rw, isa: Integer, default: lambda { 0 }, # you should specify a lambda } has secret: { is: :private, } def clear self.x= 0 # to run with type-check you must self.y= 0 # use the setter instad @x= end def change_secret(new_secret) self.secret= new_secret end def show_secret secret end end describe "Point" do describe "should has an intelligent constructor" do it "without arguments, should initialize with default values" do p = Point.new p.x.should be_zero p.y.should be_zero end it "should initialize only y" do p = Point.new( x: 5 ) p.x.should == 5 p.y.should be_zero end it "should initialize x and y" do p = Point.new( x: 5, y: 4) p.x.should == 5 p.y.should == 4 end end describe "private accessors" do it "should change private by method" do p = Point.new(secret: 1) p.show_secret.should == 1 p.change_secret(2) p.show_secret.should == 2 end it "cant read secret" do p = Point.new expect { p.secret }.to raise_error(NoMethodError) end it "cant write secret" do p = Point.new expect { p.secret = 1 }.to raise_error(NoMethodError) end end describe "should create a getter and a setter" do it "for x" do p = Point.new p.x= 5 p.x.should == 5 end it "for x, with type check" do p = Point.new expect { p.x = "lol" }.to raise_error(MooseX::Types::TypeCheckError, "isa check for x=: Type violation: value 'lol' (String) is not an instance of [Type Integer]") end it "for x, with type check" do expect { Point.new(x: "lol") }.to raise_error(MooseX::Types::TypeCheckError, "isa check for field x: Type violation: value 'lol' (String) is not an instance of [Type Integer]") end it "clear should clean attributes" do p = Point.new( x: 5, y: 4) p.clear p.x.should be_zero p.y.should be_zero end end end class Point3D < Point has x: { is: :rw, # Redefine attribute isa: String, # should be String default: "5", # default value is "5" (constant) override: true, # mandatory, or it will raise exception } has z: { is: :rw, # read-write (mandatory) isa: Integer, # should be Integer default: 0, # default value is 0 (constant) } has color: { is: :rw, # you should specify the reader/writter reader: :what_is_the_color_of_this_point, writter: :set_the_color_of_this_point, default: :red, } def clear self.x= "0" # to run with type-check you must self.y= 0 # use the setter instad @x= self.z= 0 end end describe "Point3D" do describe "should has an intelligent constructor" do it "without arguments, should initialize with default values" do p = Point3D.new p.x.should == "5" p.y.should be_zero p.z.should be_zero p.what_is_the_color_of_this_point.should == :red end it "should initialize only y" do p = Point3D.new( x: "7" ) p.x.should == "7" p.y.should be_zero p.z.should be_zero p.what_is_the_color_of_this_point.should == :red end it "should initialize x and y" do p = Point3D.new( x: "5", y: 4, z: 8, color: :yellow) p.x.should == "5" p.y.should == 4 p.z.should == 8 p.what_is_the_color_of_this_point.should == :yellow end it "for x, with type check" do p = Point3D.new expect { p.x = 666 }.to raise_error(MooseX::Types::TypeCheckError, "isa check for x=: Type violation: value '666' (Fixnum) is not an instance of [Type String]") end end describe "should create a getter and a setter" do it "for z" do p = Point3D.new p.z= 5 p.z.should == 5 end it "for z, with type check" do p = Point3D.new expect { p.z = "lol" }.to raise_error(MooseX::Types::TypeCheckError, "isa check for z=: Type violation: value 'lol' (String) is not an instance of [Type Integer]") end it "for z, with type check" do expect { Point3D.new(z: "lol") }.to raise_error(MooseX::Types::TypeCheckError, "isa check for field z: Type violation: value 'lol' (String) is not an instance of [Type Integer]") end it "clear should clean attributes" do p = Point3D.new( x: "5", y: 4, z: 9) p.clear p.x.should == "0" p.y.should be_zero p.z.should be_zero end end describe "should create the accessors names with custom names" do it "should get/set" do p = Point3D.new p.what_is_the_color_of_this_point.should == :red p.set_the_color_of_this_point(:black) p.what_is_the_color_of_this_point.should == :black end end end