gir_ffi 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
- == 0.0.1 / 2009-11-09
1
+ == 0.0.2 / 2010-11-14
2
2
 
3
- * Nothing to see yet, move along.
3
+ * Several fixes to method creation.
4
+
5
+ == 0.0.1 / 2010-10-25
6
+
7
+ * Initial release.
@@ -37,7 +37,7 @@ module GirFFI
37
37
  value
38
38
  end
39
39
 
40
- # Converts an outptr to a string array, then frees the outptr.
40
+ # Converts an outptr to a string array, then frees pointers.
41
41
  def self.outptr_to_string_array ptr, size
42
42
  return nil if ptr.nil?
43
43
 
@@ -49,7 +49,13 @@ module GirFFI
49
49
  ptrs = block.read_array_of_pointer(size)
50
50
  LibC.free block
51
51
 
52
- ptrs.map { |p| p.null? ? nil : (str = p.read_string; LibC.free p; str) }
52
+ ptrs.map do |p|
53
+ if p.null?
54
+ nil
55
+ else
56
+ p.read_string.tap { LibC.free p }
57
+ end
58
+ end
53
59
  end
54
60
 
55
61
  def self.mapped_callback_args prc=nil, &block
data/lib/gir_ffi/base.rb CHANGED
@@ -1,23 +1,35 @@
1
1
  require 'forwardable'
2
2
  module GirFFI
3
+ # Base class for all generated classes. Contains code for dealing with
4
+ # the generated Struct classes.
3
5
  class Base
4
6
  extend Forwardable
5
7
  def_delegators :@struct, :[], :[]=, :to_ptr
6
8
 
7
- def initialize(ptr=nil)
8
- @struct = ptr.nil? ?
9
- self.ffi_structure.new :
10
- self.ffi_structure.new(ptr)
9
+ def initialize(*args)
10
+ @struct = ffi_structure.new(*args)
11
11
  end
12
12
 
13
13
  def ffi_structure
14
14
  self.class.ffi_structure
15
15
  end
16
16
 
17
+ def _fake_missing *args, &block
18
+ method_missing method_name.to_sym, *args, &block
19
+ end
20
+
21
+ private
22
+
23
+ def method_name
24
+ caller[0].gsub(/.*`(.*)'/, '\1')
25
+ end
26
+
17
27
  class << self
18
28
  def ffi_structure
19
29
  self.const_get(:Struct)
20
30
  end
31
+ alias_method :_real_new, :new
32
+ undef new
21
33
  end
22
34
  end
23
35
  end
@@ -1,4 +1,3 @@
1
- require 'gir_ffi/class_base'
2
1
  require 'gir_ffi/arg_helper'
3
2
  require 'gir_ffi/function_definition_builder'
4
3
  require 'gir_ffi/constructor_definition_builder'
@@ -13,26 +12,65 @@ module GirFFI
13
12
  # introspection repository. Call its build_module and build_class methods
14
13
  # to create the modules and classes used in your program.
15
14
  module Builder
16
- def self.build_class namespace, classname, box=nil
17
- ClassBuilder.new(namespace, classname, box).generate
15
+ def self.build_class namespace, classname
16
+ ClassBuilder.new(namespace, classname).generate
18
17
  end
19
18
 
20
- def self.build_module namespace, box=nil
21
- ModuleBuilder.new(namespace, box).generate
19
+ def self.build_module namespace
20
+ ModuleBuilder.new(namespace).generate
22
21
  end
23
22
 
24
- # TODO: Make better interface
25
- def self.setup_method namespace, classname, lib, modul, klass, method
23
+ def self.setup_method namespace, classname, method
26
24
  go = method_introspection_data namespace, classname, method.to_s
27
25
 
28
- setup_function_or_method klass, modul, lib, go
26
+ return false if go.nil?
27
+ return false if go.type != :function
28
+
29
+ klass = build_class namespace, classname
30
+ modul = build_module namespace
31
+ lib = modul.const_get(:Lib)
32
+
33
+ attach_ffi_function lib, go
34
+
35
+ meta = (class << klass; self; end)
36
+ meta.class_eval function_definition(go, lib)
37
+
38
+ true
29
39
  end
30
40
 
31
- # TODO: Make better interface
32
- def self.setup_function namespace, lib, modul, method
41
+ def self.setup_function namespace, method
33
42
  go = function_introspection_data namespace, method.to_s
34
43
 
35
- setup_function_or_method modul, modul, lib, go
44
+ return false if go.nil?
45
+ return false if go.type != :function
46
+
47
+ modul = build_module namespace
48
+ lib = modul.const_get(:Lib)
49
+
50
+ attach_ffi_function lib, go
51
+
52
+ meta = (class << modul; self; end)
53
+ meta.class_eval function_definition(go, lib)
54
+
55
+ true
56
+ end
57
+
58
+ def self.setup_instance_method namespace, classname, method
59
+ go = method_introspection_data namespace, classname, method.to_s
60
+
61
+ return false if go.nil?
62
+ return false if go.type != :function
63
+
64
+ klass = build_class namespace, classname
65
+ modul = build_module namespace
66
+ lib = modul.const_get(:Lib)
67
+
68
+ attach_ffi_function lib, go
69
+
70
+ klass.class_eval "undef #{method}"
71
+ klass.class_eval function_definition(go, lib)
72
+
73
+ true
36
74
  end
37
75
 
38
76
  # All methods below will be made private at the end.
@@ -57,17 +95,17 @@ module GirFFI
57
95
  return objectinfo.find_method method
58
96
  end
59
97
 
60
- def self.attach_ffi_function modul, lib, info, box
98
+ def self.attach_ffi_function lib, info
61
99
  sym = info.symbol
62
- argtypes = ffi_function_argument_types modul, lib, info, box
63
- rt = ffi_function_return_type modul, lib, info, box
100
+ argtypes = ffi_function_argument_types info
101
+ rt = ffi_function_return_type info
64
102
 
65
103
  lib.attach_function sym, argtypes, rt
66
104
  end
67
105
 
68
- def self.ffi_function_argument_types modul, lib, info, box
106
+ def self.ffi_function_argument_types info
69
107
  types = info.args.map do |a|
70
- iarginfo_to_ffitype modul, lib, a, box
108
+ iarginfo_to_ffitype a
71
109
  end
72
110
  if info.type == :function
73
111
  types.unshift :pointer if info.method?
@@ -75,17 +113,11 @@ module GirFFI
75
113
  types
76
114
  end
77
115
 
78
- def self.ffi_function_return_type modul, lib, info, box
79
- itypeinfo_to_ffitype modul, lib, info.return_type, box
80
- end
81
-
82
- def self.define_ffi_types modul, lib, info, box
83
- info.args.each do |arg|
84
- type = iarginfo_to_ffitype modul, lib, arg, box
85
- end
116
+ def self.ffi_function_return_type info
117
+ itypeinfo_to_ffitype info.return_type
86
118
  end
87
119
 
88
- def self.itypeinfo_to_ffitype modul, lib, info, box
120
+ def self.itypeinfo_to_ffitype info
89
121
  if info.pointer?
90
122
  return :string if info.tag == :utf8
91
123
  return :pointer
@@ -95,65 +127,48 @@ module GirFFI
95
127
  interface = info.interface
96
128
  case interface.type
97
129
  when :object, :struct, :flags, :enum
98
- return build_class interface.namespace, interface.name, box
130
+ return build_class interface.namespace, interface.name
99
131
  when :callback
100
- return build_callback modul, lib, interface, box
132
+ return build_callback interface
101
133
  else
102
134
  raise NotImplementedError
103
135
  end
104
136
  when :boolean
105
137
  return :bool
138
+ when :GType
139
+ return :int32
106
140
  else
107
141
  return info.tag
108
142
  end
109
143
  end
110
144
 
111
- def self.iarginfo_to_ffitype modul, lib, info, box
145
+ def self.iarginfo_to_ffitype info
112
146
  return :pointer if info.direction == :inout
113
- return itypeinfo_to_ffitype modul, lib, info.type, box
147
+ return itypeinfo_to_ffitype info.type
114
148
  end
115
149
 
116
- def self.build_callback modul, lib, interface, box
150
+ def self.build_callback interface
151
+ modul = build_module interface.namespace
152
+ lib = modul.const_get(:Lib)
153
+
117
154
  sym = interface.name.to_sym
118
155
 
119
156
  # FIXME: Rescue is ugly here.
120
157
  ft = lib.find_type sym rescue nil
121
158
  if ft.nil?
122
- args = ffi_function_argument_types modul, lib, interface, box
123
- ret = ffi_function_return_type modul, lib, interface, box
159
+ args = ffi_function_argument_types interface
160
+ ret = ffi_function_return_type interface
124
161
  lib.callback sym, args, ret
125
162
  end
126
163
  sym
127
164
  end
128
165
 
129
- def self.setup_function_or_method klass, modul, lib, go
130
- return false if go.nil?
131
- return false if go.type != :function
132
-
133
- box = get_box modul
134
-
135
- define_ffi_types modul, lib, go, box
136
- attach_ffi_function modul, lib, go, box
137
-
138
- (class << klass; self; end).class_eval function_definition(go, lib)
139
- true
140
- end
141
-
142
- # TODO: This is a weird way to get back the box.
143
- def self.get_box modul
144
- name = modul.to_s
145
- if name =~ /::/
146
- return Kernel.const_get(name.split('::')[0])
147
- else
148
- return nil
149
- end
150
- end
151
-
152
166
  # Set up method access.
153
167
  (self.public_methods - Module.public_methods).each do |m|
154
168
  private_class_method m.to_sym
155
169
  end
156
- public_class_method :build_module, :build_class, :setup_method, :setup_function, :setup_function_or_method
170
+ public_class_method :build_module, :build_class
171
+ public_class_method :setup_method, :setup_function, :setup_instance_method
157
172
  public_class_method :itypeinfo_to_ffitype
158
173
  end
159
174
  end
@@ -2,10 +2,9 @@ module GirFFI
2
2
  # Builds a class based on information found in the introspection
3
3
  # repository.
4
4
  class ClassBuilder
5
- def initialize namespace, classname, box
5
+ def initialize namespace, classname
6
6
  @namespace = namespace
7
7
  @classname = classname
8
- @box = box
9
8
  end
10
9
 
11
10
  def generate
@@ -41,14 +40,14 @@ module GirFFI
41
40
  def get_superclass
42
41
  @parent = @info.type == :object ? @info.parent : nil
43
42
  if @parent
44
- @superclass = Builder.build_class @parent.namespace, @parent.name, @box
43
+ @superclass = Builder.build_class @parent.namespace, @parent.name
45
44
  else
46
45
  @superclass = GirFFI::Base
47
46
  end
48
47
  end
49
48
 
50
49
  def instantiate_module
51
- @module = Builder.build_module @namespace, @box
50
+ @module = Builder.build_module @namespace
52
51
  @lib = @module.const_get :Lib
53
52
  end
54
53
 
@@ -60,23 +59,8 @@ module GirFFI
60
59
 
61
60
  def setup_class
62
61
  setup_method_missing
63
- setup_base
64
62
  setup_layout
65
- setup_constructor
66
- end
67
-
68
- def setup_base
69
- return if @parent
70
- class << @klass
71
- self.class_eval { alias_method :_real_new, :new }
72
- end
73
- end
74
-
75
- def setup_constructor
76
- ctor = @info.find_method 'new'
77
- if not ctor.nil? and ctor.constructor?
78
- Builder.setup_function_or_method @klass, @module, @lib, ctor
79
- end
63
+ alias_instance_methods
80
64
  end
81
65
 
82
66
  def setup_method_missing
@@ -89,7 +73,7 @@ module GirFFI
89
73
  @info.fields.each do |f|
90
74
  layoutspec << f.name.to_sym
91
75
 
92
- ffitype = Builder.itypeinfo_to_ffitype @module, @lib, f.type, @box
76
+ ffitype = Builder.itypeinfo_to_ffitype f.type
93
77
  if ffitype.kind_of?(Class) and BuilderHelper.const_defined_for ffitype, :Struct
94
78
  ffitype = ffitype.const_get :Struct
95
79
  end
@@ -101,6 +85,14 @@ module GirFFI
101
85
  @structklass.class_eval { layout(*layoutspec) }
102
86
  end
103
87
 
88
+ def alias_instance_methods
89
+ @info.methods.each do |m|
90
+ @klass.class_eval do
91
+ alias_method m.name.to_sym, :_fake_missing
92
+ end
93
+ end
94
+ end
95
+
104
96
  def instance_method_missing_definition
105
97
  InstanceMethodMissingDefinitionBuilder.new(@lib, @module, @namespace, @classname).generate
106
98
  end
@@ -108,6 +108,7 @@ module GirFFI
108
108
 
109
109
  if tag == :interface
110
110
  interface = type.interface
111
+ GirFFI::Builder.build_class interface.namespace, interface.name
111
112
  @retvals << "#{interface.namespace}::#{interface.name}._real_new(#{retval})"
112
113
  else
113
114
  @retvals << retval
@@ -1,10 +1,14 @@
1
- require 'gir_ffi/class_base'
2
-
3
1
  module GirFFI
4
2
  # Wraps GIBaseInfo struct, the base \type for all info types.
5
3
  # Decendant types will be implemented as needed.
6
4
  class IBaseInfo
7
- include ClassBase
5
+ def initialize ptr
6
+ @gobj = ptr
7
+ end
8
+
9
+ def to_ptr
10
+ @gobj
11
+ end
8
12
 
9
13
  # This is a helper method to construct a method returning an array, out
10
14
  # of the methods returning their number and the individual elements.
@@ -11,13 +11,9 @@ module GirFFI
11
11
 
12
12
  return <<-CODE
13
13
  def #{slf}method_missing method, *arguments, &block
14
- result = GirFFI::Builder.#{fn} #{args.join ', '}, #{libs.join ', '}, self, method.to_s
14
+ result = GirFFI::Builder.#{fn} #{args.join ', '}, method.to_s
15
15
  return super unless result
16
- if block.nil?
17
- self.send method, *arguments
18
- else
19
- self.send method, *arguments, &block
20
- end
16
+ self.send method, *arguments, &block
21
17
  end
22
18
  CODE
23
19
  end
@@ -46,7 +42,7 @@ module GirFFI
46
42
  private
47
43
 
48
44
  def slf; ""; end
49
- def fn; "setup_method"; end
45
+ def fn; "setup_instance_method"; end
50
46
  def arguments; [@namespace, @classname]; end
51
47
  def libs; [@lib, @module]; end
52
48
  end
@@ -56,6 +52,7 @@ module GirFFI
56
52
  private
57
53
 
58
54
  def slf; "self."; end
55
+ def fn; "setup_method"; end
59
56
  end
60
57
 
61
58
  end
@@ -5,9 +5,8 @@ module GirFFI
5
5
  # repository.
6
6
  class ModuleBuilder
7
7
 
8
- def initialize namespace, box
8
+ def initialize namespace
9
9
  @namespace = namespace
10
- @box = box
11
10
  end
12
11
 
13
12
  def generate
@@ -28,12 +27,7 @@ module GirFFI
28
27
  end
29
28
 
30
29
  def setup_module
31
- if @box.nil?
32
- boxm = ::Object
33
- else
34
- boxm = BuilderHelper.get_or_define_module ::Object, @box.to_s
35
- end
36
- @module = BuilderHelper.get_or_define_module boxm, @namespace.to_s
30
+ @module = BuilderHelper.get_or_define_module ::Object, @namespace.to_s
37
31
  end
38
32
 
39
33
  def setup_lib_for_ffi
@@ -53,12 +47,11 @@ module GirFFI
53
47
  end
54
48
 
55
49
  def const_missing_definition
56
- box = @box.nil? ? "nil" : "\"#{@box}\""
57
50
  return <<-CODE
58
51
  def self.const_missing classname
59
52
  info = IRepository.default.find_by_name "#{@namespace}", classname.to_s
60
53
  return super if info.nil?
61
- return GirFFI::Builder.build_class "#{@namespace}", classname.to_s, #{box}
54
+ return GirFFI::Builder.build_class "#{@namespace}", classname.to_s
62
55
  end
63
56
  CODE
64
57
  end
@@ -1,4 +1,4 @@
1
- GirFFI::Builder.setup_function "Gtk", Gtk::Lib, Gtk, "init"
1
+ GirFFI::Builder.setup_function "Gtk", "init"
2
2
  module Gtk
3
3
  class << self
4
4
  alias _base_init init
data/test/base_test.rb ADDED
@@ -0,0 +1,72 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+ require 'gir_ffi/base'
3
+
4
+ class BaseTest < Test::Unit::TestCase
5
+ context "A class derived from GirFFI::Base" do
6
+ setup do
7
+ @klass = Class.new(GirFFI::Base) do
8
+ # Boilerplate to make regular #new work again.
9
+ def initialize; end
10
+ def self.new; self._real_new; end
11
+ end
12
+ end
13
+
14
+ should "be able to use method_name to get the names of its methods" do
15
+ @klass.class_eval do
16
+ def this_is_my_name
17
+ method_name
18
+ end
19
+ end
20
+ assert_equal "this_is_my_name", @klass.new.this_is_my_name
21
+ end
22
+
23
+ context "its #_fake_missing method" do
24
+ should "not be missing" do
25
+ assert @klass.new.respond_to? :_fake_missing
26
+ end
27
+
28
+ should "call method_missing" do
29
+ @klass.class_eval do
30
+ def method_missing method, *args
31
+ method
32
+ end
33
+ end
34
+ assert_equal :_fake_missing, @klass.new._fake_missing
35
+ end
36
+
37
+ should "pass on its arguments" do
38
+ @klass.class_eval do
39
+ def method_missing method, *args
40
+ args.join(', ')
41
+ end
42
+ end
43
+ assert_equal "a, b", @klass.new._fake_missing("a", "b")
44
+ end
45
+
46
+ should "pass on a given block" do
47
+ @klass.class_eval do
48
+ def method_missing method, *args
49
+ yield if block_given?
50
+ end
51
+ end
52
+ assert_equal :called, @klass.new._fake_missing { :called }
53
+ end
54
+ end
55
+
56
+ should "be able to use alias_method to create a self-defining method" do
57
+ @klass.class_eval do
58
+ def method_missing method, *args
59
+ self.class.class_eval "
60
+ undef #{method}
61
+ def #{method}
62
+ :redefined
63
+ end
64
+ "
65
+ self.send method
66
+ end
67
+ alias_method :new_method, :_fake_missing
68
+ end
69
+ assert_equal :redefined, @klass.new.new_method
70
+ end
71
+ end
72
+ end
data/test/builder_test.rb CHANGED
@@ -1,105 +1,105 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
- require 'gir_ffi/builder'
2
+ require 'gir_ffi'
3
3
 
4
4
  class BuilderTest < Test::Unit::TestCase
5
5
  context "The GirFFI::Builder module" do
6
6
  # TODO: Use gir's sample Everything library for testing instead.
7
7
  context "building GObject::Object" do
8
8
  setup do
9
- GirFFI::Builder.build_class 'GObject', 'Object', 'NS1'
9
+ cleanup_module :GObject
10
+ GirFFI::Builder.build_class 'GObject', 'Object'
10
11
  end
11
12
 
12
13
  should "create a method_missing method for the class" do
13
- ms = NS1::GObject::Object.instance_methods(false).map(&:to_sym)
14
+ ms = GObject::Object.instance_methods(false).map(&:to_sym)
14
15
  assert_contains ms, :method_missing
15
16
  end
16
17
 
17
18
  should "create a Lib module in the parent namespace ready to attach functions from gobject-2.0" do
18
19
  gir = GirFFI::IRepository.default
19
20
  expected = gir.shared_library 'GObject'
20
- assert_same_elements [*expected], NS1::GObject::Lib.ffi_libraries.map(&:name)
21
+ assert_same_elements [*expected], GObject::Lib.ffi_libraries.map(&:name)
21
22
  end
22
23
 
23
24
  should "create an array CALLBACKS inside the GObject::Lib module" do
24
- assert_equal [], NS1::GObject::Lib::CALLBACKS
25
+ assert_equal [], GObject::Lib::CALLBACKS
25
26
  end
26
27
 
27
28
  should "not replace existing classes" do
28
- oldclass = NS1::GObject::Object
29
- GirFFI::Builder.build_class 'GObject', 'Object', 'NS1'
30
- assert_equal oldclass, NS1::GObject::Object
29
+ oldclass = GObject::Object
30
+ GirFFI::Builder.build_class 'GObject', 'Object'
31
+ assert_equal oldclass, GObject::Object
31
32
  end
32
33
  end
33
34
 
34
35
  context "building Gtk::Window" do
35
36
  setup do
36
- GirFFI::Builder.build_class 'Gtk', 'Window', 'NS3'
37
+ cleanup_module :Gtk
38
+ cleanup_module :GObject
39
+ GirFFI::Builder.build_class 'Gtk', 'Window'
37
40
  end
38
41
 
39
42
  should "build Gtk namespace" do
40
- assert NS3::Gtk.const_defined? :Lib
41
- assert NS3::Gtk.respond_to? :method_missing
43
+ assert Gtk.const_defined? :Lib
44
+ assert Gtk.respond_to? :method_missing
42
45
  end
43
46
 
44
47
  should "build parent classes also" do
45
- assert NS3::Gtk.const_defined? :Widget
46
- assert NS3::Gtk.const_defined? :Object
47
- assert NS3.const_defined? :GObject
48
- assert NS3::GObject.const_defined? :InitiallyUnowned
49
- assert NS3::GObject.const_defined? :Object
48
+ assert Gtk.const_defined? :Widget
49
+ assert Gtk.const_defined? :Object
50
+ assert Object.const_defined? :GObject
51
+ assert GObject.const_defined? :InitiallyUnowned
52
+ assert GObject.const_defined? :Object
50
53
  end
51
54
 
52
55
  should "set up inheritence chain" do
53
56
  assert_equal [
54
- NS3::Gtk::Window,
55
- NS3::Gtk::Bin,
56
- NS3::Gtk::Container,
57
- NS3::Gtk::Widget,
58
- NS3::Gtk::Object,
59
- NS3::GObject::InitiallyUnowned,
60
- NS3::GObject::Object
61
- ], NS3::Gtk::Window.ancestors[0..6]
57
+ Gtk::Window,
58
+ Gtk::Bin,
59
+ Gtk::Container,
60
+ Gtk::Widget,
61
+ Gtk::Object,
62
+ GObject::InitiallyUnowned,
63
+ GObject::Object
64
+ ], Gtk::Window.ancestors[0..6]
62
65
  end
63
66
 
64
67
  should "create a Gtk::Window#to_ptr method" do
65
- assert_contains NS3::Gtk::Window.instance_methods.map(&:to_sym), :to_ptr
66
- end
67
-
68
- should "attach gtk_window_new to Gtk::Lib" do
69
- assert NS3::Gtk::Lib.respond_to? :gtk_window_new
68
+ assert_contains Gtk::Window.instance_methods.map(&:to_sym), :to_ptr
70
69
  end
71
70
 
72
71
  should "result in Gtk::Window.new to succeed" do
73
- assert_nothing_raised {NS3::Gtk::Window.new(:toplevel)}
72
+ assert_nothing_raised {Gtk::Window.new(:toplevel)}
74
73
  end
75
74
  end
76
75
 
77
76
  context "building Gtk" do
78
77
  setup do
79
- GirFFI::Builder.build_module 'Gtk', 'NS2'
78
+ cleanup_module :Gtk
79
+ GirFFI::Builder.build_module 'Gtk'
80
80
  end
81
81
 
82
82
  should "create a Lib module ready to attach functions from gtk-x11-2.0" do
83
83
  # The Gtk module has more than one library on my current machine.
84
84
  gir = GirFFI::IRepository.default
85
85
  expected = (gir.shared_library 'Gtk').split(',')
86
- assert_same_elements expected, NS2::Gtk::Lib.ffi_libraries.map(&:name)
86
+ assert_same_elements expected, Gtk::Lib.ffi_libraries.map(&:name)
87
87
  end
88
88
 
89
89
  should "create an array CALLBACKS inside the Gtk::Lib module" do
90
- assert_equal [], NS2::Gtk::Lib::CALLBACKS
90
+ assert_equal [], Gtk::Lib::CALLBACKS
91
91
  end
92
92
 
93
93
  should "not replace existing module" do
94
- oldmodule = NS2::Gtk
95
- GirFFI::Builder.build_module 'Gtk', 'NS2'
96
- assert_equal oldmodule, NS2::Gtk
94
+ oldmodule = Gtk
95
+ GirFFI::Builder.build_module 'Gtk'
96
+ assert_equal oldmodule, Gtk
97
97
  end
98
98
 
99
99
  should "not replace existing Lib module" do
100
- oldmodule = NS2::Gtk::Lib
101
- GirFFI::Builder.build_module 'Gtk', 'NS2'
102
- assert_equal oldmodule, NS2::Gtk::Lib
100
+ oldmodule = Gtk::Lib
101
+ GirFFI::Builder.build_module 'Gtk'
102
+ assert_equal oldmodule, Gtk::Lib
103
103
  end
104
104
  end
105
105
 
@@ -131,7 +131,7 @@ class BuilderTest < Test::Unit::TestCase
131
131
  ffi_lib "gtk-x11-2.0"
132
132
  end
133
133
 
134
- GirFFI::Builder.send :attach_ffi_function, mod, libmod, @go, nil
134
+ GirFFI::Builder.send :attach_ffi_function, libmod, @go
135
135
  assert_contains libmod.public_methods.map(&:to_sym), :gtk_main
136
136
  end
137
137
  end
@@ -151,11 +151,11 @@ class BuilderTest < Test::Unit::TestCase
151
151
  should "have :pointer, :pointer as types of the arguments for the attached function" do
152
152
  # FIXME: Ideally, we attach the function and test that it requires
153
153
  # the correct argument types.
154
- assert_equal [:pointer, :pointer], GirFFI::Builder.send(:ffi_function_argument_types, Gtk, Gtk::Lib, @go, nil)
154
+ assert_equal [:pointer, :pointer], GirFFI::Builder.send(:ffi_function_argument_types, @go)
155
155
  end
156
156
 
157
157
  should "have :void as return type for the attached function" do
158
- assert_equal :void, GirFFI::Builder.send(:ffi_function_return_type, Gtk, Gtk::Lib, @go, nil)
158
+ assert_equal :void, GirFFI::Builder.send(:ffi_function_return_type, @go)
159
159
  end
160
160
  end
161
161
 
@@ -171,14 +171,15 @@ class BuilderTest < Test::Unit::TestCase
171
171
  end
172
172
 
173
173
  should "have :pointer as types of the arguments for the attached function" do
174
- assert_equal [:pointer], GirFFI::Builder.send(:ffi_function_argument_types, Gtk, Gtk::Lib, @go, nil)
174
+ assert_equal [:pointer], GirFFI::Builder.send(:ffi_function_argument_types, @go)
175
175
  end
176
176
 
177
177
  end
178
178
 
179
179
  context "looking at GObject.signal_connect_data" do
180
180
  setup do
181
- GirFFI::Builder.build_module 'GObject', 'NS5'
181
+ cleanup_module :GObject
182
+ GirFFI::Builder.build_module 'GObject'
182
183
  @go = get_function_introspection_data 'GObject', 'signal_connect_data'
183
184
  end
184
185
 
@@ -189,14 +190,14 @@ class BuilderTest < Test::Unit::TestCase
189
190
  end
190
191
 
191
192
  should "have the correct types of the arguments for the attached function" do
192
- assert_equal [:pointer, :string, :Callback, :pointer, :ClosureNotify, NS5::GObject::ConnectFlags],
193
- GirFFI::Builder.send(:ffi_function_argument_types, NS5::GObject, NS5::GObject::Lib, @go, 'NS5')
193
+ assert_equal [:pointer, :string, :Callback, :pointer, :ClosureNotify, GObject::ConnectFlags],
194
+ GirFFI::Builder.send(:ffi_function_argument_types, @go)
194
195
  end
195
196
 
196
197
  should "define ffi callback types :Callback and :ClosureNotify" do
197
- GirFFI::Builder.setup_function 'GObject', NS5::GObject::Lib, NS5::GObject, 'signal_connect_data'
198
- cb = NS5::GObject::Lib.find_type :Callback
199
- cn = NS5::GObject::Lib.find_type :ClosureNotify
198
+ GirFFI::Builder.setup_function 'GObject', 'signal_connect_data'
199
+ cb = GObject::Lib.find_type :Callback
200
+ cn = GObject::Lib.find_type :ClosureNotify
200
201
 
201
202
  assert_equal FFI.find_type(:void), cb.result_type
202
203
  assert_equal FFI.find_type(:void), cn.result_type
@@ -205,7 +206,7 @@ class BuilderTest < Test::Unit::TestCase
205
206
  end
206
207
 
207
208
  should "define ffi enum type ConnectFlags" do
208
- assert_equal({:after => 1, :swapped => 2}, NS5::GObject::ConnectFlags.to_h)
209
+ assert_equal({:after => 1, :swapped => 2}, GObject::ConnectFlags.to_h)
209
210
  end
210
211
  end
211
212
 
@@ -240,88 +241,81 @@ class BuilderTest < Test::Unit::TestCase
240
241
  should "set up #_real_new as an alias to #new" do
241
242
  assert Everything::TestBoxed.respond_to? "_real_new"
242
243
  end
244
+ end
243
245
 
244
- should "allow creation using #new" do
245
- tb = Everything::TestBoxed.new
246
- assert_instance_of Everything::TestBoxed, tb
247
- end
248
-
249
- should "allow creation using alternative constructors" do
250
- tb = Everything::TestBoxed.new_alternative_constructor1 1
251
- assert_instance_of Everything::TestBoxed, tb
252
- assert_equal 1, tb[:some_int8]
253
-
254
- tb = Everything::TestBoxed.new_alternative_constructor2 1, 2
255
- assert_instance_of Everything::TestBoxed, tb
256
- assert_equal 1 + 2, tb[:some_int8]
246
+ # TODO: Should not allow functions to be called as methods, etc.
257
247
 
258
- tb = Everything::TestBoxed.new_alternative_constructor3 "54"
259
- assert_instance_of Everything::TestBoxed, tb
260
- assert_equal 54, tb[:some_int8]
248
+ context "building the Everything module" do
249
+ setup do
250
+ cleanup_module :Everything
251
+ GirFFI::Builder.build_module 'Everything'
261
252
  end
262
253
 
263
- should "make the equals method work" do
264
- tb = Everything::TestBoxed.new_alternative_constructor1 123
265
- tb2 = Everything::TestBoxed.new_alternative_constructor2 120, 3
266
- assert_equal true, tb.equals(tb2)
254
+ should "create a method_missing method for the module" do
255
+ ms = (Everything.public_methods - Module.public_methods).map(&:to_sym)
256
+ assert_contains ms, :method_missing
267
257
  end
268
258
 
269
- should "make the copy method work" do
270
- tb = Everything::TestBoxed.new_alternative_constructor1 123
271
- tb2 = tb.copy
272
- assert_instance_of Everything::TestBoxed, tb2
273
- assert_equal 123, tb2[:some_int8], "fields copied"
274
- tb2[:some_int8] = 89
275
- assert_equal 123, tb[:some_int8], "is a true copy"
259
+ should "cause the TestObj class to be autocreated" do
260
+ assert !Everything.const_defined?(:TestObj)
261
+ assert_nothing_raised {Everything::TestObj}
262
+ assert Everything.const_defined? :TestObj
276
263
  end
277
264
  end
278
265
 
279
- context "building Everything::TestEnum" do
266
+ # TODO: Turn this into full test of instance method creation, including
267
+ # inheritance issues.
268
+ context "built Everything::TestObj" do
280
269
  setup do
281
- GirFFI::Builder.build_class 'Everything', 'TestEnum'
270
+ cleanup_module :Everything
271
+ GirFFI::Builder.build_class 'Everything', 'TestObj'
282
272
  end
283
- should "create an object of type FFI::Enum" do
284
- assert_instance_of FFI::Enum, Everything::TestEnum
285
- end
286
- end
287
-
288
- # TODO: Should not allow functions to be called as methods, etc.
289
273
 
290
- context "looking at Everything's functions" do
291
- setup do
292
- GirFFI::Builder.build_module 'Everything'
274
+ should "make autocreated instance method available to all instances" do
275
+ o1 = Everything::TestObj.new_from_file("foo")
276
+ o2 = Everything::TestObj.new_from_file("foo")
277
+ o1.instance_method
278
+ Everything::TestObj.class_eval do
279
+ undef method_missing
280
+ end
281
+ assert_nothing_raised { o2.instance_method }
293
282
  end
294
283
 
295
- should "correctly handle test_boolean" do
296
- assert_equal false, Everything.test_boolean(false)
297
- assert_equal true, Everything.test_boolean(true)
284
+ should "attach C functions to Everything::Lib" do
285
+ o = Everything::TestObj.new_from_file("foo")
286
+ o.instance_method
287
+ assert Everything::Lib.respond_to? :test_obj_instance_method
298
288
  end
299
289
 
300
- should "correctly handle test_callback_user_data" do
301
- a = :foo
302
- result = Everything.test_callback_user_data Proc.new {|u|
303
- a = u
304
- 5
305
- }, :bar
306
- assert_equal :bar, a
307
- assert_equal 5, result
290
+ should "not have regular #new as a constructor" do
291
+ assert_raises(NoMethodError) { Everything::TestObj.new }
308
292
  end
309
293
  end
310
294
 
311
- context "building the Everything module" do
295
+ context "built Everything::TestSubObj" do
312
296
  setup do
313
- GirFFI::Builder.build_module 'Everything', 'NS4'
297
+ cleanup_module :Everything
298
+ GirFFI::Builder.build_class 'Everything', 'TestSubObj'
314
299
  end
315
300
 
316
- should "create a method_missing method for the module" do
317
- ms = (NS4::Everything.public_methods - Module.public_methods).map(&:to_sym)
318
- assert_contains ms, :method_missing
301
+ should "autocreate parent class' set_bare inside the parent class" do
302
+ o1 = Everything::TestSubObj.new
303
+ o2 = Everything::TestObj.new_from_file("foo")
304
+
305
+ assert_nothing_raised {o1.set_bare(nil)}
306
+
307
+ Everything::TestObj.class_eval do
308
+ undef method_missing
309
+ end
310
+
311
+ assert_nothing_raised {o2.set_bare(nil)}
319
312
  end
320
313
 
321
- should "cause the TestObj class to be autocreated" do
322
- assert !NS4::Everything.const_defined?(:TestObj)
323
- assert_nothing_raised {NS4::Everything::TestObj}
324
- assert NS4::Everything.const_defined? :TestObj
314
+ should "use its own version of instance_method when parent's version has been created" do
315
+ obj = Everything::TestObj.new_from_file("foo")
316
+ assert_equal(-1, obj.instance_method)
317
+ subobj = Everything::TestSubObj.new
318
+ assert_equal 0, subobj.instance_method
325
319
  end
326
320
  end
327
321
  end
@@ -1,5 +1,5 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
- require 'gir_ffi/builder'
2
+ require 'gir_ffi'
3
3
 
4
4
  class ConstructorDefinitionBuilderTest < Test::Unit::TestCase
5
5
  context "The ConstructorDefinitionBuilder" do
@@ -0,0 +1,78 @@
1
+ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
+ require 'gir_ffi'
3
+
4
+ GirFFI.setup :Everything
5
+
6
+ # Tests generated methods and functions in the Everything namespace.
7
+ class EverythingTest < Test::Unit::TestCase
8
+ context "The generated Everything module" do
9
+ should "have correct test_boolean" do
10
+ assert_equal false, Everything.test_boolean(false)
11
+ assert_equal true, Everything.test_boolean(true)
12
+ end
13
+
14
+ should "have correct test_callback_user_data" do
15
+ a = :foo
16
+ result = Everything.test_callback_user_data Proc.new {|u|
17
+ a = u
18
+ 5
19
+ }, :bar
20
+ assert_equal :bar, a
21
+ assert_equal 5, result
22
+ end
23
+
24
+ should "have correct test_gtype" do
25
+ result = Everything.test_gtype 23
26
+ assert_equal 23, result
27
+ end
28
+
29
+ should "have correct test_value_return" do
30
+ result = Everything.test_value_return 3423
31
+ assert_equal 3423, result.get_int
32
+ end
33
+
34
+ context "the Everything::TestBoxed class" do
35
+ should "create an instance using #new" do
36
+ tb = Everything::TestBoxed.new
37
+ assert_instance_of Everything::TestBoxed, tb
38
+ end
39
+
40
+ should "allow creating an instance using alternative constructors" do
41
+ tb = Everything::TestBoxed.new_alternative_constructor1 1
42
+ assert_instance_of Everything::TestBoxed, tb
43
+ assert_equal 1, tb[:some_int8]
44
+
45
+ tb = Everything::TestBoxed.new_alternative_constructor2 1, 2
46
+ assert_instance_of Everything::TestBoxed, tb
47
+ assert_equal 1 + 2, tb[:some_int8]
48
+
49
+ tb = Everything::TestBoxed.new_alternative_constructor3 "54"
50
+ assert_instance_of Everything::TestBoxed, tb
51
+ assert_equal 54, tb[:some_int8]
52
+ end
53
+
54
+ should "have a working equals method" do
55
+ tb = Everything::TestBoxed.new_alternative_constructor1 123
56
+ tb2 = Everything::TestBoxed.new_alternative_constructor2 120, 3
57
+ assert_equal true, tb.equals(tb2)
58
+ end
59
+
60
+ should "have a working copy method" do
61
+ tb = Everything::TestBoxed.new_alternative_constructor1 123
62
+ tb2 = tb.copy
63
+ assert_instance_of Everything::TestBoxed, tb2
64
+ assert_equal 123, tb2[:some_int8], "fields copied"
65
+ tb2[:some_int8] = 89
66
+ assert_equal 123, tb[:some_int8], "is a true copy"
67
+ end
68
+ end
69
+
70
+ context "the Everything::TestEnum type" do
71
+ should "be of type FFI::Enum" do
72
+ assert_instance_of FFI::Enum, Everything::TestEnum
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -1,6 +1,5 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
- require 'gir_ffi/builder'
3
- require 'gir_ffi/function_definition_builder'
2
+ require 'gir_ffi'
4
3
 
5
4
  class FunctionDefinitionBuilderTest < Test::Unit::TestCase
6
5
  context "The FunctionDefinition builder" do
@@ -1,13 +1,18 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
2
  require 'gir_ffi'
3
- GirFFI.setup :Gtk
4
3
 
5
4
  class GtkOverridesTest < Test::Unit::TestCase
6
5
  context "The Gtk.init function" do
6
+ setup do
7
+ cleanup_module :Gtk
8
+ GirFFI.setup :Gtk
9
+ end
10
+
7
11
  should "not take any arguments" do
8
12
  assert_raises(ArgumentError) { Gtk.init 1, ["foo"] }
9
13
  assert_nothing_raised { Gtk.init }
10
14
  end
15
+
11
16
  # FIXME: The following test doesn't actually work.
12
17
  # In practice however, the Gtk.init function does exactly this.
13
18
  if false
data/test/test_helper.rb CHANGED
@@ -36,4 +36,10 @@ class Test::Unit::TestCase
36
36
  GirFFI::IRepository.default.require namespace, nil
37
37
  GirFFI::Builder.send :method_introspection_data, namespace, klass, function
38
38
  end
39
+
40
+ def cleanup_module name
41
+ if Object.const_defined? name
42
+ Object.send(:remove_const, name)
43
+ end
44
+ end
39
45
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gir_ffi
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matijs van Zuijlen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-25 00:00:00 +02:00
18
+ date: 2010-11-14 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -84,7 +84,6 @@ files:
84
84
  - lib/gir_ffi/i_repository.rb
85
85
  - lib/gir_ffi/i_vfunc_info.rb
86
86
  - lib/gir_ffi/i_constant_info.rb
87
- - lib/gir_ffi/class_base.rb
88
87
  - lib/gir_ffi/i_struct_info.rb
89
88
  - lib/gir_ffi/i_callable_info.rb
90
89
  - lib/gir_ffi/function_definition_builder.rb
@@ -108,6 +107,8 @@ files:
108
107
  - test/test_helper.rb
109
108
  - test/girffi_test.rb
110
109
  - test/constructor_definition_builder_test.rb
110
+ - test/base_test.rb
111
+ - test/everything_test.rb
111
112
  - test/builder_test.rb
112
113
  - test/gtk_overrides_test.rb
113
114
  - tasks/bones.rake
@@ -164,8 +165,10 @@ specification_version: 3
164
165
  summary: Ruby-FFI-based binding of the GObject Introspection Repository
165
166
  test_files:
166
167
  - test/arg_helper_test.rb
168
+ - test/base_test.rb
167
169
  - test/builder_test.rb
168
170
  - test/constructor_definition_builder_test.rb
171
+ - test/everything_test.rb
169
172
  - test/function_definition_builder_test.rb
170
173
  - test/g_type_test.rb
171
174
  - test/girffi_test.rb
@@ -1,11 +0,0 @@
1
- module GirFFI
2
- # Provides methods needed by all generated classes
3
- module ClassBase
4
- def initialize ptr
5
- @gobj = ptr
6
- end
7
- def to_ptr
8
- @gobj
9
- end
10
- end
11
- end