xmlconv2 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/LICENCE.txt +339 -0
- data/Manifest.txt +107 -0
- data/README.txt +25 -0
- data/Rakefile +28 -0
- data/bin/admin +65 -0
- data/bin/xmlconvd +19 -0
- data/data/grammar/i2.grammar +73 -0
- data/src/conversion/bdd_geh.rb +281 -0
- data/src/conversion/bdd_i2.rb +102 -0
- data/src/conversion/bdd_xml.rb +242 -0
- data/src/conversion/geh_bdd.rb +165 -0
- data/src/conversion/i2_bdd.rb +271 -0
- data/src/conversion/xml_bdd.rb +125 -0
- data/src/custom/lookandfeel.rb +47 -0
- data/src/i2/address.rb +33 -0
- data/src/i2/date.rb +37 -0
- data/src/i2/document.rb +26 -0
- data/src/i2/header.rb +24 -0
- data/src/i2/order.rb +44 -0
- data/src/i2/parser.rb +25 -0
- data/src/i2/position.rb +37 -0
- data/src/i2/record.rb +11 -0
- data/src/model/address.rb +20 -0
- data/src/model/agreement.rb +10 -0
- data/src/model/bdd.rb +26 -0
- data/src/model/bsr.rb +16 -0
- data/src/model/delivery.rb +15 -0
- data/src/model/delivery_item.rb +18 -0
- data/src/model/freetext_container.rb +26 -0
- data/src/model/id_container.rb +15 -0
- data/src/model/invoice.rb +18 -0
- data/src/model/invoice_item.rb +11 -0
- data/src/model/item.rb +19 -0
- data/src/model/item_container.rb +15 -0
- data/src/model/name.rb +27 -0
- data/src/model/part_info.rb +10 -0
- data/src/model/part_info_container.rb +15 -0
- data/src/model/party.rb +23 -0
- data/src/model/party_container.rb +20 -0
- data/src/model/price.rb +10 -0
- data/src/model/price_container.rb +18 -0
- data/src/model/transaction.rb +28 -0
- data/src/state/global.rb +28 -0
- data/src/state/global_predefine.rb +11 -0
- data/src/state/login.rb +38 -0
- data/src/state/transaction.rb +13 -0
- data/src/state/transactions.rb +130 -0
- data/src/util/application.rb +143 -0
- data/src/util/destination.rb +130 -0
- data/src/util/invoicer.rb +72 -0
- data/src/util/known_user.rb +16 -0
- data/src/util/polling_manager.rb +78 -0
- data/src/util/session.rb +23 -0
- data/src/util/transaction.rb +105 -0
- data/src/util/validator.rb +20 -0
- data/src/view/foot.rb +27 -0
- data/src/view/head.rb +13 -0
- data/src/view/login.rb +36 -0
- data/src/view/navigation.rb +30 -0
- data/src/view/navigationlink.rb +21 -0
- data/src/view/pager.rb +73 -0
- data/src/view/preformatted.rb +39 -0
- data/src/view/template.rb +17 -0
- data/src/view/transaction.rb +42 -0
- data/src/view/transactions.rb +90 -0
- data/test/mock.rb +149 -0
- data/test/suite.rb +16 -0
- data/test/test_conversion/bdd_geh.rb +533 -0
- data/test/test_conversion/bdd_i2.rb +314 -0
- data/test/test_conversion/bdd_xml.rb +556 -0
- data/test/test_conversion/geh_bdd.rb +372 -0
- data/test/test_conversion/i2_bdd.rb +804 -0
- data/test/test_conversion/xml_bdd.rb +203 -0
- data/test/test_i2/address.rb +88 -0
- data/test/test_i2/date.rb +49 -0
- data/test/test_i2/document.rb +62 -0
- data/test/test_i2/header.rb +39 -0
- data/test/test_i2/order.rb +94 -0
- data/test/test_i2/parser.rb +309 -0
- data/test/test_i2/position.rb +65 -0
- data/test/test_integration/geh_i2.rb +312 -0
- data/test/test_integration/i2_geh.rb +449 -0
- data/test/test_integration/i2_xml.rb +162 -0
- data/test/test_integration/xml_i2.rb +254 -0
- data/test/test_model/address.rb +35 -0
- data/test/test_model/agreement.rb +22 -0
- data/test/test_model/bdd.rb +55 -0
- data/test/test_model/bsr.rb +38 -0
- data/test/test_model/delivery.rb +79 -0
- data/test/test_model/delivery_item.rb +52 -0
- data/test/test_model/freetext_container.rb +45 -0
- data/test/test_model/invoice.rb +65 -0
- data/test/test_model/invoice_item.rb +41 -0
- data/test/test_model/name.rb +57 -0
- data/test/test_model/part_info.rb +24 -0
- data/test/test_model/party.rb +96 -0
- data/test/test_model/price.rb +24 -0
- data/test/test_util/application.rb +168 -0
- data/test/test_util/destination.rb +197 -0
- data/test/test_util/invoicer.rb +36 -0
- data/test/test_util/polling_manager.rb +111 -0
- data/test/test_util/transaction.rb +129 -0
- data/user-stories/UserStories_XmlConv2.txt +381 -0
- data/user-stories/doku/ABB.incoming.HTTP.invoice.xml +315 -0
- data/user-stories/doku/ABB.received.xml +259 -0
- data/user-stories/doku/BO_OrderProcessing.sxw +0 -0
- metadata +195 -0
data/src/view/foot.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Foot -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/composite'
|
5
|
+
require 'view/navigation'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
module XmlConv
|
9
|
+
module View
|
10
|
+
class Foot < HtmlGrid::Composite
|
11
|
+
COMPONENTS = {
|
12
|
+
[0,0] => :copyright,
|
13
|
+
[1,0] => Navigation,
|
14
|
+
}
|
15
|
+
CSS_CLASS = 'foot composite'
|
16
|
+
LEGACY_INTERFACE = false
|
17
|
+
def copyright(model)
|
18
|
+
link = HtmlGrid::Link.new(:copyright, model, @session, self)
|
19
|
+
link.href = 'http://www.ywesee.com'
|
20
|
+
link.value = @lookandfeel.lookup(:copyright, Date.today.strftime('%Y'))
|
21
|
+
link.css_class = 'foot'
|
22
|
+
link.target = '_blank'
|
23
|
+
link
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/src/view/head.rb
ADDED
data/src/view/login.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Login -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'view/template'
|
5
|
+
require 'htmlgrid/form'
|
6
|
+
require 'htmlgrid/pass'
|
7
|
+
|
8
|
+
module XmlConv
|
9
|
+
module View
|
10
|
+
class LoginForm < HtmlGrid::Form
|
11
|
+
COMPONENTS = {
|
12
|
+
[0,0] => :pass,
|
13
|
+
[1,1] => :submit,
|
14
|
+
}
|
15
|
+
CSS_CLASS = 'component'
|
16
|
+
EVENT = :login
|
17
|
+
LABELS = true
|
18
|
+
SYMBOL_MAP = {
|
19
|
+
:pass => HtmlGrid::Pass,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
class LoginComposite < HtmlGrid::Composite
|
23
|
+
COMPONENTS = {
|
24
|
+
[0,0] => "login_welcome",
|
25
|
+
[0,1] => LoginForm,
|
26
|
+
}
|
27
|
+
CSS_CLASS = 'composite'
|
28
|
+
CSS_MAP = {
|
29
|
+
[0,0] => 'th',
|
30
|
+
}
|
31
|
+
end
|
32
|
+
class Login < Template
|
33
|
+
CONTENT = LoginComposite
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Navigation -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/composite'
|
5
|
+
require 'view/navigationlink'
|
6
|
+
|
7
|
+
module XmlConv
|
8
|
+
module View
|
9
|
+
class Navigation < HtmlGrid::Composite
|
10
|
+
COMPONENTS = {}
|
11
|
+
CSS_CLASS = "navigation"
|
12
|
+
#HTML_ATTRIBUTES = {"align"=>"right"}
|
13
|
+
SYMBOL_MAP = {
|
14
|
+
:navigation_divider => HtmlGrid::Text,
|
15
|
+
}
|
16
|
+
def init
|
17
|
+
build_navigation()
|
18
|
+
super
|
19
|
+
end
|
20
|
+
def build_navigation
|
21
|
+
@lookandfeel.navigation.each_with_index { |state, idx|
|
22
|
+
evt = state.is_a?(Symbol) ? state : state.direct_event
|
23
|
+
symbol_map.store(evt, NavigationLink)
|
24
|
+
components.store([idx*2,0], evt)
|
25
|
+
components.store([idx*2-1,0], :navigation_divider) if(idx > 0)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::NavigationLink -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/link'
|
5
|
+
|
6
|
+
module XmlConv
|
7
|
+
module View
|
8
|
+
class NavigationLink < HtmlGrid::Link
|
9
|
+
#CSS_CLASS = "navigation"
|
10
|
+
def init
|
11
|
+
super
|
12
|
+
unless(@lookandfeel.direct_event == @name)
|
13
|
+
@attributes.store("href", @lookandfeel.event_url(@name))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
data/src/view/pager.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Pager -- xmlconv2 -- 01.07.2004 -- ywesee@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/link'
|
5
|
+
require 'htmlgrid/list'
|
6
|
+
|
7
|
+
module XmlConv
|
8
|
+
module View
|
9
|
+
class Pager < HtmlGrid::List
|
10
|
+
BACKGROUND_SUFFIX = ''
|
11
|
+
COMPONENTS = {
|
12
|
+
[0,0] => :number_link,
|
13
|
+
}
|
14
|
+
CSS_CLASS = 'pager'
|
15
|
+
CSS_HEAD_MAP = {
|
16
|
+
#[0,0] => 'pager-head',
|
17
|
+
}
|
18
|
+
CSS_MAP = {
|
19
|
+
#[0,0] => 'pager',
|
20
|
+
}
|
21
|
+
LEGACY_INTERFACE = false
|
22
|
+
OFFSET_STEP = [1,0]
|
23
|
+
SORT_DEFAULT = :to_i
|
24
|
+
SORT_HEADER = false
|
25
|
+
def init
|
26
|
+
@page = @container.model
|
27
|
+
super
|
28
|
+
end
|
29
|
+
def compose_header(offset)
|
30
|
+
@grid.add(page_number(@model), *offset)
|
31
|
+
@grid.add_style('head', *offset)
|
32
|
+
offset = resolve_offset(offset, self::class::OFFSET_STEP)
|
33
|
+
if(@page != @model.first)
|
34
|
+
link = page_link(@page.previous)
|
35
|
+
link.value = @lookandfeel.lookup(:page_back)
|
36
|
+
@grid.add(link, *offset)
|
37
|
+
end
|
38
|
+
#@grid.add_attribute('class', 'pager', *offset)
|
39
|
+
resolve_offset(offset, self::class::OFFSET_STEP)
|
40
|
+
end
|
41
|
+
def compose_footer(offset)
|
42
|
+
if(@page != @model.last)
|
43
|
+
link = page_link(@page.next)
|
44
|
+
link.value = @lookandfeel.lookup(:page_fwd)
|
45
|
+
@grid.add(link, *offset)
|
46
|
+
else
|
47
|
+
@grid.add(nil, *offset)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
private
|
51
|
+
def number_link(model)
|
52
|
+
page_link(model)
|
53
|
+
end
|
54
|
+
def page_link(page)
|
55
|
+
if(page != @page)
|
56
|
+
link = HtmlGrid::Link.new(:self, page, @session, self)
|
57
|
+
link.value = page.to_s
|
58
|
+
#link.set_attribute("class", "pager")
|
59
|
+
values = {
|
60
|
+
:page => page.to_i.to_s,
|
61
|
+
}
|
62
|
+
link.href = @lookandfeel.event_url(:self, values)
|
63
|
+
link
|
64
|
+
else
|
65
|
+
page.to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
def page_number(model)
|
69
|
+
@lookandfeel.lookup(:page_number, @page, @page.total)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Preformatted -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/value'
|
5
|
+
|
6
|
+
module XmlConv
|
7
|
+
module View
|
8
|
+
BREAK_WIDTH = 65
|
9
|
+
class Preformatted < HtmlGrid::Value
|
10
|
+
def init
|
11
|
+
super
|
12
|
+
if(@value)
|
13
|
+
raw = @value.gsub(/>\s+</, "><").gsub(/\r\n?/, "\n")
|
14
|
+
pretty = CGI.pretty(raw)
|
15
|
+
wrap = ''
|
16
|
+
pretty.each_line { |line|
|
17
|
+
if(line.length < BREAK_WIDTH)
|
18
|
+
wrap << line
|
19
|
+
else
|
20
|
+
parts = line.split('" "')
|
21
|
+
wrapline = parts.shift
|
22
|
+
while(part = parts.shift)
|
23
|
+
if((wrapline.length + part.length) >= BREAK_WIDTH)
|
24
|
+
wrap << wrapline
|
25
|
+
wrap << "\"\n"
|
26
|
+
wrapline = " \"" << part
|
27
|
+
else
|
28
|
+
wrapline << '" "' << part
|
29
|
+
end
|
30
|
+
end
|
31
|
+
wrap << wrapline
|
32
|
+
end
|
33
|
+
}
|
34
|
+
@value = CGI.escapeHTML(wrap)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Template -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/divtemplate'
|
5
|
+
require 'view/foot'
|
6
|
+
|
7
|
+
module XmlConv
|
8
|
+
module View
|
9
|
+
class Template < HtmlGrid::DivTemplate
|
10
|
+
COMPONENTS = {
|
11
|
+
[0,0] => :content,
|
12
|
+
[0,1] => :foot,
|
13
|
+
}
|
14
|
+
FOOT = Foot
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Transaction -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/value'
|
5
|
+
require 'view/template'
|
6
|
+
require 'view/preformatted'
|
7
|
+
|
8
|
+
module XmlConv
|
9
|
+
module View
|
10
|
+
class TransactionComposite < HtmlGrid::Composite
|
11
|
+
COMPONENTS = {
|
12
|
+
[0,0] => 'th_input',
|
13
|
+
[1,0] => 'th_output',
|
14
|
+
[0,1] => :input,
|
15
|
+
[1,1] => :output,
|
16
|
+
[0,2] => 'th_error',
|
17
|
+
[0,3] => :error_string,
|
18
|
+
}
|
19
|
+
CSS_CLASS = 'composite'
|
20
|
+
CSS_MAP = {
|
21
|
+
[0,0,2] => 'th',
|
22
|
+
[0,1,2] => 'helfti preformatted',
|
23
|
+
[0,2] => 'th',
|
24
|
+
[0,3] => 'list preformatted bg',
|
25
|
+
}
|
26
|
+
COLSPAN_MAP = {
|
27
|
+
[0,2] => 2,
|
28
|
+
[0,3] => 2,
|
29
|
+
}
|
30
|
+
DEFAULT_CLASS = View::Preformatted
|
31
|
+
LEGACY_INTERFACE = false
|
32
|
+
def error_string(model)
|
33
|
+
if(err = model.error)
|
34
|
+
[err.class, err.message, err.backtrace].join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
class Transaction < Template
|
39
|
+
CONTENT = TransactionComposite
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# View::Transactions -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'htmlgrid/list'
|
5
|
+
require 'htmlgrid/value'
|
6
|
+
require 'view/template'
|
7
|
+
require 'view/pager'
|
8
|
+
|
9
|
+
module XmlConv
|
10
|
+
module View
|
11
|
+
class TransactionsList < HtmlGrid::List
|
12
|
+
BACKGROUND_SUFFIX = ' bg'
|
13
|
+
COMPONENTS = {
|
14
|
+
[0,0] => :transaction_id,
|
15
|
+
[1,0] => :origin,
|
16
|
+
[2,0] => :commit_time,
|
17
|
+
[3,0] => :uri_comparable,
|
18
|
+
[4,0] => :status_comparable,
|
19
|
+
}
|
20
|
+
CSS_CLASS = 'composite'
|
21
|
+
CSS_HEAD_MAP = {
|
22
|
+
[0,0] => 'right',
|
23
|
+
}
|
24
|
+
CSS_MAP = {
|
25
|
+
[0,0] => 'list right',
|
26
|
+
[1,0,4] => 'list',
|
27
|
+
}
|
28
|
+
DEFAULT_CLASS = HtmlGrid::Value
|
29
|
+
LEGACY_INTERFACE = false
|
30
|
+
SORT_DEFAULT = nil #:commit_time
|
31
|
+
SORT_REVERSE = false
|
32
|
+
def commit_time(model)
|
33
|
+
time_format(model.commit_time || model.start_time)
|
34
|
+
end
|
35
|
+
def origin(model)
|
36
|
+
uri_fmt(model.origin)
|
37
|
+
end
|
38
|
+
def uri_comparable(model)
|
39
|
+
uri_fmt(model.uri)
|
40
|
+
end
|
41
|
+
def uri_fmt(uri)
|
42
|
+
uri = uri.to_s
|
43
|
+
if((i1 = uri.index(/([^\/])\/[^\/]/, 1)) \
|
44
|
+
&& (i2 = uri.rindex(/(\/[^\/]+){3}/)) \
|
45
|
+
&& (i2 > i1))
|
46
|
+
uri[0..(i1.next)] << '...' << uri[i2..-1]
|
47
|
+
else
|
48
|
+
uri
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def status_comparable(model)
|
52
|
+
model.update_status
|
53
|
+
status = model.status
|
54
|
+
@lookandfeel.lookup("status_#{status}") or status.to_s
|
55
|
+
end
|
56
|
+
def time_format(a_time)
|
57
|
+
if(a_time.respond_to?(:strftime))
|
58
|
+
a_time.strftime("%d.%m.%Y %H:%M:%S")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
def transaction_id(model)
|
62
|
+
link = HtmlGrid::Link.new(:transaction_id, model, @session, self)
|
63
|
+
args = {
|
64
|
+
'transaction_id' => model.transaction_id,
|
65
|
+
}
|
66
|
+
link.href = @lookandfeel.event_url(:transaction, args)
|
67
|
+
link.value = model.transaction_id
|
68
|
+
link
|
69
|
+
end
|
70
|
+
end
|
71
|
+
class TransactionsComposite < HtmlGrid::Composite
|
72
|
+
COMPONENTS = {
|
73
|
+
[0,0] => :pager,
|
74
|
+
[0,1] => :transactions,
|
75
|
+
}
|
76
|
+
CSS_CLASS = 'composite'
|
77
|
+
LEGACY_INTERFACE = false
|
78
|
+
def pager(model)
|
79
|
+
Pager.new(model.pages, @session, self)
|
80
|
+
end
|
81
|
+
def transactions(page)
|
82
|
+
TransactionsList.new(page.model, @session, self)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
class Transactions < Template
|
86
|
+
CONTENT = TransactionsComposite
|
87
|
+
#CONTENT = TransactionsList
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/test/mock.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Ruby/Mock version 1.0
|
2
|
+
#
|
3
|
+
# A class for conveniently building mock objects in RUnit test cases.
|
4
|
+
# Copyright (c) 2001 Nat Pryce, all rights reserved
|
5
|
+
#
|
6
|
+
# This program is free software; you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation; either version 2 of the License.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
18
|
+
|
19
|
+
require 'runit/error'
|
20
|
+
|
21
|
+
|
22
|
+
class Mock
|
23
|
+
# Creates a new, named mock object. The name is reported in exceptions
|
24
|
+
# thrown by the mock object when method invocations are incorrect.
|
25
|
+
#
|
26
|
+
def initialize( mock_name = self.to_s )
|
27
|
+
@mock_calls = []
|
28
|
+
@next_call = 0
|
29
|
+
@name = mock_name
|
30
|
+
end
|
31
|
+
|
32
|
+
# Mock the next method call to be made to this mock object.
|
33
|
+
#
|
34
|
+
# A mock method is defined by the method name (a symbol) and a block
|
35
|
+
# that defines the arity of the method and the mocked behaviour for
|
36
|
+
# this call. The mocked behaviour should assert preconditions and
|
37
|
+
# return a value. Mocked behaviour should rarely be any more complex
|
38
|
+
# than that. If it is, that's probably an indication that the tests
|
39
|
+
# need some restructuring or that the tested code needs refactoring.
|
40
|
+
#
|
41
|
+
# If no block is given and preconditions have been defined for the named
|
42
|
+
# method, a block is created for the mocked methodthat has the same arity
|
43
|
+
# as the precondition and returns self.
|
44
|
+
#
|
45
|
+
def __next( name, &test )
|
46
|
+
if test == nil
|
47
|
+
if respond_to?( Mock.__pre(name) )
|
48
|
+
test = proc { |*args| self }
|
49
|
+
else
|
50
|
+
raise "no block given for mocked method #{name}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@mock_calls.push( [name,test] )
|
54
|
+
end
|
55
|
+
|
56
|
+
# Call this at the end of a test to ensure that all scheduled calls
|
57
|
+
# have been made to the mock
|
58
|
+
#
|
59
|
+
def __verify
|
60
|
+
if @next_call != @mock_calls.length
|
61
|
+
raise RUNIT::AssertionFailedError,
|
62
|
+
"not all expected method calls were made to #{@name}",
|
63
|
+
caller
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
# Dispatches aribtrary method calls to the next mocked behaviour
|
70
|
+
#
|
71
|
+
def method_missing( name, *args, &block )
|
72
|
+
__mock_call( name, args, (block_given? ? block : nil) )
|
73
|
+
end
|
74
|
+
|
75
|
+
# Implements a method call using the next mocked behaviour and asserts
|
76
|
+
# that the expected method is called with the expected number of
|
77
|
+
# arguments.
|
78
|
+
#
|
79
|
+
def __mock_call( name, args, block )
|
80
|
+
if @next_call >= @mock_calls.length
|
81
|
+
raise RUNIT::AssertionFailedError,
|
82
|
+
"unexpected call to #{name} method of #{@name}",
|
83
|
+
caller(2)
|
84
|
+
end
|
85
|
+
|
86
|
+
expected_name,body = @mock_calls[@next_call]
|
87
|
+
@next_call += 1
|
88
|
+
|
89
|
+
if name != expected_name
|
90
|
+
raise RUNIT::AssertionFailedError,
|
91
|
+
"wrong method called on #{@name}; " +
|
92
|
+
"expected #{expected_name}, was #{name}",
|
93
|
+
caller(2)
|
94
|
+
end
|
95
|
+
|
96
|
+
args_length = args.length + (block ? 1 : 0)
|
97
|
+
|
98
|
+
if body.arity < 0
|
99
|
+
if (body.arity+1).abs > args_length
|
100
|
+
raise RUNIT::AssertionFailedError,
|
101
|
+
"too few arguments to #{name} method of #{@name}; " +
|
102
|
+
"require #{(body.arity+1).abs}, got #{args.length}",
|
103
|
+
caller(2)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
if body.arity != args_length
|
107
|
+
raise RUNIT::AssertionFailedError,
|
108
|
+
"wrong number of arguments to " +
|
109
|
+
"#{name} method of #{@name}; " +
|
110
|
+
"require #{body.arity}, got #{args.length}",
|
111
|
+
caller(2)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
if respond_to? Mock.__pre(name)
|
116
|
+
if block
|
117
|
+
precondition_ok = __send__( Mock.__pre(name), *args, &block )
|
118
|
+
else
|
119
|
+
precondition_ok = __send__( Mock.__pre(name), *args )
|
120
|
+
end
|
121
|
+
|
122
|
+
if not precondition_ok
|
123
|
+
raise RUNIT::AssertionFailedError,
|
124
|
+
"precondition of #{name} method violated",
|
125
|
+
caller(2)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if block
|
130
|
+
instance_eval { body.call( block, *args ) }
|
131
|
+
else
|
132
|
+
instance_eval { body.call( *args ) }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# The name of a precondition for a method
|
137
|
+
def Mock.__pre( method )
|
138
|
+
"__pre_#{method.to_i}".intern
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
def Mock.method_added( name )
|
143
|
+
unless(/^__pre_/.match(name.to_s))
|
144
|
+
pre = self.__pre(name)
|
145
|
+
alias_method( pre, name )
|
146
|
+
undef_method(name)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|