Merge remote-tracking branch 'soapopera/master'
This commit is contained in:
commit
00d3ddfe87
|
@ -1 +0,0 @@
|
|||
Subproject commit 21132f02889ef82e368144dbf8892d321d27661c
|
|
@ -0,0 +1,225 @@
|
|||
Eval [
|
||||
'From Pharo-1.1-11411 of 17 July 2010 [Latest update: #11411] on 19 February 2011 at 9:09:05 pm'
|
||||
]
|
||||
|
||||
ReadWriteStream subclass: MIMERWStream [
|
||||
| readLimit |
|
||||
|
||||
nextPut: aInt [
|
||||
| res |
|
||||
res := super nextPut: aInt.
|
||||
readLimit := self readLimit max: self position.
|
||||
^ res
|
||||
]
|
||||
|
||||
contents [
|
||||
^ collection copyFrom: 1 to: self readLimit.
|
||||
]
|
||||
|
||||
readLimit [
|
||||
^ readLimit ifNil: [readLimit := 0].
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
Object subclass: MimeConverter [
|
||||
| dataStream mimeStream |
|
||||
|
||||
<category: 'Network-MIME'>
|
||||
|
||||
dataStream [
|
||||
<category: 'accessing'>
|
||||
^dataStream
|
||||
]
|
||||
|
||||
dataStream: anObject [
|
||||
<category: 'accessing'>
|
||||
dataStream := anObject
|
||||
]
|
||||
|
||||
mimeStream [
|
||||
<category: 'accessing'>
|
||||
^mimeStream
|
||||
]
|
||||
|
||||
mimeStream: anObject [
|
||||
<category: 'accessing'>
|
||||
mimeStream := anObject
|
||||
]
|
||||
|
||||
mimeDecode [
|
||||
"Do conversion reading from mimeStream writing to dataStream"
|
||||
|
||||
<category: 'conversion'>
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
mimeEncode [
|
||||
"Do conversion reading from dataStream writing to mimeStream"
|
||||
|
||||
<category: 'conversion'>
|
||||
self subclassResponsibility
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
MimeConverter subclass: Base64MimeConverter [
|
||||
| data |
|
||||
|
||||
<comment: 'This class encodes and decodes data in Base64 format. This is MIME encoding. We translate a whole stream at once, taking a Stream as input and giving one as output. Returns a whole stream for the caller to use.
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Outbound: bytes are broken into 6 bit chunks, and the 0-63 value is converted to a character. 3 data bytes go into 4 characters.
Inbound: Characters are translated in to 0-63 values and shifted into 8 bit bytes.
(See: N. Borenstein, Bellcore, N. Freed, Innosoft, Network Working Group, Request for Comments: RFC 1521, September 1993, MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies. Sec 6.2)
By Ted Kaehler, based on Tim Olson''s Base64Filter.'>
|
||||
<category: 'Network-MIME'>
|
||||
|
||||
FromCharTable := nil.
|
||||
ToCharTable := nil.
|
||||
|
||||
Base64MimeConverter class >> initialize [
|
||||
FromCharTable := Array new: 256. "nils"
|
||||
ToCharTable := Array new: 64.
|
||||
($A asciiValue to: $Z asciiValue) doWithIndex:
|
||||
[:val :ind |
|
||||
FromCharTable at: val + 1 put: ind - 1.
|
||||
ToCharTable at: ind put: val asCharacter].
|
||||
($a asciiValue to: $z asciiValue) doWithIndex:
|
||||
[:val :ind |
|
||||
FromCharTable at: val + 1 put: ind + 25.
|
||||
ToCharTable at: ind + 26 put: val asCharacter].
|
||||
($0 asciiValue to: $9 asciiValue) doWithIndex:
|
||||
[:val :ind |
|
||||
FromCharTable at: val + 1 put: ind + 25 + 26.
|
||||
ToCharTable at: ind + 26 + 26 put: val asCharacter].
|
||||
FromCharTable at: $+ asciiValue + 1 put: 62.
|
||||
ToCharTable at: 63 put: $+.
|
||||
FromCharTable at: $/ asciiValue + 1 put: 63.
|
||||
ToCharTable at: 64 put: $/
|
||||
]
|
||||
|
||||
Base64MimeConverter class >> mimeDecodeToBytes: aStream [
|
||||
"Return a RWBinaryOrTextStream of the original ByteArray. aStream has only 65 innocuous character values. aStream is not binary. (See class comment). 4 bytes in aStream goes to 3 bytes in output."
|
||||
|
||||
| me |
|
||||
aStream position: 0.
|
||||
me := self new mimeStream: aStream.
|
||||
me dataStream: (MIMERWStream
|
||||
on: (ByteArray new: aStream size * 3 // 4)).
|
||||
me mimeDecodeToByteArray.
|
||||
me dataStream position: 0.
|
||||
^me dataStream
|
||||
]
|
||||
|
||||
Base64MimeConverter class >> mimeEncode: aStream [
|
||||
"Return a ReadWriteStream of characters. The data of aStream is encoded as 65 innocuous characters. (See class comment). 3 bytes in aStream goes to 4 bytes in output."
|
||||
|
||||
| me |
|
||||
me := self new dataStream: aStream.
|
||||
me
|
||||
mimeStream: (MIMERWStream on: (String new: (aStream size + 20) * 4 // 3)).
|
||||
me mimeEncode.
|
||||
me mimeStream position: 0.
|
||||
^me mimeStream
|
||||
]
|
||||
|
||||
mimeDecode [
|
||||
"Convert a stream in base 64 with only a-z,A-Z,0-9,+,/ to a full byte stream of characters. Reutrn a whole stream for the user to read."
|
||||
|
||||
<category: 'conversion'>
|
||||
| nibA nibB nibC nibD |
|
||||
[mimeStream atEnd] whileFalse:
|
||||
[(nibA := self nextValue) ifNil: [^dataStream].
|
||||
(nibB := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: ((nibA bitShift: 2) + (nibB bitShift: -4)) asCharacter.
|
||||
nibB := nibB bitAnd: 15.
|
||||
(nibC := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: ((nibB bitShift: 4) + (nibC bitShift: -2)) asCharacter.
|
||||
nibC := nibC bitAnd: 3.
|
||||
(nibD := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: ((nibC bitShift: 6) + nibD) asCharacter].
|
||||
^dataStream
|
||||
]
|
||||
|
||||
mimeDecodeToByteArray [
|
||||
"Convert a stream in base 64 with only a-z,A-Z,0-9,+,/ to a full ByteArray of 0-255 values. Reutrn a whole stream for the user to read."
|
||||
|
||||
<category: 'conversion'>
|
||||
| nibA nibB nibC nibD |
|
||||
[mimeStream atEnd] whileFalse:
|
||||
[(nibA := self nextValue) ifNil: [^dataStream].
|
||||
(nibB := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: (nibA bitShift: 2) + (nibB bitShift: -4).
|
||||
nibB := nibB bitAnd: 15.
|
||||
(nibC := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: (nibB bitShift: 4) + (nibC bitShift: -2).
|
||||
nibC := nibC bitAnd: 3.
|
||||
(nibD := self nextValue) ifNil: [^dataStream].
|
||||
dataStream nextPut: (nibC bitShift: 6) + nibD].
|
||||
^dataStream
|
||||
]
|
||||
|
||||
mimeEncode [
|
||||
"Convert from data to 6 bit characters."
|
||||
|
||||
<category: 'conversion'>
|
||||
| phase1 phase2 raw nib lineLength |
|
||||
phase1 := phase2 := false.
|
||||
lineLength := 0.
|
||||
[dataStream atEnd] whileFalse:
|
||||
[lineLength >= 70
|
||||
ifTrue:
|
||||
[mimeStream cr.
|
||||
lineLength := 0].
|
||||
data := raw := dataStream next asInteger.
|
||||
nib := (data bitAnd: 252) bitShift: -2.
|
||||
mimeStream nextPut: (ToCharTable at: nib + 1).
|
||||
(raw := dataStream next) ifNil:
|
||||
[raw := 0.
|
||||
phase1 := true].
|
||||
data := ((data bitAnd: 3) bitShift: 8) + raw asInteger.
|
||||
nib := (data bitAnd: 1008) bitShift: -4.
|
||||
mimeStream nextPut: (ToCharTable at: nib + 1).
|
||||
(raw := dataStream next) ifNil:
|
||||
[raw := 0.
|
||||
phase2 := true].
|
||||
data := ((data bitAnd: 15) bitShift: 8) + raw asInteger.
|
||||
nib := (data bitAnd: 4032) bitShift: -6.
|
||||
mimeStream nextPut: (ToCharTable at: nib + 1).
|
||||
nib := data bitAnd: 63.
|
||||
mimeStream nextPut: (ToCharTable at: nib + 1).
|
||||
lineLength := lineLength + 4].
|
||||
phase1
|
||||
ifTrue:
|
||||
[mimeStream
|
||||
skip: -2;
|
||||
nextPut: $=;
|
||||
nextPut: $=.
|
||||
^mimeStream].
|
||||
phase2
|
||||
ifTrue:
|
||||
[mimeStream
|
||||
skip: -1;
|
||||
nextPut: $=.
|
||||
^mimeStream]
|
||||
]
|
||||
|
||||
nextValue [
|
||||
"The next six bits of data char from the mimeStream, or nil. Skip all other chars"
|
||||
|
||||
<category: 'conversion'>
|
||||
| raw num |
|
||||
|
||||
[raw := mimeStream next.
|
||||
raw ifNil: [^nil]. "end of stream"
|
||||
raw == $= ifTrue: [^nil].
|
||||
num := FromCharTable at: raw asciiValue + 1.
|
||||
num ifNotNil: [^num].
|
||||
"else ignore space, return, tab, ..."
|
||||
true]
|
||||
whileTrue
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
Eval [
|
||||
Base64MimeConverter initialize
|
||||
]
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
Eval [
|
||||
'From Pharo-1.1-11411 of 17 July 2010 [Latest update: #11411] on 19 February 2011 at 9:09:10 pm'
|
||||
]
|
||||
|
||||
|
||||
TestCase subclass: Base64MimeConverterTest [
|
||||
| message |
|
||||
|
||||
<comment: 'This is the unit test for the class Base64MimeConverter. Unit tests are a good way to exercise the functionality of your system in a repeatable and automatic manner. They are therefore recommended if you plan to release anything. For more information, see:
- http://www.c2.com/cgi/wiki?UnitTest
- http://minnow.cc.gatech.edu/squeak/1547
- the sunit class category'>
|
||||
<category: 'CollectionsTests-Streams'>
|
||||
|
||||
setUp [
|
||||
<category: 'setup'>
|
||||
message := 'Hi There!' readStream
|
||||
]
|
||||
|
||||
testBase64Encoded [
|
||||
"self run: #testBase64Encoded"
|
||||
|
||||
<category: 'tests'>
|
||||
| encoded |
|
||||
encoded := (Base64MimeConverter mimeEncode: message) contents.
|
||||
self assert: encoded = 'Hi There!' base64Encoded
|
||||
]
|
||||
|
||||
testMimeEncodeDecode [
|
||||
"self run: #testMimeEncodeDecode"
|
||||
|
||||
<category: 'tests'>
|
||||
| encoded |
|
||||
encoded := Base64MimeConverter mimeEncode: message.
|
||||
self assert: encoded contents = 'SGkgVGhlcmUh'.
|
||||
self assert: (Base64MimeConverter mimeDecodeToBytes: encoded) contents asString
|
||||
= message contents.
|
||||
|
||||
"Encoding should proceed from the current stream position."
|
||||
message reset.
|
||||
message skip: 2.
|
||||
encoded := Base64MimeConverter mimeEncode: message.
|
||||
self assert: encoded contents = 'IFRoZXJlIQ=='.
|
||||
]
|
||||
|
||||
testOnByteArray [
|
||||
"self run: #testOnByteArray"
|
||||
|
||||
<category: 'tests'>
|
||||
self
|
||||
assert: 'Hi There!' base64Encoded = 'Hi There!' asByteArray base64Encoded
|
||||
]
|
||||
]
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
Collection extend [
|
||||
beginsWith: aString [
|
||||
<category: '*soapopera-core'>
|
||||
|
||||
"This comes from Pharo 1.1 and is on SequencableCollection"
|
||||
"Answer true if the receiver starts with the argument collection"
|
||||
(aString isEmpty or: [self size < aString size]) ifTrue: [^false].
|
||||
aString withIndexDo: [:each :index | (self at: index) ~= each ifTrue: [^false]].
|
||||
^true
|
||||
]
|
||||
|
||||
withIndexDo: elementAndIndexBlock [
|
||||
<category: '*soapopera-core'>
|
||||
"This comes from Pharo 1.1 and is on SequencableCollection"
|
||||
"Just like with:do: except that the iteration index supplies the second argument to the block."
|
||||
1 to: self size do:
|
||||
[:index |
|
||||
elementAndIndexBlock
|
||||
value: (self at: index)
|
||||
value: index]
|
||||
]
|
||||
|
||||
ifEmpty: aBlock [
|
||||
<category: '*soapopera-core'>
|
||||
self isEmpty ifTrue: [^ aBlock value]
|
||||
]
|
||||
|
||||
isEmptyOrNil [
|
||||
<category: '*soapopera-core'>
|
||||
^ self isEmpty
|
||||
]
|
||||
|
||||
ifNotEmptyDo: aBlock [
|
||||
<category: '*soapopera-core'>
|
||||
"Evaluate the given block with the receiver as its argument."
|
||||
|
||||
self isEmpty ifFalse: [^ aBlock value: self].
|
||||
]
|
||||
|
||||
copyWithoutAll: aCollection [
|
||||
"Answer a copy of the receiver that does not contain any elements
|
||||
equal to those in aCollection."
|
||||
|
||||
^ self reject: [:each | aCollection includes: each]
|
||||
]
|
||||
]
|
||||
|
||||
String extend [
|
||||
findString: subString startingAt: aStart [
|
||||
| res start |
|
||||
<category: '*soapopera-core'>
|
||||
"This comes from Pharo 1.1 and is on String"
|
||||
"Answer the index of subString within the receiver, starting at start. If
|
||||
the receiver does not contain subString, answer 0."
|
||||
|
||||
start := aStart = 0 ifTrue: [1] ifFalse: [aStart].
|
||||
res := self indexOf: subString matchCase: true startingAt: start.
|
||||
|
||||
res ifNil: [^ 0]
|
||||
ifNotNil: [^ res first]
|
||||
]
|
||||
|
||||
base64Encoded [
|
||||
<category: '*network-mime'>
|
||||
"Encode the receiver as base64"
|
||||
"'Hello World' base64Encoded"
|
||||
^(Base64MimeConverter mimeEncode: self readStream) contents
|
||||
]
|
||||
|
||||
base64Decoded [
|
||||
<category: '*network-mime'>
|
||||
"Decode the receiver from base 64"
|
||||
"'SGVsbG8gV29ybGQ=' base64Decoded"
|
||||
^(Base64MimeConverter mimeDecode: self as: self class)
|
||||
]
|
||||
|
||||
withFirstCharacterDownshifted [
|
||||
"Return a copy with the first letter downShifted"
|
||||
| answer |
|
||||
|
||||
self ifEmpty: [^ self copy].
|
||||
answer := self copy.
|
||||
answer at: 1 put: (answer at: 1) asLowercase.
|
||||
^ answer.
|
||||
]
|
||||
]
|
||||
|
||||
ByteArray extend [
|
||||
base64Encoded [
|
||||
<category: '*network-mime'>
|
||||
"Encode the receiver as base64"
|
||||
"'Hello World' base64Encoded"
|
||||
^(Base64MimeConverter mimeEncode: self readStream) contents
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
UndefinedObject extend [
|
||||
isEmptyOrNil [
|
||||
<category: '*soapopera-core'>
|
||||
^ true
|
||||
]
|
||||
]
|
||||
|
||||
Character extend [
|
||||
charCode [
|
||||
<category: '*soapopera-core'>
|
||||
^ codePoint
|
||||
]
|
||||
]
|
||||
|
||||
DateTime extend [
|
||||
DateTime class >> fromString: aString [
|
||||
^ self readFrom: aString readStream.
|
||||
]
|
||||
|
||||
asString [
|
||||
^ String streamContents: [:stream | self printOn: stream]
|
||||
]
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
- Test with localhost as name..
|
||||
- Test redirection on HTTP. Actually this will emit an Exception that
|
||||
is not handled yet and should be handled.
|
||||
- Test with HTTPS
|
||||
- Implement auth in some way
|
|
@ -0,0 +1,7 @@
|
|||
http://www.mars.dti.ne.jp/~umejava/smalltalk/soapOpera/index.html
|
||||
|
||||
SoapOpera consists of two parts: SoapCore and OperaORB.
|
||||
SoapCore and OperaORB are licensed under the MIT style license.
|
||||
|
||||
Adoptions for Pharo considered as MIT licensed as well:
|
||||
http://www.squeaksource.com/@VtQYLu2HzOA7XXqy/qJ9Lxpcn
|
|
@ -0,0 +1,19 @@
|
|||
DynamicBindings-GuillermoPolito.3.mcz
|
||||
KomHttpServer-GuillermoPolito.16.mcz
|
||||
KomServices-GuillermoPolito.13.mcz
|
||||
SOAP-Client-GuillermoPolito.5.mcz
|
||||
SOAP-Core-GuillermoPolito.62.mcz
|
||||
SOAP-Example-GuillermoPolito.9.mcz
|
||||
SOAP-Extra-GuillermoPolito.7.mcz
|
||||
SOAP-Server-GuillermoPolito.12.mcz
|
||||
SOAP-TestCases-GuillermoPolito.34.mcz
|
||||
SoXML-GuillermoPolito.11.mcz
|
||||
|
||||
|
||||
= Unusual =
|
||||
The VW XMLParser wants to see namespaces... parsing of a simple element will
|
||||
fail due the lack of namespaces. We introduce a simple parser subclass that
|
||||
will cope with the fact of missing namespaces...
|
||||
|
||||
The xmlns:name=URL attributes are not seen... we will need to make them available
|
||||
to the SoapWrapElement.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,231 @@
|
|||
TestCase subclass: SoXmlAttributesHolderTestCase [
|
||||
|
||||
<comment: nil>
|
||||
<category: 'SOAP-TestCases'>
|
||||
|
||||
testAsDictionary [
|
||||
<category: 'testing'>
|
||||
| attribsHolder dict |
|
||||
attribsHolder := SoXmlAttributesHolder new.
|
||||
attribsHolder putAttribute: #('key1' 'val1').
|
||||
attribsHolder putAttribute: #('key2' 'val2').
|
||||
dict := attribsHolder asDictionary.
|
||||
self should: [(dict at: 'key1') = 'val1'].
|
||||
self should: [(dict at: 'key2') = 'val2']
|
||||
]
|
||||
|
||||
testDeclareNamespaceURIs [
|
||||
<category: 'testing'>
|
||||
| attribsHolder |
|
||||
attribsHolder := SoXmlAttributesHolder new.
|
||||
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
|
||||
attribsHolder declareNamespace: 'Foo2' uri: 'http://www.baz.org'.
|
||||
self should:
|
||||
[(attribsHolder declaredNamespaceURIFor: 'Foo1') = 'http://www.bar.org'].
|
||||
self should:
|
||||
[(attribsHolder declaredNamespaceURIFor: 'Foo2') = 'http://www.baz.org']
|
||||
]
|
||||
|
||||
testDeclareNamespaces [
|
||||
<category: 'testing'>
|
||||
| attribsHolder |
|
||||
attribsHolder := SoXmlAttributesHolder new.
|
||||
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
|
||||
attribsHolder declareNamespace: 'Foo2' uri: 'http://www.baz.org'.
|
||||
self
|
||||
should: [attribsHolder declaredNamespacePrefixes = (Set with: 'Foo1' with: 'Foo2')]
|
||||
]
|
||||
|
||||
testDeclareNamespacesAndPutAttributes [
|
||||
<category: 'testing'>
|
||||
| attribsHolder ansStr |
|
||||
attribsHolder := SoXmlAttributesHolder new.
|
||||
attribsHolder declareNamespace: 'Foo1' uri: 'http://www.bar.org'.
|
||||
attribsHolder putAttribute: #('key1' 'val1').
|
||||
ansStr := ' xmlns:Foo1="http://www.bar.org" key1="val1"'.
|
||||
self should: [ansStr = attribsHolder printString]
|
||||
]
|
||||
|
||||
testPutAttributes [
|
||||
<category: 'testing'>
|
||||
| attribsHolder |
|
||||
attribsHolder := SoXmlAttributesHolder new.
|
||||
attribsHolder putAttribute: #('key1' 'val1').
|
||||
self should: ['val1' = (attribsHolder getAttributeNamed: 'key1')].
|
||||
attribsHolder putAttribute: #('key1' 'val2').
|
||||
self shouldnt: ['val1' = (attribsHolder getAttributeNamed: 'key1')].
|
||||
self should: ['val2' = (attribsHolder getAttributeNamed: 'key1')]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
TestCase subclass: SoXmlUtilTestCase [
|
||||
|
||||
<comment: nil>
|
||||
<category: 'SOAP-TestCases'>
|
||||
|
||||
compString [
|
||||
<category: 'fixtures'>
|
||||
^self normalString , self convString
|
||||
]
|
||||
|
||||
convString [
|
||||
<category: 'fixtures'>
|
||||
^'<>''"&'
|
||||
]
|
||||
|
||||
nameapacedSimpleXmlString [
|
||||
<category: 'fixtures'>
|
||||
^'<m:Bar a="1" b="2" xmlns:m="http://soapinterop.org/">
|
||||
<bar>cont</bar>
|
||||
</m:Bar>'
|
||||
]
|
||||
|
||||
namespacedSimpleXmlElement [
|
||||
<category: 'fixtures'>
|
||||
^SoXmlUtil parseXml: self nameapacedSimpleXmlString
|
||||
]
|
||||
|
||||
normalString [
|
||||
<category: 'fixtures'>
|
||||
^'SoapOpera is a Squeak SOAP implementaion written by Masashi Umezawa'
|
||||
]
|
||||
|
||||
simpleXmlElement [
|
||||
<category: 'fixtures'>
|
||||
^SoXmlUtil parseXml: self simpleXmlString
|
||||
]
|
||||
|
||||
simpleXmlElementWithText [
|
||||
<category: 'fixtures'>
|
||||
^SoXmlUtil parseXml: self simpleXmlStringWithText
|
||||
]
|
||||
|
||||
simpleXmlString [
|
||||
<category: 'fixtures'>
|
||||
^'<Foo a="1" b="2">
|
||||
<bar>cont</bar>
|
||||
</Foo>'
|
||||
]
|
||||
|
||||
simpleXmlStringWithText [
|
||||
<category: 'fixtures'>
|
||||
^'<Foo a="1" b="2">
|
||||
some text...
|
||||
<bar>cont</bar>
|
||||
</Foo>'
|
||||
]
|
||||
|
||||
testAttribDict [
|
||||
<category: 'testing'>
|
||||
| elem dic1 dic2 |
|
||||
elem := self simpleXmlElement.
|
||||
dic1 := SoXmlUtil attribDictFrom: elem.
|
||||
dic2 := Dictionary new.
|
||||
dic2 at: 'a' put: '1'.
|
||||
dic2 at: 'b' put: '2'.
|
||||
self should: [dic1 = dic2]
|
||||
]
|
||||
|
||||
testComplexStringWrite [
|
||||
<category: 'testing'>
|
||||
| str1 str2 str3 |
|
||||
str1 := self compString.
|
||||
str2 := SoXmlUtil asXmlText: str1.
|
||||
str3 := self normalString , '<>'"&'.
|
||||
self shouldnt: [str1 = str2].
|
||||
self should: [str2 = str3]
|
||||
]
|
||||
|
||||
testConvStringWrite [
|
||||
<category: 'testing'>
|
||||
| str1 str2 str3 |
|
||||
str1 := self convString.
|
||||
str2 := SoXmlUtil asXmlText: str1.
|
||||
str3 := '<>'"&'.
|
||||
self shouldnt: [str1 = str2].
|
||||
self should: [str2 = str3]
|
||||
]
|
||||
|
||||
testElementName [
|
||||
<category: 'testing'>
|
||||
| elem nm |
|
||||
elem := self simpleXmlElement.
|
||||
nm := SoXmlUtil elementNameFrom: elem.
|
||||
self should: [nm = 'Foo']
|
||||
]
|
||||
|
||||
testElementShortName [
|
||||
<category: 'testing'>
|
||||
| elem2 nm2 |
|
||||
elem2 := self namespacedSimpleXmlElement.
|
||||
nm2 := SoXmlUtil elementShortNameFrom: elem2.
|
||||
self should: [nm2 = 'Bar']
|
||||
]
|
||||
|
||||
testElementsWithoutTexts [
|
||||
<category: 'testing'>
|
||||
| elem1 elems1 elem2 elems2 |
|
||||
elem1 := self simpleXmlElement.
|
||||
elems1 := SoXmlUtil elementsWithoutTextsFrom: elem1.
|
||||
elem2 := self simpleXmlElementWithText.
|
||||
elems2 := SoXmlUtil elementsWithoutTextsFrom: elem2.
|
||||
self should: [elems1 size = elems2 size].
|
||||
self should: [elems1 printString = elems2 printString]
|
||||
]
|
||||
|
||||
testNormalStringWrite [
|
||||
<category: 'testing'>
|
||||
| str1 str2 |
|
||||
str1 := self normalString.
|
||||
str2 := SoXmlUtil asXmlText: str1.
|
||||
self should: [str1 = str2]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
TestCase subclass: SoXmlWrapElementTestCase [
|
||||
|
||||
<comment: nil>
|
||||
<category: 'SOAP-TestCases'>
|
||||
|
||||
testElemPrint1 [
|
||||
<category: 'testing'>
|
||||
| fixString wStr xmlElem |
|
||||
fixString := '<Foo>bar</Foo>
|
||||
'.
|
||||
wStr := WriteStream on: (String new: 16).
|
||||
xmlElem := SoXmlWrapElement new.
|
||||
xmlElem name: 'Foo'.
|
||||
xmlElem value: 'bar'.
|
||||
xmlElem printXmlOn: wStr.
|
||||
self should: [wStr contents = fixString]
|
||||
]
|
||||
|
||||
testElemPrint2 [
|
||||
<category: 'testing'>
|
||||
| fixString wStr xmlElem child |
|
||||
fixString := '<SMIX>
|
||||
<interchangeUnit>
|
||||
<classDefinition className="Customer">
|
||||
<instVarNames>name address tel</instVarNames>
|
||||
</classDefinition>
|
||||
</interchangeUnit>
|
||||
</SMIX>
|
||||
'.
|
||||
wStr := WriteStream on: (String new: 16).
|
||||
xmlElem := SoXmlWrapElement new.
|
||||
xmlElem name: 'SMIX'.
|
||||
child := xmlElem createChildNamed: 'interchangeUnit'.
|
||||
child := child createChildNamed: 'classDefinition'.
|
||||
child putAttribute: #(#className #Customer).
|
||||
child := child createChildNamed: 'instVarNames'.
|
||||
child value: 'name address tel'.
|
||||
xmlElem printXmlOn: wStr.
|
||||
self should: [wStr contents = fixString]
|
||||
]
|
||||
]
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,457 @@
|
|||
|
||||
Object subclass: SoapSampleCustomer [
|
||||
| name age dateOfBirth |
|
||||
|
||||
<category: 'SOAP-Example-CustomComplexType'>
|
||||
<comment: nil>
|
||||
|
||||
SoapSampleCustomer class >> customerA [
|
||||
<category: 'sample instances'>
|
||||
| cust |
|
||||
cust := self new.
|
||||
cust name: 'Masashi'.
|
||||
cust age: 36.
|
||||
cust dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00').
|
||||
^cust
|
||||
]
|
||||
|
||||
SoapSampleCustomer class >> customerB [
|
||||
<category: 'sample instances'>
|
||||
| cust |
|
||||
cust := self new.
|
||||
cust name: 'Mike'.
|
||||
cust age: 26.
|
||||
cust dateOfBirth: (DateTime fromString: '1980-10-20T00:00:00-07:00').
|
||||
^cust
|
||||
]
|
||||
|
||||
SoapSampleCustomer class >> initialize [
|
||||
"SoapSampleCustomer initialize"
|
||||
|
||||
<category: 'class initialization'>
|
||||
SoapEncoder complexTypeDict at: self name put: 'types:Customer'.
|
||||
SoapLiteralEncoder complexTypeDict at: self name put: 'types:Customer'.
|
||||
SoapDecoder complexTypeDict at: 'types:Customer' put: self
|
||||
]
|
||||
|
||||
age [
|
||||
"Answer the value of age"
|
||||
|
||||
<category: 'accessing'>
|
||||
^age
|
||||
]
|
||||
|
||||
age: anObject [
|
||||
"Set the value of age"
|
||||
|
||||
<category: 'accessing'>
|
||||
age := anObject
|
||||
]
|
||||
|
||||
dateOfBirth [
|
||||
"Answer the value of dateOfBirth"
|
||||
|
||||
<category: 'accessing'>
|
||||
^dateOfBirth
|
||||
]
|
||||
|
||||
dateOfBirth: anObject [
|
||||
"Set the value of dateOfBirth"
|
||||
|
||||
<category: 'accessing'>
|
||||
dateOfBirth := anObject
|
||||
]
|
||||
|
||||
name [
|
||||
<category: 'accessing'>
|
||||
^name
|
||||
]
|
||||
|
||||
name: anObject [
|
||||
"Set the value of name"
|
||||
|
||||
<category: 'accessing'>
|
||||
name := anObject
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
Object subclass: SoapSampleGroup [
|
||||
| name members |
|
||||
|
||||
<category: 'SOAP-Example-CustomComplexType'>
|
||||
<comment: nil>
|
||||
|
||||
SoapSampleGroup class >> groupA [
|
||||
"SoapSampleGroup groupA"
|
||||
|
||||
<category: 'sample instances'>
|
||||
| group |
|
||||
group := self new.
|
||||
group name: 'Squeak support'.
|
||||
group members add: SoapSampleCustomer customerA.
|
||||
group members add: SoapSampleCustomer customerB.
|
||||
^group
|
||||
]
|
||||
|
||||
SoapSampleGroup class >> initialize [
|
||||
"SoapSampleGroup initialize"
|
||||
|
||||
<category: 'class initialization'>
|
||||
SoapEncoder complexTypeDict at: self name put: 'types:Groups'.
|
||||
SoapLiteralEncoder complexTypeDict at: self name put: 'types:Groups'.
|
||||
SoapDecoder complexTypeDict at: 'types:Groups' put: self
|
||||
]
|
||||
|
||||
members [
|
||||
"Answer the value of members"
|
||||
|
||||
<category: 'accessing'>
|
||||
members ifNil: [members := OrderedCollection new].
|
||||
^members
|
||||
]
|
||||
|
||||
members: anObject [
|
||||
"Set the value of members"
|
||||
|
||||
<category: 'accessing'>
|
||||
members := anObject
|
||||
]
|
||||
|
||||
name [
|
||||
<category: 'accessing'>
|
||||
^name
|
||||
]
|
||||
|
||||
name: anObject [
|
||||
"Set the value of name"
|
||||
|
||||
<category: 'accessing'>
|
||||
name := anObject
|
||||
]
|
||||
]
|
||||
|
||||
TestCase subclass: SoapDecoderCustomTestCase [
|
||||
|
||||
<comment: nil>
|
||||
<category: 'SOAP-TestCases'>
|
||||
|
||||
dotNetSharedValuesEnvelopeXML2 [
|
||||
<category: 'fixtures'>
|
||||
^'<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:types="http://tempuri.org/" xmlns:tns="http://tempuri.org/"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<types:FindCustomersResponse>
|
||||
<FindCustomersResult href="#id1"></FindCustomersResult>
|
||||
</types:FindCustomersResponse>
|
||||
<soapenc:Array id="id1" soapenc:arrayType="types:Customer[2]">
|
||||
<Item href="#id2"></Item>
|
||||
<Item href="#id3"></Item>
|
||||
</soapenc:Array>
|
||||
<types:Customer id="id2" xsi:type="types:Customer">
|
||||
<Name xsi:type="xsd:string">Ume</Name>
|
||||
<Age xsi:type="xsd:int">36</Age>
|
||||
<DateOfBirth
|
||||
xsi:type="xsd:dateTime">1970-11-22T00:00:00.0000000-07:00</DateOfBirth>
|
||||
</types:Customer>
|
||||
<types:Customer id="id3" xsi:type="types:Customer">
|
||||
<Name xsi:type="xsd:string">Ramon</Name>
|
||||
<Age xsi:type="xsd:int">31</Age>
|
||||
<DateOfBirth
|
||||
xsi:type="xsd:dateTime">1995-11-22T00:00:00.0000000-07:00</DateOfBirth>
|
||||
</types:Customer>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
'
|
||||
]
|
||||
|
||||
testDecodeDotNetSharedValuesXMLEnvelope2 [
|
||||
"self debug: #testDecodeDotNetSharedValuesXMLEnvelope2"
|
||||
|
||||
<category: 'testing'>
|
||||
| originalUseDotNetStyleSharedValues envelopeBuilder returnEnvelope message resp value |
|
||||
SoapSampleCustomer initialize.
|
||||
|
||||
[originalUseDotNetStyleSharedValues := SoapResponse
|
||||
useDotNetStyleSharedValues.
|
||||
SoapResponse useDotNetStyleSharedValues: true.
|
||||
envelopeBuilder := SoapEnvelopeBuilder new.
|
||||
returnEnvelope := envelopeBuilder
|
||||
buildSoapEnvelopeFromXmlString: self dotNetSharedValuesEnvelopeXML2.
|
||||
message := SoapMessage envelope: returnEnvelope.
|
||||
resp := SoapResponse fromSoapMessage: message.
|
||||
value := resp returnValue.
|
||||
self should: [value size = 2].
|
||||
self should: [value first name = 'Ume'].
|
||||
self should: [value first age = 36].
|
||||
self should:
|
||||
[value first dateOfBirth
|
||||
= (DateTime fromString: '1970-11-22T00:00:00-07:00')].
|
||||
self should: [value second name = 'Ramon'].
|
||||
self should: [value second age = 31].
|
||||
self should:
|
||||
[value second dateOfBirth
|
||||
= (DateTime fromString: '1995-11-22T00:00:00-07:00')]]
|
||||
ensure:
|
||||
[SoapResponse
|
||||
useDotNetStyleSharedValues: originalUseDotNetStyleSharedValues]
|
||||
]
|
||||
|
||||
testEncodeCustomStructType [
|
||||
"self debug: #testEncodeCustomStructType"
|
||||
|
||||
<category: 'testing'>
|
||||
| enc cust elem elem2 |
|
||||
enc := SoapEncoder new.
|
||||
enc useSharedValues: false.
|
||||
cust := SoapSampleCustomer new.
|
||||
cust
|
||||
name: 'John';
|
||||
age: 25;
|
||||
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
|
||||
yourself.
|
||||
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
|
||||
elem := enc
|
||||
encodeSoapVariable: (SoapVariable name: 'customer' value: cust).
|
||||
self should: [elem name = 'customer'].
|
||||
"self should: [elem xsiType isNil]."
|
||||
self should: [elem xsiType = 'types:Customer'].
|
||||
self should: [(elem findChildNamed: 'name') value = 'John'].
|
||||
self should: [(elem findChildNamed: 'age') value = '25'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(elem findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
|
||||
"
|
||||
elem2 := enc encodeSoapVariable: (SoapVariable
|
||||
name: 'customer'
|
||||
value: cust
|
||||
xsdType: (enc complexXsdTypeOf: cust)).
|
||||
self should: [elem2 name = 'customer'].
|
||||
self should: [elem2 xsiType = 'types:Customer'].
|
||||
self should: [(elem2 findChildNamed: 'name') value = 'John'].
|
||||
self should: [(elem2 findChildNamed: 'age') value = '25'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(elem2 findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00']
|
||||
"
|
||||
]
|
||||
|
||||
testEncodeCustomStructTypeHavingCustomStructs [
|
||||
"self debug: #testEncodeCustomStructTypeHavingCustomStructs"
|
||||
|
||||
<category: 'testing'>
|
||||
| enc group elem members memA memB |
|
||||
enc := SoapEncoder new.
|
||||
group := SoapSampleGroup groupA.
|
||||
enc complexTypeDict at: #SoapSampleGroup put: 'types:Group'.
|
||||
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
|
||||
enc useSharedValues: true.
|
||||
elem := enc encodeSoapVariable: (SoapVariable name: 'group' value: group).
|
||||
self should: [elem name = 'group'].
|
||||
self should: [(elem findChildNamed: 'name') value = 'Squeak support'].
|
||||
members := elem findChildNamed: 'members'.
|
||||
self should: [members xsiType isNil].
|
||||
self should: [members arrayItemType = 'types:Customer'].
|
||||
self should: [members size = 2].
|
||||
memA := members children first.
|
||||
self should: [memA name = 'item'].
|
||||
self should: [memA xsiType = 'types:Customer'].
|
||||
self should: [(memA findChildNamed: 'name') value = 'Masashi'].
|
||||
self should: [(memA findChildNamed: 'age') value = '36'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(memA findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
|
||||
"
|
||||
memB := members children second.
|
||||
self should: [memB name = 'item'].
|
||||
self should: [memB xsiType = 'types:Customer'].
|
||||
self should: [(memB findChildNamed: 'name') value = 'Mike'].
|
||||
self should: [(memB findChildNamed: 'age') value = '26'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(memB findChildNamed: 'dateOfBirth') value = '1980-10-20T00:00:00-07:00']
|
||||
"
|
||||
]
|
||||
|
||||
testEncodeCustomStructTypeSharedInArray [
|
||||
"self debug: #testEncodeCustomStructTypeSharedInArray"
|
||||
|
||||
<category: 'testing'>
|
||||
| enc cust cust2 elems elem first second third |
|
||||
enc := SoapEncoder new.
|
||||
cust := SoapSampleCustomer new.
|
||||
cust
|
||||
name: 'John';
|
||||
age: 25;
|
||||
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
|
||||
yourself.
|
||||
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
|
||||
cust2 := SoapSampleCustomer new.
|
||||
cust2
|
||||
name: 'Taro';
|
||||
age: 35;
|
||||
dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00');
|
||||
yourself.
|
||||
enc useSharedValues: true.
|
||||
elems := (SoapEncArray encoder: enc)
|
||||
fromArray: (Array
|
||||
with: cust
|
||||
with: cust2
|
||||
with: cust)
|
||||
named: 'resultElements'
|
||||
elementType: 'ResultElement'.
|
||||
elem := enc
|
||||
encodeSoapVariable: (SoapVariable name: 'resultElements' value: elems).
|
||||
self should: [elem isArrayType].
|
||||
first := elem children first.
|
||||
self should: [first id notNil].
|
||||
self should: [(first findChildNamed: 'name') value = 'John'].
|
||||
self should: [(first findChildNamed: 'age') value = '25'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(first findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
|
||||
"
|
||||
second := elem children second.
|
||||
self should: [second id isNil].
|
||||
self should: [(second findChildNamed: 'name') value = 'Taro'].
|
||||
self should: [(second findChildNamed: 'age') value = '35'].
|
||||
"BUG: FIXME:
|
||||
self should:
|
||||
[(second findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
|
||||
"
|
||||
third := elem children third.
|
||||
self should: [third id isNil].
|
||||
self should: [third children isEmpty].
|
||||
self should: [first id = (third href copyFrom: 2) asNumber]
|
||||
]
|
||||
|
||||
testEncodeCustomStructTypeSharedInStruct [
|
||||
"self debug: #testEncodeCustomStructTypeSharedInStruct"
|
||||
|
||||
<category: 'testing'>
|
||||
| enc cust cust2 elem struct1 a b c |
|
||||
enc := SoapEncoder new.
|
||||
cust := SoapSampleCustomer new.
|
||||
cust
|
||||
name: 'John';
|
||||
age: 25;
|
||||
dateOfBirth: (DateTime fromString: '1980-11-22T00:00:00-07:00');
|
||||
yourself.
|
||||
enc complexTypeDict at: #SoapSampleCustomer put: 'types:Customer'.
|
||||
cust2 := SoapSampleCustomer new.
|
||||
cust2
|
||||
name: 'Taro';
|
||||
age: 35;
|
||||
dateOfBirth: (DateTime fromString: '1970-11-22T00:00:00-07:00');
|
||||
yourself.
|
||||
struct1 := SoapEncStruct fromAssociations:
|
||||
{#a -> cust.
|
||||
#b -> cust2.
|
||||
#c -> cust2}.
|
||||
enc useSharedValues: true.
|
||||
elem := enc
|
||||
encodeSoapVariable: (SoapVariable name: 'resultElements' value: struct1).
|
||||
self should: [elem name = 'resultElements'].
|
||||
a := elem findChildNamed: 'a'.
|
||||
self should: [a id isNil].
|
||||
self should: [(a findChildNamed: 'name') value = 'John'].
|
||||
self should: [(a findChildNamed: 'age') value = '25'].
|
||||
"FIXME: BUG:
|
||||
self should:
|
||||
[(a findChildNamed: 'dateOfBirth') value = '1980-11-22T00:00:00-07:00'].
|
||||
"
|
||||
b := elem findChildNamed: 'b'.
|
||||
self should: [b id notNil].
|
||||
self should: [(b findChildNamed: 'name') value = 'Taro'].
|
||||
self should: [(b findChildNamed: 'age') value = '35'].
|
||||
"FIXME: BUG:
|
||||
self should:
|
||||
[(b findChildNamed: 'dateOfBirth') value = '1970-11-22T00:00:00-07:00'].
|
||||
"
|
||||
c := elem findChildNamed: 'c'.
|
||||
self should: [c id isNil].
|
||||
self should: [c children isEmpty].
|
||||
self should: [b id = (c href copyFrom: 2) asNumber]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
TestCase subclass: SoapDecoderCustomTestCase [
|
||||
|
||||
<comment: nil>
|
||||
<category: 'SOAP-TestCases'>
|
||||
|
||||
dotNetSharedValuesEnvelopeXML2 [
|
||||
<category: 'fixtures'>
|
||||
^'<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:types="http://tempuri.org/" xmlns:tns="http://tempuri.org/"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<types:FindCustomersResponse>
|
||||
<FindCustomersResult href="#id1"></FindCustomersResult>
|
||||
</types:FindCustomersResponse>
|
||||
<soapenc:Array id="id1" soapenc:arrayType="types:Customer[2]">
|
||||
<Item href="#id2"></Item>
|
||||
<Item href="#id3"></Item>
|
||||
</soapenc:Array>
|
||||
<types:Customer id="id2" xsi:type="types:Customer">
|
||||
<Name xsi:type="xsd:string">Ume</Name>
|
||||
<Age xsi:type="xsd:int">36</Age>
|
||||
<DateOfBirth
|
||||
xsi:type="xsd:dateTime">1970-11-22T00:00:00.0000000-07:00</DateOfBirth>
|
||||
</types:Customer>
|
||||
<types:Customer id="id3" xsi:type="types:Customer">
|
||||
<Name xsi:type="xsd:string">Ramon</Name>
|
||||
<Age xsi:type="xsd:int">31</Age>
|
||||
<DateOfBirth
|
||||
xsi:type="xsd:dateTime">1995-11-22T00:00:00.0000000-07:00</DateOfBirth>
|
||||
</types:Customer>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
'
|
||||
]
|
||||
|
||||
testDecodeDotNetSharedValuesXMLEnvelope2 [
|
||||
"self debug: #testDecodeDotNetSharedValuesXMLEnvelope2"
|
||||
|
||||
<category: 'testing'>
|
||||
| originalUseDotNetStyleSharedValues envelopeBuilder returnEnvelope message resp value |
|
||||
SoapSampleCustomer initialize.
|
||||
|
||||
[originalUseDotNetStyleSharedValues := SoapResponse
|
||||
useDotNetStyleSharedValues.
|
||||
SoapResponse useDotNetStyleSharedValues: true.
|
||||
envelopeBuilder := SoapEnvelopeBuilder new.
|
||||
returnEnvelope := envelopeBuilder
|
||||
buildSoapEnvelopeFromXmlString: self dotNetSharedValuesEnvelopeXML2.
|
||||
message := SoapMessage envelope: returnEnvelope.
|
||||
resp := SoapResponse fromSoapMessage: message.
|
||||
value := resp returnValue.
|
||||
self should: [value size = 2].
|
||||
self should: [value first name = 'Ume'].
|
||||
self should: [value first age = 36].
|
||||
|
||||
"BUG: broken time classes
|
||||
self should:
|
||||
[value first dateOfBirth
|
||||
= (DateTime fromString: '1970-11-22T00:00:00-07:00')].
|
||||
"
|
||||
self should: [value second name = 'Ramon'].
|
||||
self should: [value second age = 31].
|
||||
"BUG: broken time classes in GST
|
||||
self should:
|
||||
[value second dateOfBirth
|
||||
= (DateTime fromString: '1995-11-22T00:00:00-07:00')]
|
||||
"
|
||||
]
|
||||
ensure:
|
||||
[SoapResponse
|
||||
useDotNetStyleSharedValues: originalUseDotNetStyleSharedValues]
|
||||
]
|
||||
]
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
|||
<package>
|
||||
<name>SoapOpera</name>
|
||||
<namespace>SO</namespace>
|
||||
|
||||
<filein>Extensions.st</filein>
|
||||
<filein>Base64MimeConverter.st</filein>
|
||||
<filein>SoXML.st</filein>
|
||||
<filein>SoapCore.st</filein>
|
||||
<filein>SoapClient.st</filein>
|
||||
<test>
|
||||
<sunit>SO.SoXmlAttributesHolderTestCase</sunit>
|
||||
<sunit>SO.SoXmlUtilTestCase</sunit>
|
||||
<sunit>SO.SoXmlWrapElementTestCase</sunit>
|
||||
<sunit>SO.SoapActionTestCase</sunit>
|
||||
<sunit>SO.Base64MimeConverterTest</sunit>
|
||||
<sunit>SO.SoapDecoderTestCase</sunit>
|
||||
<sunit>SO.SoapCallTestCase</sunit>
|
||||
<sunit>SO.SoapEncArrayTestCase</sunit>
|
||||
<sunit>SO.SoapEncoderTestCase</sunit>
|
||||
<sunit>SO.SoapEnvelopeTestCase</sunit>
|
||||
<sunit>SO.SoapExceptionBuilderTestCase</sunit>
|
||||
<sunit>SO.SoapFaultTestCase</sunit>
|
||||
<sunit>SO.SoapHeaderTestCase</sunit>
|
||||
<sunit>SO.SoapNullDecoderTestCase</sunit>
|
||||
<sunit>SO.SoapNullEncoderTestCase</sunit>
|
||||
<sunit>SO.SoapVariableTestCase</sunit>
|
||||
<sunit>SO.SoapWrapElementTestCase</sunit>
|
||||
<sunit>SO.SoapEncStructTestCase</sunit>
|
||||
<sunit>SO.SoapEnvelopeBuilderTestCase</sunit>
|
||||
<sunit>SO.SoapDecoderTestCase</sunit>
|
||||
<sunit>SO.SoapDecoderCustomTestCase</sunit>
|
||||
<filein>SoXMLTest.st</filein>
|
||||
<filein>SoapCoreTests.st</filein>
|
||||
<filein>SoapComplexTypesTests.st</filein>
|
||||
<filein>Base64MimeConverterTest.st</filein>
|
||||
</test>
|
||||
</package>
|
Reference in New Issue