qbfc 0.1.0-x86-mswin32-60

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