Example #1
0
    def test_process_amendments_section(self):
        xml = u"""
            <REGTEXT PART="105" TITLE="12">
            <AMDPAR>
            3. In § 105.1, revise paragraph (b) to read as follows:
            </AMDPAR>
            <SECTION>
                <SECTNO>§ 105.1</SECTNO>
                <SUBJECT>Purpose.</SUBJECT>
                <STARS/>
                <P>(b) This part carries out.</P>
            </SECTION>
            </REGTEXT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105'], 'cfr_part': '105'}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(notice['changes'].keys(), ['105-1-b'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(
            changes['node'].text.startswith(u'(b) This part carries out.'))
    def test_process_amendments_multiple_in_same_parent(self):
        xml = u"""
            <REGTEXT PART="105" TITLE="12">
                <AMDPAR>
                    1. In § 105.1, revise paragraph (b) to read as follows:
                </AMDPAR>
                <AMDPAR>2. Also, revise paragraph (c):</AMDPAR>
                <SECTION>
                    <SECTNO>§ 105.1</SECTNO>
                    <SUBJECT>Purpose.</SUBJECT>
                    <STARS/>
                    <P>(b) This part carries out.</P>
                    <P>(c) More stuff</P>
                </SECTION>
            </REGTEXT>"""

        notice_xml = etree.fromstring(xml)
        notice = {"cfr_parts": ["105"]}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(notice["changes"].keys(), ["105-1-b", "105-1-c"])

        changes = notice["changes"]["105-1-b"][0]
        self.assertEqual(changes["action"], "PUT")
        self.assertEqual(changes["node"]["text"].strip(), u"(b) This part carries out.")
        changes = notice["changes"]["105-1-c"][0]
        self.assertEqual(changes["action"], "PUT")
        self.assertTrue(changes["node"]["text"].strip(), u"(c) More stuff")
    def test_process_amendments_restart_new_section(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="104", TITLE="12"):
                ctx.AMDPAR("1. In Supplement I to Part 104, comment "
                           "22(a) is added")
                ctx.P("Content")
            with ctx.REGTEXT(PART="105", TITLE="12"):
                ctx.AMDPAR(u"3. In § 105.1, revise paragraph (b) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 105.1")
                    ctx.SUBJECT("Purpose.")
                    ctx.STARS()
                    ctx.P("(b) This part carries out.")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['amendments']))
        c22a, b = notice['amendments']
        self.assertEqual(c22a.action, 'POST')
        self.assertEqual(b.action, 'PUT')
        self.assertEqual(c22a.label, ['104', '22', 'a', 'Interp'])
        self.assertEqual(b.label, ['105', '1', 'b'])
    def test_process_amendments_mix_regs(self):
        """Some notices apply to multiple regs. For now, just ignore the
        sections not associated with the reg we're focused on"""
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="105", TITLE="12"):
                ctx.AMDPAR(u"3. In § 105.1, revise paragraph (a) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 105.1")
                    ctx.SUBJECT("105Purpose.")
                    ctx.P("(a) 105Content")
            with ctx.REGTEXT(PART="106", TITLE="12"):
                ctx.AMDPAR(u"3. In § 106.3, revise paragraph (b) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 106.3")
                    ctx.SUBJECT("106Purpose.")
                    ctx.P("(b) Content")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['changes']))
        self.assertTrue('105-1-a' in notice['changes'])
        self.assertTrue('106-3-b' in notice['changes'])
    def test_process_amendments_mix_regs(self):
        """Some notices apply to multiple regs. For now, just ignore the
        sections not associated with the reg we're focused on"""
        with self.tree.builder("ROOT") as root:
            with root.REGTEXT(PART="105", TITLE="12") as regtext:
                regtext.AMDPAR(u"3. In § 105.1, revise paragraph (a) to read "
                               "as follows:")
                with regtext.SECTION() as section:
                    section.SECTNO(u"§ 105.1")
                    section.SUBJECT("105Purpose.")
                    section.P("(a) 105Content")
            with root.REGTEXT(PART="106", TITLE="12") as regtext:
                regtext.AMDPAR(u"3. In § 106.3, revise paragraph (b) to read "
                               "as follows:")
                with regtext.SECTION() as section:
                    section.SECTNO(u"§ 106.3")
                    section.SUBJECT("106Purpose.")
                    section.P("(b) Content")

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(2, len(notice['changes']))
        self.assertTrue('105-1-a' in notice['changes'])
        self.assertTrue('106-3-b' in notice['changes'])
    def test_process_amendments_multiple_in_same_parent(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            ctx.AMDPAR(u"1. In § 105.1, revise paragraph (b) to read as "
                       u"follows:")
            ctx.AMDPAR("2. Also, revise paragraph (c):")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 105.1")
                ctx.SUBJECT("Purpose.")
                ctx.STARS()
                ctx.P("(b) This part carries out.")
                ctx.P("(c) More stuff")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        self.assertItemsEqual(notice['changes'].keys(), ['105-1-b', '105-1-c'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertEqual(changes['node']['text'].strip(),
                         u'(b) This part carries out.')
        changes = notice['changes']['105-1-c'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(changes['node']['text'].strip(), u'(c) More stuff')
Example #7
0
    def test_multiple_changes(self):
        """ A notice can have two modifications to a paragraph. """

        xml = u"""
        <ROOT>
        <REGTEXT PART="106" TITLE="12">
        <AMDPAR>
            2. Designate §§ 106.1 through 106.3 as subpart A under the heading.
        </AMDPAR>
        </REGTEXT>
        <REGTEXT PART="106" TITLE="12">
        <AMDPAR>
            3. In § 106.2, revise the introductory text to read as follows:
        </AMDPAR>
        <SECTION>
            <SECTNO>§ 106.2</SECTNO>
            <SUBJECT> Definitions </SUBJECT>
            <P> Except as otherwise provided, the following apply. </P>
        </SECTION>
        </REGTEXT>
        </ROOT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(2, len(notice['changes']['106-2']))
    def test_process_amendments_section(self):
        xml = u"""
            <REGTEXT PART="105" TITLE="12">
            <AMDPAR>
            3. In § 105.1, revise paragraph (b) to read as follows:
            </AMDPAR>
            <SECTION>
                <SECTNO>§ 105.1</SECTNO>
                <SUBJECT>Purpose.</SUBJECT>
                <STARS/>
                <P>(b) This part carries out.</P>
            </SECTION>
            </REGTEXT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_part': '105'}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(notice['changes'].keys(), ['105-1-b'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(changes['node']['text'].startswith(
            u'(b) This part carries out.'))
    def test_process_amendments_mix_regs(self):
        """Some notices apply to multiple regs. For now, just ignore the
        sections not associated with the reg we're focused on"""
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="105", TITLE="12"):
                ctx.AMDPAR(u"3. In § 105.1, revise paragraph (a) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 105.1")
                    ctx.SUBJECT("105Purpose.")
                    ctx.P("(a) 105Content")
            with ctx.REGTEXT(PART="106", TITLE="12"):
                ctx.AMDPAR(u"3. In § 106.3, revise paragraph (b) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 106.3")
                    ctx.SUBJECT("106Purpose.")
                    ctx.P("(b) Content")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['changes']))
        self.assertTrue('105-1-a' in notice['changes'])
        self.assertTrue('106-3-b' in notice['changes'])
    def test_process_amendments_subpart(self):
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, self.new_subpart_xml())

        self.assertTrue('105-Subpart-B' in notice['changes'].keys())
        self.assertTrue('105-30-a' in notice['changes'].keys())
        self.assertTrue('105-30' in notice['changes'].keys())
Example #11
0
    def test_process_amendments_multiple_in_same_parent(self):
        xml = u"""
            <REGTEXT PART="105" TITLE="12">
                <AMDPAR>
                    1. In § 105.1, revise paragraph (b) to read as follows:
                </AMDPAR>
                <AMDPAR>2. Also, revise paragraph (c):</AMDPAR>
                <SECTION>
                    <SECTNO>§ 105.1</SECTNO>
                    <SUBJECT>Purpose.</SUBJECT>
                    <STARS/>
                    <P>(b) This part carries out.</P>
                    <P>(c) More stuff</P>
                </SECTION>
            </REGTEXT>"""

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(notice['changes'].keys(), ['105-1-b', '105-1-c'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertEqual(changes['node']['text'].strip(),
                         u'(b) This part carries out.')
        changes = notice['changes']['105-1-c'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(changes['node']['text'].strip(),
                        u'(c) More stuff')
Example #12
0
    def test_process_amendments_restart_new_section(self):
        xml = u"""
        <ROOT>
            <REGTEXT PART="104" TITLE="12">
                <AMDPAR>
                    1. In Supplement I to Part 104, comment 22(a) is added
                </AMDPAR>
                <P>Content</P>
            </REGTEXT>
            <REGTEXT PART="105" TITLE="12">
                <AMDPAR>
                3. In § 105.1, revise paragraph (b) to read as follows:
                </AMDPAR>
                <SECTION>
                    <SECTNO>§ 105.1</SECTNO>
                    <SUBJECT>Purpose.</SUBJECT>
                    <STARS/>
                    <P>(b) This part carries out.</P>
                </SECTION>
            </REGTEXT>
        </ROOT>"""

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(2, len(notice['amendments']))
        c22a, b = notice['amendments']
        self.assertEqual(c22a.action, 'POST')
        self.assertEqual(b.action, 'PUT')
        self.assertEqual(c22a.label, ['104', '22', 'a', 'Interp'])
        self.assertEqual(b.label, ['105', '1', 'b'])
    def test_process_amendments_restart_new_section(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="104", TITLE="12"):
                ctx.AMDPAR("1. In Supplement I to Part 104, comment "
                           "22(a) is added")
                ctx.P("Content")
            with ctx.REGTEXT(PART="105", TITLE="12"):
                ctx.AMDPAR(u"3. In § 105.1, revise paragraph (b) to read as "
                           u"follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 105.1")
                    ctx.SUBJECT("Purpose.")
                    ctx.STARS()
                    ctx.P("(b) This part carries out.")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['amendments']))
        c22a, b = notice['amendments']
        self.assertEqual(c22a.action, 'POST')
        self.assertEqual(b.action, 'PUT')
        self.assertEqual(c22a.label, ['104', '22', 'a', 'Interp'])
        self.assertEqual(b.label, ['105', '1', 'b'])
    def test_process_amendments_multiple_in_same_parent(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            ctx.AMDPAR(u"1. In § 105.1, revise paragraph (b) to read as "
                       u"follows:")
            ctx.AMDPAR("2. Also, revise paragraph (c):")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 105.1")
                ctx.SUBJECT("Purpose.")
                ctx.STARS()
                ctx.P("(b) This part carries out.")
                ctx.P("(c) More stuff")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        self.assertItemsEqual(notice['changes'].keys(), ['105-1-b', '105-1-c'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertEqual(changes['node']['text'].strip(),
                         u'(b) This part carries out.')
        changes = notice['changes']['105-1-c'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(changes['node']['text'].strip(),
                        u'(c) More stuff')
    def test_process_amendments_subpart(self):
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, self.new_subpart_xml())

        self.assertTrue('105-Subpart-B' in notice['changes'].keys())
        self.assertTrue('105-30-a' in notice['changes'].keys())
        self.assertTrue('105-30' in notice['changes'].keys())
Example #16
0
    def test_process_amendments_mix_regs(self):
        """Some notices apply to multiple regs. For now, just ignore the
        sections not associated with the reg we're focused on"""
        xml = u"""
            <ROOT>
            <REGTEXT PART="105" TITLE="12">
                <AMDPAR>
                3. In § 105.1, revise paragraph (a) to read as follows:
                </AMDPAR>
                <SECTION>
                    <SECTNO>§ 105.1</SECTNO>
                    <SUBJECT>105Purpose.</SUBJECT>
                    <P>(a) 105Content</P>
                </SECTION>
            </REGTEXT>
            <REGTEXT PART="106" TITLE="12">
                <AMDPAR>
                3. In § 106.3, revise paragraph (b) to read as follows:
                </AMDPAR>
                <SECTION>
                    <SECTNO>§ 106.3</SECTNO>
                    <SUBJECT>106Purpose.</SUBJECT>
                    <P>(b) Content</P>
                </SECTION>
            </REGTEXT>
            </ROOT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(2, len(notice['changes']))
        self.assertTrue('105-1-a' in notice['changes'])
        self.assertTrue('106-3-b' in notice['changes'])
    def test_process_amendments_multiple_in_same_parent(self):
        with self.tree.builder("REGTEXT", PART="105", TITLE="12") as regtext:
            regtext.AMDPAR(u"1. In § 105.1, revise paragraph (b) to read as "
                           "follows:")
            regtext.AMDPAR("2. Also, revise paragraph (c):")
            with regtext.SECTION() as section:
                section.SECTNO(u"§ 105.1")
                section.SUBJECT("Purpose.")
                section.STARS()
                section.P("(b) This part carries out.")
                section.P("(c) More stuff")

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(notice['changes'].keys(), ['105-1-b', '105-1-c'])

        changes = notice['changes']['105-1-b'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertEqual(changes['node']['text'].strip(),
                         u'(b) This part carries out.')
        changes = notice['changes']['105-1-c'][0]
        self.assertEqual(changes['action'], 'PUT')
        self.assertTrue(changes['node']['text'].strip(),
                        u'(c) More stuff')
Example #18
0
    def test_process_amendments_context(self):
        """Context should carry over between REGTEXTs"""
        xml = u"""
            <ROOT>
            <REGTEXT TITLE="12">
                <AMDPAR>
                3. In § 106.1, revise paragraph (a) to read as follows:
                </AMDPAR>
            </REGTEXT>
            <REGTEXT TITLE="12">
                <AMDPAR>
                3. Add appendix C
                </AMDPAR>
            </REGTEXT>
            </ROOT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(2, len(notice['amendments']))
        amd1, amd2 = notice['amendments']
        self.assertEqual(['106', '1', 'a'], amd1.label)
        self.assertEqual(['106', 'C'], amd2.label)
Example #19
0
    def test_process_amendments_subpart(self):
        xml = self.new_subpart_xml()

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, notice_xml)

        self.assertTrue('105-Subpart-B' in notice['changes'].keys())
        self.assertTrue('105-30-a' in notice['changes'].keys())
        self.assertTrue('105-30' in notice['changes'].keys())
    def test_process_amendments_subpart(self):
        xml = self.new_subpart_xml()

        notice_xml = etree.fromstring(xml)
        notice = {"cfr_parts": ["105"]}
        build.process_amendments(notice, notice_xml)

        self.assertTrue("105-Subpart-B" in notice["changes"].keys())
        self.assertTrue("105-30-a" in notice["changes"].keys())
        self.assertTrue("105-30" in notice["changes"].keys())
    def test_process_amendments_no_nodes(self):
        with self.tree.builder("ROOT") as root:
            with root.REGTEXT(PART="104", TITLE="12") as regtext:
                regtext.AMDPAR(u"1. In § 104.13, paragraph (b) is removed")

        notice = {'cfr_parts': ['104']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(1, len(notice['amendments']))
        delete = notice['amendments'][0]
        self.assertEqual(delete.action, 'DELETE')
        self.assertEqual(delete.label, ['104', '13', 'b'])
    def test_process_amendments_no_nodes(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="104", TITLE="12"):
                ctx.AMDPAR(u"1. In § 104.13, paragraph (b) is removed")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['104']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(1, len(notice['amendments']))
        delete = notice['amendments'][0]
        self.assertEqual(delete.action, 'DELETE')
        self.assertEqual(delete.label, ['104', '13', 'b'])
    def test_process_amendments_no_nodes(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="104", TITLE="12"):
                ctx.AMDPAR(u"1. In § 104.13, paragraph (b) is removed")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['104']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(1, len(notice['amendments']))
        delete = notice['amendments'][0]
        self.assertEqual(delete.action, 'DELETE')
        self.assertEqual(delete.label, ['104', '13', 'b'])
    def test_introductory_text(self):
        """ Sometimes notices change just the introductory text of a paragraph
        (instead of changing the entire paragraph tree).  """
        with XMLBuilder("REGTEXT", PART="106", TITLE="12") as ctx:
            ctx.AMDPAR(u"3. In § 106.2, revise the introductory text to read "
                       u"as follows:")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 106.2")
                ctx.SUBJECT(" Definitions ")
                ctx.P(" Except as otherwise provided, the following apply. ")
        ParseAMDPARs().transform(ctx.xml)
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual('[text]', notice['changes']['106-2'][0]['field'])
    def test_introductory_text(self):
        """ Sometimes notices change just the introductory text of a paragraph
        (instead of changing the entire paragraph tree).  """
        with XMLBuilder("REGTEXT", PART="106", TITLE="12") as ctx:
            ctx.AMDPAR(u"3. In § 106.2, revise the introductory text to read "
                       u"as follows:")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 106.2")
                ctx.SUBJECT(" Definitions ")
                ctx.P(" Except as otherwise provided, the following apply. ")
        ParseAMDPARs().transform(ctx.xml)
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual('[text]', notice['changes']['106-2'][0]['field'])
    def test_introductory_text(self):
        """ Sometimes notices change just the introductory text of a paragraph
        (instead of changing the entire paragraph tree).  """
        with self.tree.builder("REGTEXT", PART="106", TITLE="12") as regtext:
            regtext.AMDPAR(u"3. In § 106.2, revise the introductory text to "
                           "read as follows:")
            with regtext.SECTION() as section:
                section.SECTNO(u"§ 106.2")
                section.SUBJECT(" Definitions ")
                section.P(" Except as otherwise provided, the following "
                          "apply. ")
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual('[text]', notice['changes']['106-2'][0]['field'])
    def test_process_amendments_markerless(self):
        with self.tree.builder("REGTEXT", PART="105", TITLE="12") as regtext:
            regtext.AMDPAR(u"1. Revise [label:105-11-p5] as blah")
            with regtext.SECTION() as section:
                section.SECTNO(u"§ 105.11")
                section.SUBJECT("Purpose.")
                section.STARS()
                section.P("Some text here")

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, self.tree.render_xml())
        self.assertEqual(notice['changes'].keys(), ['105-11-p5'])

        changes = notice['changes']['105-11-p5'][0]
        self.assertEqual(changes['action'], 'PUT')
    def test_process_amendments_markerless(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            ctx.AMDPAR(u"1. Revise [label:105-11-p5] as blah")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 105.11")
                ctx.SUBJECT("Purpose.")
                ctx.STARS()
                ctx.P("Some text here")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)
        self.assertItemsEqual(notice['changes'].keys(), ['105-11-p5'])

        changes = notice['changes']['105-11-p5'][0]
        self.assertEqual(changes['action'], 'PUT')
    def test_process_amendments_markerless(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            ctx.AMDPAR(u"1. Revise [label:105-11-p5] as blah")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 105.11")
                ctx.SUBJECT("Purpose.")
                ctx.STARS()
                ctx.P("Some text here")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)
        self.assertItemsEqual(notice['changes'].keys(), ['105-11-p5'])

        changes = notice['changes']['105-11-p5'][0]
        self.assertEqual(changes['action'], 'PUT')
    def test_process_amendments_context(self):
        """Context should carry over between REGTEXTs"""
        with self.tree.builder("ROOT") as root:
            with root.REGTEXT(TITLE="12") as regtext:
                regtext.AMDPAR(u"3. In § 106.1, revise paragraph (a) to "
                               "read as follows:")
            with root.REGTEXT(TITLE="12") as regtext:
                regtext.AMDPAR("3. Add appendix C")

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(2, len(notice['amendments']))
        amd1, amd2 = notice['amendments']
        self.assertEqual(['106', '1', 'a'], amd1.label)
        self.assertEqual(['106', 'C'], amd2.label)
    def test_process_amendments(self):
        with self.tree.builder("REGTEXT", PART="105", TITLE="12") as regtext:
            with regtext.SUBPART() as subpart:
                subpart.HD(u"Subpart A—General", SOURCE="HED")
            regtext.AMDPAR(u"2. Designate §§ 105.1 through 105.3 as subpart "
                           "A under the heading.")

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, self.tree.render_xml())

        section_list = ['105-2', '105-3', '105-1']
        self.assertEqual(notice['changes'].keys(), section_list)

        for l, c in notice['changes'].items():
            change = c[0]
            self.assertEqual(change['destination'], ['105', 'Subpart', 'A'])
            self.assertEqual(change['action'], 'DESIGNATE')
    def test_process_amendments_context(self):
        """Context should carry over between REGTEXTs"""
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(TITLE="12"):
                ctx.AMDPAR(u"3. In § 106.1, revise paragraph (a) to read as "
                           u"follows:")
            with ctx.REGTEXT(TITLE="12"):
                ctx.AMDPAR("3. Add appendix C")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['amendments']))
        amd1, amd2 = notice['amendments']
        self.assertEqual(['106', '1', 'a'], amd1.label)
        self.assertEqual(['106', 'C'], amd2.label)
    def test_process_amendments_insert_in_order(self):
        with self.tree.builder("ROOT") as root:
            with root.REGTEXT(TITLE="10") as regtext:
                regtext.AMDPAR('[insert-in-order] [label:123-45-p6]')
                with regtext.SECTION() as section:
                    section.SECTNO(u"§ 123.45")
                    section.SUBJECT("Some Subject.")
                    section.STARS()
                    section.P("This is the sixth paragraph")
                    section.STARS()
        notice = {'cfr_parts': ['123']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(1, len(notice['amendments']))
        amendment = notice['amendments'][0]
        self.assertEqual(['123', '45', 'p6'], amendment.label)
        self.assertEqual('INSERT', amendment.action)
    def test_process_amendments_context(self):
        """Context should carry over between REGTEXTs"""
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(TITLE="12"):
                ctx.AMDPAR(u"3. In § 106.1, revise paragraph (a) to read as "
                           u"follows:")
            with ctx.REGTEXT(TITLE="12"):
                ctx.AMDPAR("3. Add appendix C")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105', '106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['amendments']))
        amd1, amd2 = notice['amendments']
        self.assertEqual(['106', '1', 'a'], amd1.label)
        self.assertEqual(['106', 'C'], amd2.label)
    def test_process_amendments_insert_in_order(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(TITLE="10"):
                ctx.AMDPAR('[insert-in-order] [label:123-45-p6]')
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 123.45")
                    ctx.SUBJECT("Some Subject.")
                    ctx.STARS()
                    ctx.P("This is the sixth paragraph")
                    ctx.STARS()
        ParseAMDPARs().transform(ctx.xml)
        notice = {'cfr_parts': ['123']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(1, len(notice['amendments']))
        amendment = notice['amendments'][0]
        self.assertEqual(['123', '45', 'p6'], amendment.label)
        self.assertEqual('INSERT', amendment.action)
Example #36
0
    def test_process_amendments_no_nodes(self):
        xml = u"""
        <ROOT>
            <REGTEXT PART="104" TITLE="12">
                <AMDPAR>
                    1. In § 104.13, paragraph (b) is removed
                </AMDPAR>
            </REGTEXT>
        </ROOT>"""

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['104']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(1, len(notice['amendments']))
        delete = notice['amendments'][0]
        self.assertEqual(delete.action, 'DELETE')
        self.assertEqual(delete.label, ['104', '13', 'b'])
    def test_process_amendments_insert_in_order(self):
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(TITLE="10"):
                ctx.AMDPAR('[insert-in-order] [label:123-45-p6]')
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 123.45")
                    ctx.SUBJECT("Some Subject.")
                    ctx.STARS()
                    ctx.P("This is the sixth paragraph")
                    ctx.STARS()
        ParseAMDPARs().transform(ctx.xml)
        notice = {'cfr_parts': ['123']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(1, len(notice['amendments']))
        amendment = notice['amendments'][0]
        self.assertEqual(['123', '45', 'p6'], amendment.label)
        self.assertEqual('INSERT', amendment.action)
    def test_process_amendments_no_nodes(self):
        xml = u"""
        <ROOT>
            <REGTEXT PART="104" TITLE="12">
                <AMDPAR>
                    1. In § 104.13, paragraph (b) is removed
                </AMDPAR>
            </REGTEXT>
        </ROOT>"""

        notice_xml = etree.fromstring(xml)
        notice = {"cfr_parts": ["104"]}
        build.process_amendments(notice, notice_xml)

        self.assertEqual(1, len(notice["amendments"]))
        delete = notice["amendments"][0]
        self.assertEqual(delete.action, "DELETE")
        self.assertEqual(delete.label, ["104", "13", "b"])
    def test_process_amendments(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            with ctx.SUBPART():
                ctx.HD(u"Subpart A—General", SOURCE="HED")
            ctx.AMDPAR(u"2. Designate §§ 105.1 through 105.3 as subpart A "
                       u"under the heading.")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        section_list = ['105-2', '105-3', '105-1']
        self.assertItemsEqual(notice['changes'].keys(), section_list)

        for l, c in notice['changes'].items():
            change = c[0]
            self.assertEqual(change['destination'], ['105', 'Subpart', 'A'])
            self.assertEqual(change['action'], 'DESIGNATE')
    def test_multiple_changes(self):
        """ A notice can have two modifications to a paragraph. """
        with self.tree.builder("ROOT") as root:
            with root.REGTEXT(PART="106", TITLE="12") as regtext:
                regtext.AMDPAR(u"2. Designate §§ 106.1 through 106.3 as "
                               "subpart A under the heading.")
            with root.REGTEXT(PART="106", TITLE="12") as regtext:
                regtext.AMDPAR(u"3. In § 106.2, revise the introductory text "
                               "to read as follows:")
                with regtext.SECTION() as section:
                    section.SECTNO(u"§ 106.2")
                    section.SUBJECT(" Definitions ")
                    section.P(" Except as otherwise provided, the following "
                              "apply. ")
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, self.tree.render_xml())

        self.assertEqual(2, len(notice['changes']['106-2']))
    def test_process_amendments(self):
        with XMLBuilder("REGTEXT", PART="105", TITLE="12") as ctx:
            with ctx.SUBPART():
                ctx.HD(u"Subpart A—General", SOURCE="HED")
            ctx.AMDPAR(u"2. Designate §§ 105.1 through 105.3 as subpart A "
                       u"under the heading.")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, ctx.xml)

        section_list = ['105-2', '105-3', '105-1']
        self.assertItemsEqual(notice['changes'].keys(), section_list)

        for l, c in notice['changes'].items():
            change = c[0]
            self.assertEqual(change['destination'], ['105', 'Subpart', 'A'])
            self.assertEqual(change['action'], 'DESIGNATE')
    def test_multiple_changes(self):
        """ A notice can have two modifications to a paragraph. """
        with XMLBuilder("ROOT") as ctx:
            with ctx.REGTEXT(PART="106", TITLE="12"):
                ctx.AMDPAR(u"2. Designate §§ 106.1 through 106.3 as subpart "
                           u"A under the heading.")
            with ctx.REGTEXT(PART="106", TITLE="12"):
                ctx.AMDPAR(u"3. In § 106.2, revise the introductory text to "
                           u"read as follows:")
                with ctx.SECTION():
                    ctx.SECTNO(u"§ 106.2")
                    ctx.SUBJECT(" Definitions ")
                    ctx.P(" Except as otherwise provided, the following "
                          "apply. ")
        ParseAMDPARs().transform(ctx.xml)
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, ctx.xml)

        self.assertEqual(2, len(notice['changes']['106-2']))
    def test_process_amendments_multiple_sections(self):
        """Regression test verifying multiple SECTIONs in the same REGTEXT"""
        with XMLBuilder("REGTEXT", PART="111") as ctx:
            ctx.AMDPAR(u"1. Modify § 111.22 by revising paragraph (b)")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 111.22")
                ctx.SUBJECT("Subject Here.")
                ctx.STARS()
                ctx.P("(b) Revised second paragraph")
            ctx.AMDPAR(u"2. Modify § 111.33 by revising paragraph (c)")
            with ctx.SECTION():
                ctx.SECTNO(u"§ 111.33")
                ctx.SUBJECT("Another Subject")
                ctx.STARS()
                ctx.P("(c) Revised third paragraph")
        ParseAMDPARs().transform(ctx.xml)

        notice = {'cfr_parts': ['111']}
        build.process_amendments(notice, ctx.xml)
        self.assertItemsEqual(notice['changes'].keys(),
                              ['111-22-b', '111-33-c'])
Example #44
0
    def test_process_amendments(self):
        xml = u"""
        <REGTEXT PART="105" TITLE="12">
        <SUBPART>
        <HD SOURCE="HED">Subpart A—General</HD>
        </SUBPART>
        <AMDPAR>
        2. Designate §§ 105.1 through 105.3 as subpart A under the heading.
        </AMDPAR>
        </REGTEXT>"""

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['105']}
        build.process_amendments(notice, notice_xml)

        section_list = ['105-2', '105-3', '105-1']
        self.assertEqual(notice['changes'].keys(), section_list)

        for l, c in notice['changes'].items():
            change = c[0]
            self.assertEqual(change['destination'], ['105', 'Subpart', 'A'])
            self.assertEqual(change['action'], 'DESIGNATE')
Example #45
0
    def test_introductory_text(self):
        """ Sometimes notices change just the introductory text of a paragraph
        (instead of changing the entire paragraph tree).  """

        xml = u"""
        <REGTEXT PART="106" TITLE="12">
        <AMDPAR>
            3. In § 106.2, revise the introductory text to read as follows:
        </AMDPAR>
        <SECTION>
            <SECTNO>§ 106.2</SECTNO>
            <SUBJECT> Definitions </SUBJECT>
            <P> Except as otherwise provided, the following apply. </P>
        </SECTION>
        </REGTEXT>
        """

        notice_xml = etree.fromstring(xml)
        notice = {'cfr_parts': ['106']}
        build.process_amendments(notice, notice_xml)

        self.assertEqual('[text]', notice['changes']['106-2'][0]['field'])
Example #46
0
def parse_rule_changes(document_number):
    """Parse changes present in a single rule.

    DOCUMENT_NUMBER is the identifier associated with a final rule. If a rule
    has been split, use the split identifiers, a.k.a. version ids."""
    rule_entry = entry.RuleChanges(document_number)
    notice_entry = entry.Notice(document_number)

    deps = dependency.Graph()
    deps.add(rule_entry, notice_entry)

    deps.validate_for(rule_entry)
    # We don't check for staleness as we want to always execute when given a
    # specific file to process

    notice_xml = notice_entry.read()
    notice = process_amendments({'cfr_parts': notice_xml.cfr_parts},
                                notice_xml.xml)
    rule_entry.write(notice)