spec/moosex_spec.rb in moosex-0.0.9 vs spec/moosex_spec.rb in moosex-0.0.10
- old
+ new
@@ -1,755 +1,16 @@
require 'moosex'
-class Point
+class A
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
- }
-
- def clear
- self.x= 0 # to run with type-check you must
- self.y= 0 # use the setter instad @x=
- 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 "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('isa check for "x" failed: is not instance of Integer!')
- end
-
- it "for x, with type check" do
- expect {
- Point.new(x: "lol")
- }.to raise_error('isa check for "x" failed: is not instance of 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 Foo
- include MooseX
-
- has bar: {
- is: :rwp, # read-write-private (private setter)
- required: true, # you should require in the constructor
- }
-
- has my_other_bar: {
- is: :rw,
- init_arg: :bar2
- }
-end
-
-describe "Foo" do
- it "should require bar if necessary" do
- expect {
- Foo.new
- }.to raise_error("attr \"bar\" is required")
+describe "MooseX" do
+ it "should contains has method" do
+ A.methods.include?(:has).should be_true
end
- it "should require bar if necessary" do
- foo = Foo.new( bar: 123 )
- foo.bar.should == 123
- end
-
- it "should not be possible update bar (setter private)" do
- foo = Foo.new( bar: 123 )
- expect {
- foo.bar = 1024
- }.to raise_error(NoMethodError)
- end
-
- it "should be possible initialize my_other_bar by bar2" do
- foo = Foo.new( bar: 1, bar2: 555)
- foo.my_other_bar.should == 555
- end
-end
-
-class Baz
- include MooseX
-
- has bam: {
- is: :ro, # read-only, you should specify in new only
- isa: lambda do |bam| # you should add your own validator
- raise 'bam should be less than 100' if bam > 100
- end,
- required: true,
- }
-
- has boom: {
- is: :rw,
- predicate: true, # add has_boom? method, ask if the attribute is unset
- clearer: true, # add reset_boom! method, unset the attribute
- }
-end
-
-describe "Baz" do
- it "should require bam if necessary" do
- baz = Baz.new( bam: 99 )
- baz.bam.should == 99
- end
-
- it "should not be possible update baz (read only)" do
- baz = Baz.new( bam: 99 )
- expect {
- baz.bam = 1024
- }.to raise_error(NoMethodError)
- end
-
- it "should run the lambda isa" do
- expect {
- Baz.new( bam: 199 )
- }.to raise_error(/bam should be less than 100/)
- end
-
- it "rw acessor should has nil value, supports predicate" do
- baz = Baz.new( bam: 99 )
-
- baz.has_boom?.should be_false
- baz.boom.should be_nil
- baz.boom= 0
- baz.has_boom?.should be_true
- baz.boom.should be_zero
- end
-
- it "rw acessor should has nil value, supports clearer" do
- baz = Baz.new( bam: 99, boom: 0 )
-
- baz.has_boom?.should be_true
- baz.boom.should be_zero
-
- baz.reset_boom!
-
- baz.has_boom?.should be_false
- baz.boom.should be_nil
- end
-
- it "should be possible call the clearer twice" do
- baz = Baz.new( bam: 99, boom: 0 )
-
- baz.reset_boom!
- baz.reset_boom!
-
- baz.has_boom?.should be_false
- baz.boom.should be_nil
- end
-end
-
-class Lol
- include MooseX
-
- has [:a, :b], { # define attributes a and b
- is: :ro, # with same set of properties
- default: 0,
- }
-
- has c: { # alternative syntax to be
- is: :ro, # more similar to Moo/Moose
- default: 1,
- predicate: :can_haz_c?, # custom predicate
- clearer: "desintegrate_c", # force coerce to symbol
- }
-
- has [:d, :e] => {
- is: "ro", # can coerce from strings
- default: 2,
- required: true,
- }
-end
-
-describe "Lol" do
- it "Lol should has five arguments" do
- lol = Lol.new(a: 5, d: -1)
- lol.a.should == 5
- lol.b.should be_zero
- lol.c.should == 1
- lol.d.should == -1
- lol.e.should == 2
- end
-
- it "Lol should support custom predicate and clearer" do
- lol = Lol.new(a: 5, d: -1)
-
- lol.can_haz_c?.should be_true
- lol.desintegrate_c
- lol.can_haz_c?.should be_false
- end
-end
-
-class ProxyToTarget
- include MooseX
-
- has target: {
- is: :ro,
- default: lambda { Target.new }, # default, new instace of Target
- handles: { # handles is for delegation,
- my_method_x: :method_x, # inject methods with new names
- my_method_y: :method_y, # old => obj.target.method_x
- }, # now => obj.my_method_x
- }
-end
-
-module TargetModule
- def method_x; 1024; end # works with simple methods
- def method_y(a,b,c); a + b + c; end # or methods with arguments
-end
-
-class Target
- include TargetModule
-end
-
-describe "ProxyToTarget" do
- it "should delegate method_x to the target" do
- p = ProxyToTarget.new
-
- p.target.method_x.should == 1024
- p.my_method_x.should == 1024
- end
-
- it "should delegate method_y to the target" do
- p = ProxyToTarget.new
-
- p.target.method_y(1,2,3).should == 6
- p.my_method_y(1,2,3).should == 6
- end
-end
-
-class ProxyToTargetUsingArrayOfMethods
- include MooseX
-
- has targetz: {
- is: :ro,
- default: lambda { Target.new },
- handles: [
- :method_x, :method_y # will inject all methods with same name
- ]
- }
-end
-
-describe "ProxyToTargetUsingArrayOfMethods" do
- it "should delegate method_x to the target" do
- p = ProxyToTargetUsingArrayOfMethods.new
-
- p.targetz.method_x.should == 1024
- p.method_x.should == 1024
- end
-
- it "should delegate method_y to the target" do
- p = ProxyToTargetUsingArrayOfMethods.new
-
- p.targetz.method_y(1,2,3).should == 6
- p.method_y(1,2,3).should == 6
- end
-end
-
-class ProxyToTargetUsingSingleMethod
- include MooseX
-
- has target: {
- is: :ro,
- default: lambda { Target.new },
- handles: "method_x" # coerce to an array of symbols
- }
-end
-
-describe "ProxyToTargetUsingSingleMethod" do
- it "should delegate method_x to the target" do
- p = ProxyToTargetUsingSingleMethod.new
-
- p.target.method_x.should == 1024
- p.method_x.should == 1024
- end
-end
-
-class ProxyToTargetUsingModule
- include MooseX
-
- has target: {
- is: :ro,
- default: lambda { Target.new },
- handles: TargetModule # will import all methods from module
- }
-end
-
-describe "ProxyToTargetUsingModule" do
- it "should delegate method_x to the target" do
- p = ProxyToTargetUsingModule.new
-
- p.target.method_x.should == 1024
- p.method_x.should == 1024
- end
-
- it "should delegate method_y to the target" do
- p = ProxyToTargetUsingModule.new
-
- p.target.method_y(1,2,3).should == 6
- p.method_y(1,2,3).should == 6
- end
-end
-
-class ProxyToTargetUsingClass
- include MooseX
-
- has target: {
- is: :ro,
- default: lambda { Target.new },
- handles: Target # will use only public methods on Target class
- } # exclude methods from superclass
-end
-
-describe "ProxyToTargetUsingClass" do
- it "should delegate method_x to the target" do
- p = ProxyToTargetUsingClass.new
-
- p.target.method_x.should == 1024
- p.method_x.should == 1024
- end
-
- it "should delegate method_y to the target" do
- p = ProxyToTargetUsingClass.new
-
- p.target.method_y(1,2,3).should == 6
- p.method_y(1,2,3).should == 6
- end
-end
-
-class Point3D < Point
-
- has x: { # override original attr!
- is: :rw,
- isa: Integer,
- default: 1,
- }
-
- 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 == 1
- 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: 5 )
- 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 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
- 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('isa check for "z" failed: is not instance of Integer!')
- end
-
- it "for z, with type check" do
- expect {
- Point3D.new(z: "lol")
- }.to raise_error('isa check for "z" failed: is not instance of Integer!')
- end
-
- it "clear should clean attributes" do
- p = Point3D.new( x: 5, y: 4, z: 9)
- p.clear
- p.x.should be_zero
- 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
-
-class LazyFox
- include MooseX
-
- has something: {
- is: :lazy
- }
-
- has other_thing: {
- is: :rw,
- lazy: true,
- predicate: true,
- clearer: true,
- builder: :my_build_other_thing,
- }
-
- has lazy_attr_who_accepts_lambda: {
- is: :lazy,
- builder: lambda{ |object| object.something }
- }
-
- has lazy_with_default: {
- is: :lazy,
- default: 10,
- clearer: true,
- builder: lambda {|o| 1 },
- }
-
- has last_lazy_attr: {
- is: :rw,
- lazy: true,
- }
-
- def build_something
- 1024
- end
-
- private
- def my_build_other_thing
- 128
- end
-end
-
-describe "LazyFox" do
- it "lazy attr should be act as a normal read only attr" do
- l = LazyFox.new(something: 0)
- l.something.should == 0
- end
-
- it "lazy attr should be read-only" do
- l = LazyFox.new
- expect{
- l.something= 1
- }.to raise_error(NoMethodError)
- end
-
- it "lazy: true but is :rw should act as a defered default value" do
- l = LazyFox.new
- l.other_thing.should == 128
- l.other_thing = 9
- l.other_thing.should == 9
- end
-
- it "lazy: true should not exists until necessary" do
- l = LazyFox.new
- l.has_other_thing?.should be_false
-
- l.other_thing.should == 128
-
- l.has_other_thing?.should be_true
- end
-
- it "lazy: true :rw should build again" do
- l = LazyFox.new
- l.other_thing.should == 128
-
- l.has_other_thing?.should be_true
-
- l.reset_other_thing!
-
- l.has_other_thing?.should be_false
-
- l.other_thing.should == 128
-
- l.has_other_thing?.should be_true
- end
-
- it "lazy attr should call build if necessary" do
- l = LazyFox.new
- l.something.should == 1024
- l.other_thing.should == 128
- end
-
- it "lazy attr should accept lambda" do
- l = LazyFox.new
- l.lazy_attr_who_accepts_lambda.should == 1024
- end
-
- it "lazy attr should accept lambda (2)" do
- l = LazyFox.new(something: 2)
- l.lazy_attr_who_accepts_lambda.should == 2
- end
-
- it "lazy_with_default should be initialize with default value" do
- l = LazyFox.new
- l.lazy_with_default.should == 10
- l.reset_lazy_with_default!
- l.lazy_with_default.should == 1
- end
-
- it "last_lazy_attr will raise error without a builder" do
- l = LazyFox.new
- expect {
- l.last_lazy_attr
- }.to raise_error(NoMethodError)
- end
-
- it "last_lazy_attr will not raise error with a builder" do
- l = LazyFox.new
- def l.build_last_lazy_attr
- 0
- end
- l.last_lazy_attr.should be_zero
- end
-end
-
-class CoerceTest
- include MooseX
-
- has attribute_ro: {
- is: :ro,
- isa: Integer,
- coerce: lambda {|value| value.to_i },
- }
-
- has attribute_rw: {
- is: :rw,
- isa: Integer,
- coerce: lambda {|value| value.to_i },
- }
-
- has attribute_lazy: {
- is: :lazy,
- isa: Integer,
- coerce: lambda {|value| value.to_i },
- builder: lambda{|object| "2048" },
- }
-
- def trigger_attr(new_value)
- puts "change value of attribute to #{new_value}"
- end
-end
-
-describe "CoerceTest" do
- it "should coerce the argument using to_i on constructor" do
- ct = CoerceTest.new(attribute_ro: "12")
- ct.attribute_ro.should == 12
- end
-
- it "should coerce the argument using to_i on constructor" do
- ct = CoerceTest.new(attribute_rw: "12")
- ct.attribute_rw.should == 12
- end
-
- it "should coerce in the setter" do
- ct = CoerceTest.new
- ct.attribute_rw= "128"
- ct.attribute_rw.should == 128
- end
-
- it "should coerce from builder" do
- ct = CoerceTest.new
- ct.attribute_lazy.should == 2048
- end
-end
-
-class TriggerTest
- include MooseX
-
- has logger: {
- is: :ro
- }
-
- has attr_with_trigger: {
- is: :rw,
- trigger: :my_method,
- }
-
- has attr_with_trigger_ro: {
- is: :ro,
- trigger: :my_method,
- }
-
- has attr_with_default: {
- is: :rw,
- trigger: lambda do |object, new_value|
- object.logger.log "will update attr_with_trigger with new value #{new_value}"
- end,
- default: 1,
- }
-
- has attr_lazy_trigger: {
- is: :lazy,
- trigger: :my_method,
- builder: lambda{ |x| 1},
- }
-
- def my_method(new_value)
- logger.log "will update attr_with_trigger with new value #{new_value}"
- end
-end
-
-describe "TriggerTest" do
- it "should call trigger on constructor" do
- log = double
- log.should_receive(:log)
- t = TriggerTest.new(attr_with_trigger: 1, logger: log)
-
- end
-
- it "should call trigger on constructor (ro)" do
- log = double
- log.should_receive(:log)
- t = TriggerTest.new(attr_with_trigger_ro: 1, logger: log)
-
- end
-
- it "should NOT call trigger on constructor (with default)" do
- log = double
- log.should_not_receive(:log)
- t = TriggerTest.new(logger: log)
- end
-
- it "should NOT call trigger on constructor (with default)" do
- log = double
- log.should_receive(:log)
- t = TriggerTest.new(logger: log)
-
- t.attr_with_default = 1
- end
-
- it "should call trigger on setter" do
- log = double
- log.should_receive(:log)
- t = TriggerTest.new(logger: log)
-
- t.attr_with_trigger = 1
- end
-
- it "should call trigger on setter" do
- log = double
- log.should_receive(:log)
- t = TriggerTest.new(logger: log)
-
- t.attr_lazy_trigger.should == 1
- end
-end
-
-class BuildArgsExample
- include MooseX
-
- has [:x, :y], {
- is: :rw,
- required: true,
- }
-
- def BUILDARGS(args)
- args[:x] = 1024
- args[:y] = - args[:y]
- args
- end
-end
-
-describe "BuildArgsExample" do
- it "should create the object" do
- ex = BuildArgsExample.new(x: 10, y: -2)
- ex.x.should == 1024
- ex.y.should == 2
- end
-end
-
-class BuildExample
- include MooseX
-
- has [:x, :y], {
- is: :rw,
- required: true,
- }
- def BUILD
- if self.x == self.y
- raise "invalid: you should use x != y"
- end
- end
-end
-
-describe "BuildExample" do
- it "should raise exception on build" do
- expect {
- BuildExample.new(x: 0, y: 0)
- }.to raise_error(/invalid: you should use x != y/)
+ it "should be possible create one single instance" do
+ a = A.new
+ a.is_a?(A).should be_true
end
end
\ No newline at end of file