require "test_helper" describe "Querying for classes" do before do @source ||= RbGCCXML.parse(full_dir("headers/classes.hpp")).namespaces("classes") end specify "can find all classes in a given namespace" do classes = @source.classes classes.size.should == 4 classes.find(:name => "Test1").should_not be_nil classes.find(:name => "Test2").should_not be_nil classes.find(:name => "Test3").should_not be_nil end specify "can find classes within classes" do test1 = @source.classes.find(:name => "Test1") test1.should_not be_nil test1.should be_kind_of(RbGCCXML::Class) test1.name.should == "Test1" inner1 = test1.classes("Inner1") inner1.should_not be_nil inner1.should be_kind_of(RbGCCXML::Class) inner1.name.should == "Inner1" inner2 = inner1.classes("Inner1") inner2.should_not be_nil inner2.should be_kind_of(Array) inner2.should be_empty inner2 = inner1.classes("Inner2") inner2.should_not be_nil inner2.should be_kind_of(RbGCCXML::Class) inner2.name.should == "Inner2" end specify "can find classes within classes by regex" do test1 = @source.classes(/t1/) test1.should_not be_nil test1.should be_kind_of(RbGCCXML::Class) test1.name.should == "Test1" inner1 = test1.classes(/In.*1/) inner1.should_not be_nil inner1.should be_kind_of(RbGCCXML::Class) inner1.name.should == "Inner1" inner2 = inner1.classes(/1/) inner2.should_not be_nil inner2.should be_kind_of(Array) inner2.should be_empty inner2 = inner1.classes(/2/) inner2.should_not be_nil inner2.should be_kind_of(RbGCCXML::Class) inner2.name.should == "Inner2" end specify "can find classes within classes by block" do # We're looking for any class that has virtual methods. test4 = @source.classes.select { |c| c.methods.any? { |m| m.virtual? } } test4.should_not be_nil test4.should be_kind_of(RbGCCXML::Class) test4.name.should == "Test4" # Fail case -- there's no methods that return double. test0 = @source.classes.select { |c| c.methods.any? { |m| m.return_type == "double" }} test0.should_not be_nil test0.should be_kind_of(Array) test0.should be_empty end specify "can tell if a class is pure virtual" do test1 = @source.classes("Test1") test4 = @source.classes("Test4") test1.pure_virtual?.should == false test4.pure_virtual?.should == true end end describe "Querying for class constructors" do before do @source ||= RbGCCXML.parse(full_dir("headers/classes.hpp")).namespaces("classes") end specify "should have a list of constructors" do test1 = @source.classes.find(:name => "Test1") test1.constructors.size.should == 2 test2 = @source.classes.find(:name => "Test2") test2.constructors.size.should == 3 end specify "constructors should have arguments" do test2 = @source.classes.find(:name => "Test2") test2.constructors.size.should == 3 # GCC generated copy constructors copy = test2.constructors.detect {|c| c.artificial? } copy.should_not be_nil default = test2.constructors.detect {|c| c.arguments.size == 0 } default.should_not be_nil specific = test2.constructors.detect {|c| c.arguments.size == 1 } specific.should_not be_nil specific.arguments[0].cpp_type.name.should == "int" end end describe "Querying for the class's deconstructor" do before do @source ||= RbGCCXML.parse(full_dir("headers/classes.hpp")).namespaces("classes") end specify "can tell if a class has an explicit destructor" do test1 = @source.classes("Test1") test1.destructor.should_not be_nil test1.destructor.artificial?.should == false test2 = @source.classes("Test2") test2.destructor.should_not be_nil test2.destructor.artificial?.should == true end end describe "Query for class variables" do before do @source ||= RbGCCXML.parse(full_dir("headers/classes.hpp")).namespaces("classes") end specify "find all i-vars" do test1 = @source.classes("Test1") test1.variables.length.should == 4 end specify "can find by access level" do test1 = @source.classes("Test1") test1.variables.find(:access => "public").length.should == 2 test1.variables.find(:access => "protected").name.should == "protVariable" test1.variables.find(:access => "private").name.should == "privateVariable" end end describe "Query inheritance heirarchy" do before do @source ||= RbGCCXML.parse(full_dir("headers/inheritance.hpp")).namespaces("inheritance") end specify "can find a class's superclass" do pc = @source.classes("ParentClass") pc.superclass.should be_nil base1 = @source.classes("Base1") base1.superclass.should_not be_nil base1.superclass.name.should == "ParentClass" end specify "can query for multiple inheritance" do multi = @source.classes("MultiBase") multi.superclasses.length.should == 2 multi.superclasses.should be_a_kind_of(RbGCCXML::QueryResult) multi.superclasses.select {|sp| sp.name == "ParentClass"}.should_not be_nil multi.superclasses.select {|sp| sp.name == "Parent2"}.should_not be_nil end specify "calling #superclasses always returns an array" do pc = @source.classes("ParentClass") pc.superclasses.should be_empty base1 = @source.classes("Base1") base1.superclasses.length.should == 1 base1.superclasses[0].name.should == "ParentClass" end specify "can infinitely climb the inheritance heirarchy" do low = @source.classes("VeryLow") low.superclass.superclass.superclass.name.should == "ParentClass" end specify "can query for types of inheritance" do pvb1 = @source.classes("PrivateBase1") pvb1.superclass(:public).should be_nil pvb1.superclass(:protected).should be_nil pvb1.superclass(:private).should_not be_nil pvb1.superclass(:private).name.should == "ParentClass" pvb1.superclasses(:public).length.should == 0 pvb1.superclasses(:protected).length.should == 0 pvb1.superclasses(:private).length.should == 1 vlow = @source.classes("VeryLow") vlow.superclasses(:public).length.should == 1 vlow.superclasses(:private).length.should == 0 vlow.superclasses(:protected).length.should == 1 end end