gir_ffi 0.0.1 → 0.0.2

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.
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