12ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum"""Test program for MimeWriter module.
22ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
32ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumThe test program was too big to comfortably fit in the MimeWriter
42ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossumclass, so it's here in its own file.
52ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
62ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumThis should generate Barry's example, modulo some quotes and newlines.
72ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
82ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum"""
92ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
10c5f05e45cffa16f45f1332cec531c045893f928fChristian Heimesimport unittest, StringIO
11bc27c6a5aa75a8f52304ecd311fbadef4ec621ceFlorent Xiclunafrom test.test_support import run_unittest, import_module
1290134c9a05146f3cc53fcb8a5de8fdfc2fe8dc93Brett Cannon
13bc27c6a5aa75a8f52304ecd311fbadef4ec621ceFlorent Xiclunaimport_module("MimeWriter", deprecated=True)
142ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossumfrom MimeWriter import MimeWriter
152ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
162ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumSELLER = '''\
172ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumINTERFACE Seller-1;
182ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
192ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumTYPE Seller = OBJECT
202ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum    DOCUMENTATION "A simple Seller interface to test ILU"
212ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum    METHODS
22068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            price():INTEGER,
232ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum    END;
242ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum'''
252ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
262ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumBUYER = '''\
272ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossumclass Buyer:
282ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum    def __setup__(self, maxprice):
29068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        self._maxprice = maxprice
302ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
312ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum    def __main__(self, kos):
32068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        """Entry point upon arrival at a new KOS."""
33068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        broker = kos.broker()
34068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        # B4 == Barry's Big Bass Business :-)
35068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        seller = broker.lookup('Seller_1.Seller', 'B4')
36068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        if seller:
37068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            price = seller.price()
38068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            print 'Seller wants $', price, '... '
39068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            if price > self._maxprice:
40068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum                print 'too much!'
41068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            else:
42068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum                print "I'll take it!"
43068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        else:
44068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum            print 'no seller found here'
45068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum'''                                     # Don't ask why this comment is here
462ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
472ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumSTATE = '''\
482ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum# instantiate a buyer instance and put it in a magic place for the KOS
492ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum# to find.
502ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum__kp__ = Buyer()
512ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum__kp__.__setup__(500)
522ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum'''
532ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
542ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumSIMPLE_METADATA = [
55068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Interpreter", "python"),
56068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Interpreter-Version", "1.3"),
57068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Owner-Name", "Barry Warsaw"),
58068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Owner-Rendezvous", "bwarsaw@cnri.reston.va.us"),
59068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Home-KSS", "kss.cnri.reston.va.us"),
60068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Identifier", "hdl://cnri.kss/my_first_knowbot"),
61068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Launch-Date", "Mon Feb 12 16:39:03 EST 1996"),
62068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ]
632ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
642ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumCOMPLEX_METADATA = [
65068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Metadata-Type", "complex"),
66068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Metadata-Key", "connection"),
67068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Access", "read-only"),
68068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Description", "Barry's Big Bass Business"),
69068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Id", "B4"),
70068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Direction", "client"),
71068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ]
722ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
732ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van RossumEXTERNAL_METADATA = [
74068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Metadata-Type", "complex"),
75068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Metadata-Key", "generic-interface"),
76068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Access", "read-only"),
77068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Description", "Generic Interface for All Knowbots"),
78068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Id", "generic-kp"),
79068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ("Connection-Direction", "client"),
80068ad9733023ee7dcce9184a39887e30421ed711Guido van Rossum        ]
812ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
822ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
83e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlOUTPUT = '''\
84e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlFrom: bwarsaw@cnri.reston.va.us
85e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlDate: Mon Feb 12 17:21:48 EST 1996
86e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlTo: kss-submit@cnri.reston.va.us
87e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlMIME-Version: 1.0
88e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: multipart/knowbot;
89e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    boundary="801spam999";
90e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    version="0.1"
91e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
92e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlThis is a multi-part message in MIME format.
93e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
94e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--801spam999
95e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: multipart/knowbot-metadata;
96e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    boundary="802spam999"
97e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
98e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
99e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--802spam999
100e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: message/rfc822
101e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Metadata-Type: simple
102e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Access: read-only
103e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
104e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Interpreter: python
105e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Interpreter-Version: 1.3
106e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Owner-Name: Barry Warsaw
107e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Owner-Rendezvous: bwarsaw@cnri.reston.va.us
108e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Home-KSS: kss.cnri.reston.va.us
109e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Identifier: hdl://cnri.kss/my_first_knowbot
110e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKPMD-Launch-Date: Mon Feb 12 16:39:03 EST 1996
111e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
112e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--802spam999
113e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: text/isl
114e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Metadata-Type: complex
115e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Metadata-Key: connection
116e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Access: read-only
117e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Description: Barry's Big Bass Business
118e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Id: B4
119e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Direction: client
1202ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
121e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlINTERFACE Seller-1;
122e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
123e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlTYPE Seller = OBJECT
124e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    DOCUMENTATION "A simple Seller interface to test ILU"
125e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    METHODS
126e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            price():INTEGER,
127e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    END;
128e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
129e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--802spam999
130e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: message/external-body;
131e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    access-type="URL";
132e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    URL="hdl://cnri.kss/generic-knowbot"
133e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
134e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: text/isl
135e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Metadata-Type: complex
136e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Metadata-Key: generic-interface
137e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Access: read-only
138e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Description: Generic Interface for All Knowbots
139e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Id: generic-kp
140e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Connection-Direction: client
141e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
142e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
143e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--802spam999--
144e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
145e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--801spam999
146e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: multipart/knowbot-code;
147e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    boundary="803spam999"
148e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
149e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
150e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--803spam999
151e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: text/plain
152e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Module-Name: BuyerKP
153e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
154e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandlclass Buyer:
155e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    def __setup__(self, maxprice):
156e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        self._maxprice = maxprice
157e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
158e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    def __main__(self, kos):
159e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        """Entry point upon arrival at a new KOS."""
160e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        broker = kos.broker()
161e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # B4 == Barry's Big Bass Business :-)
162e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        seller = broker.lookup('Seller_1.Seller', 'B4')
163e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        if seller:
164e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            price = seller.price()
165e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            print 'Seller wants $', price, '... '
166e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            if price > self._maxprice:
167e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl                print 'too much!'
168e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            else:
169e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl                print "I'll take it!"
170e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        else:
171e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            print 'no seller found here'
172e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
173e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--803spam999--
174e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
175e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--801spam999
176e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: multipart/knowbot-state;
177e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    boundary="804spam999"
178e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Main-Module: main
179e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
180e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
181e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--804spam999
182e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlContent-Type: text/plain
183e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg BrandlKP-Module-Name: main
184e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
185e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl# instantiate a buyer instance and put it in a magic place for the KOS
186e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl# to find.
187e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl__kp__ = Buyer()
188e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl__kp__.__setup__(500)
189e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
190e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--804spam999--
191e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
192e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl--801spam999--
193e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl'''
194e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
195e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandlclass MimewriterTest(unittest.TestCase):
196abd8a336a3ab390a2ea4b15a0ecd187e482001afTim Peters
197e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    def test(self):
198e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        buf = StringIO.StringIO()
199e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
200e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Toplevel headers
201e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl
202e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel = MimeWriter(buf)
203e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel.addheader("From", "bwarsaw@cnri.reston.va.us")
204e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
205e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel.addheader("To", "kss-submit@cnri.reston.va.us")
206e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel.addheader("MIME-Version", "1.0")
207004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake
208e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Toplevel body parts
2092ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
210e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f = toplevel.startmultipartbody("knowbot", "801spam999",
211e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl                                        [("version", "0.1")], prefix=0)
212e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f.write("This is a multi-part message in MIME format.\n")
213004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake
214e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # First toplevel body part: metadata
2152ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
216e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md = toplevel.nextpart()
217e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md.startmultipartbody("knowbot-metadata", "802spam999")
2182ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
219e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Metadata part 1
2202ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
221e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md1 = md.nextpart()
222e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md1.addheader("KP-Metadata-Type", "simple")
223e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md1.addheader("KP-Access", "read-only")
224e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        m = MimeWriter(md1.startbody("message/rfc822"))
225e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        for key, value in SIMPLE_METADATA:
226e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            m.addheader("KPMD-" + key, value)
227e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        m.flushheaders()
228e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        del md1
229004d5e6880940ddbb38460986ac62ee0f1bae97dFred Drake
230e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Metadata part 2
2312ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
232e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md2 = md.nextpart()
233e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        for key, value in COMPLEX_METADATA:
234e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            md2.addheader("KP-" + key, value)
235e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f = md2.startbody("text/isl")
236e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f.write(SELLER)
237e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        del md2
2382ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
239e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Metadata part 3
2402ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
241e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md3 = md.nextpart()
242e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f = md3.startbody("message/external-body",
243e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl                          [("access-type", "URL"),
244e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl                           ("URL", "hdl://cnri.kss/generic-knowbot")])
245e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        m = MimeWriter(f)
246e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        for key, value in EXTERNAL_METADATA:
247e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl            md3.addheader("KP-" + key, value)
248e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md3.startbody("text/isl")
249e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Phantom body doesn't need to be written
2502ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
251e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        md.lastpart()
2522ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
253e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Second toplevel body part: code
2542ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
255e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        code = toplevel.nextpart()
256e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        code.startmultipartbody("knowbot-code", "803spam999")
2572ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
258e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Code: buyer program source
2592ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
260e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        buyer = code.nextpart()
261e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        buyer.addheader("KP-Module-Name", "BuyerKP")
262e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f = buyer.startbody("text/plain")
263e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f.write(BUYER)
2642ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
265e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        code.lastpart()
2662ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
267e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # Third toplevel body part: state
2682ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
269e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        state = toplevel.nextpart()
270e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        state.addheader("KP-Main-Module", "main")
271e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        state.startmultipartbody("knowbot-state", "804spam999")
2722ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
273e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # State: a bunch of assignments
2742ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
275e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        st = state.nextpart()
276e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        st.addheader("KP-Module-Name", "main")
277e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f = st.startbody("text/plain")
278e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        f.write(STATE)
2792ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
280e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        state.lastpart()
2812ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
282e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        # End toplevel body parts
2832ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
284e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        toplevel.lastpart()
2852ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
286e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl        self.assertEqual(buf.getvalue(), OUTPUT)
2872ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
288e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandldef test_main():
289e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    run_unittest(MimewriterTest)
2902ad816f47ef5dffebb373c9dd980fcd61f4473a3Guido van Rossum
291e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandlif __name__ == '__main__':
292e8328ba72373bfc349d984f64d477c1b8d2c26c8Georg Brandl    test_main()
293