qbfc 0.1.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +41 -0
  3. data/Rakefile +82 -0
  4. data/lib/qbfc.rb +39 -0
  5. data/lib/qbfc/base.rb +82 -0
  6. data/lib/qbfc/element.rb +178 -0
  7. data/lib/qbfc/entities/generated.rb +8 -0
  8. data/lib/qbfc/entity.rb +11 -0
  9. data/lib/qbfc/info.rb +42 -0
  10. data/lib/qbfc/infos/generated.rb +9 -0
  11. data/lib/qbfc/item.rb +10 -0
  12. data/lib/qbfc/items/generated.rb +11 -0
  13. data/lib/qbfc/list.rb +84 -0
  14. data/lib/qbfc/lists/generated.rb +15 -0
  15. data/lib/qbfc/lists/qb_class.rb +25 -0
  16. data/lib/qbfc/modifiable.rb +31 -0
  17. data/lib/qbfc/ole_wrapper.rb +193 -0
  18. data/lib/qbfc/qb_collection.rb +26 -0
  19. data/lib/qbfc/qb_types.rb +34 -0
  20. data/lib/qbfc/qbfc_const.rb +14 -0
  21. data/lib/qbfc/request.rb +158 -0
  22. data/lib/qbfc/session.rb +136 -0
  23. data/lib/qbfc/terms.rb +10 -0
  24. data/lib/qbfc/terms/generated.rb +10 -0
  25. data/lib/qbfc/transaction.rb +83 -0
  26. data/lib/qbfc/transactions/generated.rb +18 -0
  27. data/lib/qbfc/voidable.rb +11 -0
  28. data/spec/rcov.opts +1 -0
  29. data/spec/spec.opts +6 -0
  30. data/spec/spec_helper.rb +62 -0
  31. data/spec/unit/base_spec.rb +138 -0
  32. data/spec/unit/element_finder_spec.rb +180 -0
  33. data/spec/unit/element_spec.rb +118 -0
  34. data/spec/unit/entities/generated_spec.rb +18 -0
  35. data/spec/unit/entity_spec.rb +18 -0
  36. data/spec/unit/info/generated_spec.rb +12 -0
  37. data/spec/unit/info_spec.rb +48 -0
  38. data/spec/unit/item_spec.rb +18 -0
  39. data/spec/unit/items/generated_spec.rb +16 -0
  40. data/spec/unit/list_finders_spec.rb +128 -0
  41. data/spec/unit/list_spec.rb +86 -0
  42. data/spec/unit/lists/generated_spec.rb +15 -0
  43. data/spec/unit/lists/qb_class_spec.rb +9 -0
  44. data/spec/unit/modifiable_spec.rb +84 -0
  45. data/spec/unit/ole_wrapper_spec.rb +293 -0
  46. data/spec/unit/qb_collection_spec.rb +13 -0
  47. data/spec/unit/qbfc_const_spec.rb +10 -0
  48. data/spec/unit/qbfc_spec.rb +10 -0
  49. data/spec/unit/request_query_survey.txt +48 -0
  50. data/spec/unit/request_spec.rb +236 -0
  51. data/spec/unit/session_spec.rb +138 -0
  52. data/spec/unit/terms/generated_spec.rb +14 -0
  53. data/spec/unit/terms_spec.rb +18 -0
  54. data/spec/unit/transaction_finders_spec.rb +124 -0
  55. data/spec/unit/transaction_spec.rb +94 -0
  56. data/spec/unit/transactions/generated_spec.rb +20 -0
  57. data/spec/unit/voidable_spec.rb +32 -0
  58. metadata +140 -0
@@ -0,0 +1,18 @@
1
+ module QBFC
2
+
3
+ # Generated Transaction types
4
+ TXN_TYPES = %w{ARRefundCreditCard Bill BillPaymentCheck BillPaymentCreditCard BuildAssembly Charge Check CreditCardCharge
5
+ CreditCardCredit CreditMemo Deposit Estimate InventoryAdjustment Invoice ItemReceipt JournalEntry PurchaseOrder
6
+ ReceivePayment SalesOrder SalesReceipt SalesTaxPaymentCheck TimeTracking VehicleMileage VendorCredit}
7
+
8
+ # Generated Transaction types that support TxnVoid Request
9
+ TXN_VOIDABLE_TYPES = %w{ARRefundCreditCard Bill BillPaymentCheck BillPaymentCreditCard Charge Check CreditCardCharge CreditCardCredit
10
+ CreditMemo Deposit InventoryAdjustment Invoice ItemReceipt JournalEntry SalesReceipt VendorCredit}
11
+
12
+ # Generated Transaction types that don't support Mod Requests
13
+ TXN_NO_MOD_TYPES = %w{ARRefundCreditCard BillPaymentCreditCard Deposit InventoryAdjustment VehicleMileage VendorCredit }
14
+
15
+ # Generate Transaction subclasses
16
+ generate(TXN_TYPES, Transaction, {Modifiable => (TXN_TYPES - TXN_NO_MOD_TYPES), Voidable => TXN_VOIDABLE_TYPES})
17
+
18
+ end
@@ -0,0 +1,11 @@
1
+ module QBFC
2
+ module Voidable
3
+ def void
4
+ req = QBFC::Request.new(@sess, "TxnVoid")
5
+ req.txn_void_type = QBFC_CONST::const_get("Tvt#{qb_name}")
6
+ req.txn_id = id
7
+ req.submit
8
+ return true
9
+ end
10
+ end
11
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1 @@
1
+ --exclude "spec/*,gems/*"
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ gem 'rspec'
3
+ require 'spec'
4
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/qbfc')
5
+
6
+ Spec::Runner.configure do |config|
7
+
8
+ end
9
+
10
+ module QBFC
11
+ class Integration
12
+ FIXTURE_DIRNAME = File.dirname(__FILE__) + "\\fixtures"
13
+ FIXTURE_FILENAME = FIXTURE_DIRNAME + "\\test.qbw"
14
+ TMP_DIRNAME = File.dirname(__FILE__) + "\\tmp"
15
+
16
+ class << self
17
+ def reader
18
+ @@reader ||= new(true)
19
+ @@reader.open_sess
20
+ @@reader
21
+ end
22
+ end
23
+
24
+ def initialize(is_reader = false)
25
+ FileUtils.mkdir_p(TMP_DIRNAME)
26
+
27
+ @is_reader = is_reader
28
+ @@i ||= 0
29
+ @@i += 1
30
+ @dirname = TMP_DIRNAME + "\\fixture_#{@@i}"
31
+ FileUtils.rm_rf(@dirname)
32
+ FileUtils.mkdir_p(@dirname)
33
+
34
+ ['lgb', 'qbw', 'qbw.ND', 'qbw.TLG'].each do |ext|
35
+ FileUtils.cp FIXTURE_DIRNAME + "\\test.#{ext}", @dirname
36
+ end
37
+
38
+ open_sess
39
+ end
40
+
41
+ def filename
42
+ File.expand_path(@dirname + "\\test.qbw").gsub(/\//, "\\")
43
+ end
44
+
45
+ def open_sess
46
+ @sess = QBFC::Session.new(:filename => filename)
47
+ end
48
+
49
+ def session
50
+ @sess
51
+ end
52
+
53
+ def close
54
+ @sess.close
55
+ unless @is_reader
56
+ sleep(5)
57
+ FileUtils.rm_rf(@dirname)
58
+ end
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe QBFC::Base do
4
+
5
+ before(:each) do
6
+ @sess = mock(QBFC::Session)
7
+ @ole_wrapper = mock(QBFC::OLEWrapper)
8
+ @ole_methods = ["FullName", "ListID"]
9
+ @base = QBFC::Base.new(@sess, @ole_wrapper)
10
+ end
11
+
12
+ it "requires a QBFC:Session argument" do
13
+ lambda {QBFC::Base.new()}.should raise_error
14
+ lambda {QBFC::Base.new(@sess)}.should_not raise_error
15
+ end
16
+
17
+ it "initializes with an optional ole_object argument" do
18
+ lambda {QBFC::Base.new(@sess, @ole_wrapper)}.should_not raise_error
19
+ end
20
+
21
+ it "should wrap (only) a WIN32OLE object in an OLEWrapper" do
22
+ @ole_object = mock(WIN32OLE)
23
+ @ole_object.should_receive(:kind_of?).with(WIN32OLE).and_return(true)
24
+ QBFC::OLEWrapper.should_receive(:new).with(@ole_object).and_return(@ole_wrapper)
25
+
26
+ QBFC::Base.new(@sess, @ole_object)
27
+ end
28
+
29
+ it "should not wrap non-WIN32OLE objects" do
30
+ @ole_wrapper.should_receive(:kind_of?).with(WIN32OLE).and_return(false)
31
+ QBFC::OLEWrapper.should_not_receive(:new).with(@ole_object)
32
+
33
+ QBFC::Base.new(@sess, @ole_wrapper)
34
+ end
35
+
36
+ it "lists OLE methods for OLEWrapper object" do
37
+ @ole_wrapper.should_receive(:ole_methods).and_return(@ole_methods)
38
+ @base.ole_methods.should be(@ole_methods)
39
+ end
40
+
41
+ it "has a respond_to_ole? method" do
42
+ @ole_wrapper.should_receive(:respond_to_ole?).with("FullName").and_return(true)
43
+ @base.respond_to_ole?("FullName").should be_true
44
+
45
+ @ole_wrapper.should_receive(:respond_to_ole?).with("NoMethod").and_return(false)
46
+ @base.respond_to_ole?("NoMethod").should be_false
47
+ end
48
+
49
+ it "should pass unknown method calls to OLEWrapper#qbfc_method_missing" do
50
+ @ole_wrapper.should_receive(:qbfc_method_missing).with(@sess, :full_name=, "arg")
51
+ @base.full_name = "arg"
52
+ end
53
+
54
+ it "has a qb_name class method" do
55
+ QBFC::Base.qb_name.should == "Base"
56
+ end
57
+
58
+ it "aliases qb_name class method as an instance method" do
59
+ @base.qb_name.should == QBFC::Base.qb_name
60
+ end
61
+
62
+ it "should create_query" do
63
+ QBFC::Request.should_receive(:new).with(@sess, "BaseQuery")
64
+ QBFC::Base.__send__(:create_query, @sess)
65
+ end
66
+
67
+ it "should should respond to is_base_class? with false" do
68
+ QBFC::Base.is_base_class?.should be_false
69
+ end
70
+
71
+ describe ".parse_find_args" do
72
+ before(:each) do
73
+ @options = {:include_items => true, :owner_id => 0, :conditions => {}}
74
+ end
75
+
76
+ it "should return a Request object if given one" do
77
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
78
+ rq.should be(@request)
79
+
80
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
81
+ rq.should be(@request)
82
+ end
83
+
84
+ it "should return nil request if no Request given" do
85
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
86
+ rq.should be_nil
87
+
88
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
89
+ rq.should be_nil
90
+ end
91
+
92
+ it "should return options if given them" do
93
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request, @options)
94
+ opt.should be(@options)
95
+
96
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
97
+ opt.should be(@options)
98
+ end
99
+
100
+ it "should return an empty hash for options if not given them" do
101
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @request)
102
+ opt.should == {}
103
+
104
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args)
105
+ opt.should == {}
106
+ end
107
+
108
+ it "should return base_options if is_base_class?" do
109
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, {})
110
+ base_opt.should == {}
111
+ end
112
+
113
+ it "should make base_options and options separate objects" do
114
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
115
+ base_opt.should_not be(opt)
116
+ end
117
+
118
+ it "should return nil for base_options if isn't a base class" do
119
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, {})
120
+ base_opt.should be_nil
121
+ end
122
+
123
+ it "should delete :conditions from base_options" do
124
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
125
+ base_opt.should == {:include_items => true, :owner_id => 0}
126
+ end
127
+
128
+ it "should delete :owner_id from options if a base class" do
129
+ rq, opt, base_opt = QBFC::Test::BaseFind.__send__(:parse_find_args, @options)
130
+ opt.should == {:include_items => true, :conditions => {}}
131
+ end
132
+
133
+ it "should not delete :owner_id if not a base class" do
134
+ rq, opt, base_opt = QBFC::Test::ElementFind.__send__(:parse_find_args, @options)
135
+ opt.should == {:include_items => true, :owner_id => 0, :conditions => {}}
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,180 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ module QBFC::Test
4
+ class BaseFind < QBFC::Element
5
+ is_base_class
6
+
7
+ ID_NAME = "ListID"
8
+
9
+ def self.qb_name
10
+ "Entity"
11
+ end
12
+ end
13
+
14
+ class ElementFind < QBFC::Element
15
+ def self.qb_name
16
+ "Check"
17
+ end
18
+ end
19
+ end
20
+
21
+ # An Element is a Transaction or a List; that is any QuickBooks objects that can
22
+ # be created, edited (possibly), deleted and read. Contrast to a Report or Info
23
+ # which are read-only.
24
+ describe QBFC::Element do
25
+
26
+ before(:each) do
27
+ @sess = mock(QBFC::Session)
28
+ @ole_wrapper = mock(QBFC::OLEWrapper)
29
+ @element = mock(QBFC::Test::ElementFind)
30
+
31
+ # Request related mocks
32
+ @request = mock("QBFC::Request")
33
+ @request.stub!(:kind_of?).with(QBFC::Request).and_return(true)
34
+ @request.stub!(:kind_of?).with(Hash).and_return(false)
35
+ @response = mock("QBFC::Request#response")
36
+
37
+ # Filter mock
38
+ @filter = mock("QBFC::OLEWrapper#Filter")
39
+ @request.stub!(:filter).and_return(@filter)
40
+ @filter.stub!(:max_returned=)
41
+ @request.stub!(:filter_available?).and_return(true)
42
+ @request.stub!(:apply_options)
43
+ end
44
+
45
+ def setup_request
46
+ QBFC::Request.stub!(:new).and_return(@request)
47
+ @request.stub!(:response).and_return(@response)
48
+ @response.stub!(:GetAt).and_return(@ole_wrapper)
49
+ @response.stub!(:ole_methods).and_return(["GetAt"])
50
+ @response.stub!(:Count).and_return(2)
51
+
52
+ QBFC::Test::ElementFind.should_receive(:new).with(@sess, @ole_wrapper).at_least(:once).and_return(@element)
53
+ end
54
+
55
+ describe ".find" do
56
+
57
+ it "should find_by_unique_id if the 'what' argument is neither :all nor :first" do
58
+ QBFC::Test::ElementFind::should_receive(:find_by_unique_id).with(@sess, "123-456", {})
59
+ QBFC::Test::ElementFind::find(@sess, "123-456", {})
60
+ end
61
+
62
+ it "should return only first entry if 'what' argument is :first" do
63
+ setup_request
64
+ QBFC::Test::ElementFind::find(@sess, :first).should be(@element)
65
+ end
66
+
67
+ it "should set request#max_returned to 1 if :first" do
68
+ setup_request
69
+ @request.should_receive(:filter).and_return(@filter)
70
+ @request.stub!(:filter_available?).and_return(true)
71
+ @filter.should_receive(:max_returned=).with(1)
72
+ QBFC::Test::ElementFind::find(@sess, :first)
73
+ end
74
+
75
+ it "should not set request#max_returned if not request.filter_available?" do
76
+ setup_request
77
+ @request.stub!(:filter_available?).and_return(false)
78
+ @request.should_not_receive(:filter)
79
+ QBFC::Test::ElementFind::find(@sess, :first)
80
+ end
81
+
82
+ it "should return an array if 'what' argument is :all" do
83
+ setup_request
84
+ @filter.should_not_receive(:max_returned=)
85
+ QBFC::Test::ElementFind::find(@sess, :all).should == [@element, @element]
86
+ end
87
+
88
+ it "should return nil if no elements are found unless finding :first" do
89
+ QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
90
+ @request.should_receive(:response).and_return(nil)
91
+ QBFC::Test::ElementFind::find(@sess, :first).should be_nil
92
+ end
93
+
94
+ it "should return an empty array if no elements are found when finding :all" do
95
+ QBFC::Request.should_receive(:new).with(@sess, 'CheckQuery').and_return(@request)
96
+ @request.should_receive(:response).and_return(nil)
97
+ QBFC::Test::ElementFind::find(@sess, :first).should be_nil
98
+ end
99
+
100
+ it "can accept a Request object"
101
+ it "generates a Request object if not given one"
102
+ it "accepts conditions"
103
+
104
+ it "applies options to request" do
105
+ setup_request
106
+ @request.should_receive(:apply_options).with({:owner_id => 0})
107
+ QBFC::Test::ElementFind::find(@sess, :first, :owner_id => 0)
108
+ end
109
+
110
+ it "passes additional arguments to Request"
111
+
112
+ it "should get request#response" do
113
+ setup_request
114
+ @request.should_receive(:response).and_return(@response)
115
+ QBFC::Test::ElementFind::find(@sess, :first)
116
+ end
117
+
118
+ it "should call base_class_find for base classes" do
119
+ QBFC::Request.stub!(:new).and_return(@request)
120
+ QBFC::Test::BaseFind.should_receive(:base_class_find).with(@sess, :first, @request, {}).and_return(@element)
121
+ QBFC::Test::BaseFind::find(@sess, :first, {}).should be(@element)
122
+ end
123
+
124
+ it "should not call base_class_find for non-base classes" do
125
+ setup_request
126
+ QBFC::Test::ElementFind.should_not_receive(:base_class_find)
127
+ QBFC::Test::ElementFind::find(@sess, :first, {})
128
+ end
129
+ end
130
+
131
+ describe ".base_class_find" do
132
+ before(:each) do
133
+ @request.stub!(:IncludeRetElementList).and_return(@include_list)
134
+ @include_list.stub!(:Add).with("ListID")
135
+ @request.stub!(:response).and_return(@response)
136
+ QBFC::Request.stub!(:new).and_return(@request)
137
+
138
+ @element = mock(QBFC::Test::ElementFind)
139
+ @base_element = mock(QBFC::Test::BaseFind)
140
+ @customer_ret = mock("CustomerRet")
141
+ @base_element.stub!(:ole_methods).and_return(["CustomerRet"])
142
+ @base_element.stub!(:CustomerRet).and_return(@customer_ret)
143
+ @customer_ret.stub!(:ListID).and_return("123-456")
144
+ QBFC::Customer.stub!(:find_by_id).and_return(@element)
145
+
146
+ @response.stub!(:GetAt).and_return(@base_element)
147
+ @response.stub!(:Count).and_return(2)
148
+ end
149
+
150
+ it "should request only ListID" do
151
+ @include_list.should_receive(:Add).with("ListID")
152
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {})
153
+ end
154
+
155
+ it "should send class ChildList::find_by_id with ListID and find options for each" do
156
+ @base_element.should_receive(:CustomerRet).at_least(:once).and_return(@customer_ret)
157
+ @customer_ret.should_receive(:ListID).at_least(:once).and_return("789-012")
158
+ QBFC::Customer.should_receive(:find_by_id).at_least(:once).with(@sess, "789-012", {}).and_return(@element)
159
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
160
+ end
161
+
162
+ it "should return nil if no records and not :all" do
163
+ @request.should_receive(:response).and_return(nil)
164
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be_nil
165
+ end
166
+
167
+ it "should return nil if no records and not :all" do
168
+ @request.should_receive(:response).and_return(nil)
169
+ QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == []
170
+ end
171
+
172
+ it "should return single record unless :all" do
173
+ QBFC::Test::BaseFind.find(@sess, :first, @request, {}).should be(@element)
174
+ end
175
+
176
+ it "should return Array if :all" do
177
+ QBFC::Test::BaseFind.find(@sess, :all, @request, {}).should == [@element, @element]
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ module QBFC::Test
4
+ class BaseKlass < QBFC::Element
5
+ is_base_class
6
+ end
7
+
8
+ class NormalKlass < QBFC::Element
9
+ end
10
+ end
11
+
12
+ # An Element is a Transaction or a List; that is any QuickBooks objects that can
13
+ # be created, edited (possibly), deleted and read. Contrast to a Report or Info
14
+ # which are read-only.
15
+ describe QBFC::Element do
16
+
17
+ before(:each) do
18
+ @sess = mock(QBFC::Session)
19
+ @ole_wrapper = mock(QBFC::OLEWrapper)
20
+ @ole_object = mock(WIN32OLE)
21
+ @ole_methods = ["FullName", "DataExtRetList"]
22
+ @element = QBFC::Test::NormalKlass.new(@sess, @ole_wrapper)
23
+ end
24
+
25
+ describe "#initialize" do
26
+ it "should set up add request if ole_object is nil" do
27
+ @request = mock(QBFC::Request)
28
+ @request.should_receive(:ole_object).and_return(@ole_object)
29
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
30
+ QBFC::Test::NormalKlass.new(@sess)
31
+ end
32
+
33
+ it "should assign the Add request as the @setter" do
34
+ @request = mock(QBFC::Request)
35
+ @request.stub!(:ole_object).and_return(@ole_object)
36
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
37
+ QBFC::Test::NormalKlass.new(@sess).
38
+ instance_variable_get(:@setter).should == @request
39
+ end
40
+
41
+ it "should error if class is_base_class?" do
42
+ lambda {
43
+ QBFC::Test::BaseKlass.new(@sess)
44
+ }.should raise_error(QBFC::BaseClassNewError)
45
+
46
+ lambda {
47
+ QBFC::Test::BaseKlass.new(@sess, @ole_wrapper)
48
+ }.should raise_error(QBFC::BaseClassNewError)
49
+ end
50
+ end
51
+
52
+ describe "#new_record?" do
53
+ before(:each) do
54
+ @request = mock(QBFC::Request)
55
+ @request.stub!(:ole_object).and_return(@ole_object)
56
+ QBFC::Request.stub!(:new).with(@sess, "NormalKlassAdd").and_return(@request)
57
+ end
58
+
59
+ it "should return true if ole_object is an AddRq" do
60
+ QBFC::Test::NormalKlass.new(@sess).new_record?.should be_true
61
+ end
62
+
63
+ it "should return false if ole_object is from a QueryRq" do
64
+ @element.new_record?.should be_false
65
+ end
66
+ end
67
+
68
+ describe ".is_base_class? (and is_base_class macro)" do
69
+ it "should return true if Class is_base_class has been called" do
70
+ QBFC::Test::BaseKlass.is_base_class?.should be_true
71
+ QBFC::Test::NormalKlass.is_base_class?.should be_false
72
+ end
73
+ end
74
+
75
+ describe "#custom" do
76
+ before(:each) do
77
+ @data_ext = mock("QBFC::OLEWrapper#DataExtRet")
78
+ @data_ext_list = [@data_ext, @data_ext]
79
+ @ole_wrapper.stub!(:DataExtRetList).and_return(@data_ext_list)
80
+ @ole_wrapper.stub!(:data_ext).and_return(@data_ext_list)
81
+ end
82
+
83
+ it "should get custom fields" do
84
+ @data_ext.should_receive(:data_ext_name).and_return("Custom Field")
85
+ @data_ext.should_receive(:owner_id).and_return(0)
86
+ @data_ext.should_receive(:data_ext_value).and_return("Hello")
87
+
88
+ @element.custom("Custom Field").should == "Hello"
89
+ end
90
+
91
+ it "should return nil if there are no custom fields" do
92
+ @ole_wrapper.should_receive(:DataExtRetList).and_return(nil)
93
+
94
+ @element.custom("Custom Field").should be_nil
95
+ end
96
+
97
+ it "should return nil if the custom field is not found" do
98
+ @data_ext.should_receive(:data_ext_name).twice.and_return("Custom Field")
99
+
100
+ @element.custom("No Field").should be_nil
101
+ end
102
+ end
103
+
104
+ describe "#save" do
105
+ it "should submit the setter object" do
106
+ @request = mock(QBFC::Request)
107
+ @request.stub!(:ole_object).and_return(@ole_object)
108
+ QBFC::Request.should_receive(:new).with(@sess, "NormalKlassAdd").and_return(@request)
109
+ @request.should_receive(:submit)
110
+
111
+ QBFC::Test::NormalKlass.new(@sess).save
112
+ end
113
+
114
+ it "should raise an error if there is no setter object" do
115
+ lambda { @element.save}.should raise_error(QBFC::NotSavableError)
116
+ end
117
+ end
118
+ end