~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-02-24 13:55:32 UTC
  • mfrom: (5549.1.33 expand-options)
  • Revision ID: pqm@pqm.ubuntu.com-20110224135532-b5zu78in53r1ptc1
(vila) Add the opt-in ability to expand options in config files (Vincent
 Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
540
540
            ' Use IniBasedConfig(_content=xxx) instead.'],
541
541
            conf._get_parser, file=config_file)
542
542
 
 
543
 
543
544
class TestIniConfigSaving(tests.TestCaseInTempDir):
544
545
 
545
546
    def test_cant_save_without_a_file_name(self):
553
554
        self.assertFileEqual(content, 'test.conf')
554
555
 
555
556
 
 
557
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
 
558
    """What is the default value of expand for config options.
 
559
 
 
560
    This is an opt-in beta feature used to evaluate whether or not option
 
561
    references can appear in dangerous place raising exceptions, disapearing
 
562
    (and as such corrupting data) or if it's safe to activate the option by
 
563
    default.
 
564
 
 
565
    Note that these tests relies on config._expand_default_value being already
 
566
    overwritten in the parent class setUp.
 
567
    """
 
568
 
 
569
    def setUp(self):
 
570
        super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
 
571
        self.config = None
 
572
        self.warnings = []
 
573
        def warning(*args):
 
574
            self.warnings.append(args[0] % args[1:])
 
575
        self.overrideAttr(trace, 'warning', warning)
 
576
 
 
577
    def get_config(self, expand):
 
578
        c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
 
579
                                            save=True)
 
580
        return c
 
581
 
 
582
    def assertExpandIs(self, expected):
 
583
        actual = config._get_expand_default_value()
 
584
        #self.config.get_user_option_as_bool('bzr.config.expand')
 
585
        self.assertEquals(expected, actual)
 
586
 
 
587
    def test_default_is_None(self):
 
588
        self.assertEquals(None, config._expand_default_value)
 
589
 
 
590
    def test_default_is_False_even_if_None(self):
 
591
        self.config = self.get_config(None)
 
592
        self.assertExpandIs(False)
 
593
 
 
594
    def test_default_is_False_even_if_invalid(self):
 
595
        self.config = self.get_config('<your choice>')
 
596
        self.assertExpandIs(False)
 
597
        # ...
 
598
        # Huh ? My choice is False ? Thanks, always happy to hear that :D
 
599
        # Wait, you've been warned !
 
600
        self.assertLength(1, self.warnings)
 
601
        self.assertEquals(
 
602
            'Value "<your choice>" is not a boolean for "bzr.config.expand"',
 
603
            self.warnings[0])
 
604
 
 
605
    def test_default_is_True(self):
 
606
        self.config = self.get_config(True)
 
607
        self.assertExpandIs(True)
 
608
        
 
609
    def test_default_is_False(self):
 
610
        self.config = self.get_config(False)
 
611
        self.assertExpandIs(False)
 
612
        
 
613
 
 
614
class TestIniConfigOptionExpansion(tests.TestCase):
 
615
    """Test option expansion from the IniConfig level.
 
616
 
 
617
    What we really want here is to test the Config level, but the class being
 
618
    abstract as far as storing values is concerned, this can't be done
 
619
    properly (yet).
 
620
    """
 
621
    # FIXME: This should be rewritten when all configs share a storage
 
622
    # implementation -- vila 2011-02-18
 
623
 
 
624
    def get_config(self, string=None):
 
625
        if string is None:
 
626
            string = ''
 
627
        c = config.IniBasedConfig.from_string(string)
 
628
        return c
 
629
 
 
630
    def assertExpansion(self, expected, conf, string, env=None):
 
631
        self.assertEquals(expected, conf.expand_options(string, env))
 
632
 
 
633
    def test_no_expansion(self):
 
634
        c = self.get_config('')
 
635
        self.assertExpansion('foo', c, 'foo')
 
636
 
 
637
    def test_env_adding_options(self):
 
638
        c = self.get_config('')
 
639
        self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
 
640
 
 
641
    def test_env_overriding_options(self):
 
642
        c = self.get_config('foo=baz')
 
643
        self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
 
644
 
 
645
    def test_simple_ref(self):
 
646
        c = self.get_config('foo=xxx')
 
647
        self.assertExpansion('xxx', c, '{foo}')
 
648
 
 
649
    def test_unknown_ref(self):
 
650
        c = self.get_config('')
 
651
        self.assertRaises(errors.ExpandingUnknownOption,
 
652
                          c.expand_options, '{foo}')
 
653
 
 
654
    def test_indirect_ref(self):
 
655
        c = self.get_config('''
 
656
foo=xxx
 
657
bar={foo}
 
658
''')
 
659
        self.assertExpansion('xxx', c, '{bar}')
 
660
 
 
661
    def test_embedded_ref(self):
 
662
        c = self.get_config('''
 
663
foo=xxx
 
664
bar=foo
 
665
''')
 
666
        self.assertExpansion('xxx', c, '{{bar}}')
 
667
 
 
668
    def test_simple_loop(self):
 
669
        c = self.get_config('foo={foo}')
 
670
        self.assertRaises(errors.OptionExpansionLoop, c.expand_options, '{foo}')
 
671
 
 
672
    def test_indirect_loop(self):
 
673
        c = self.get_config('''
 
674
foo={bar}
 
675
bar={baz}
 
676
baz={foo}''')
 
677
        e = self.assertRaises(errors.OptionExpansionLoop,
 
678
                              c.expand_options, '{foo}')
 
679
        self.assertEquals('foo->bar->baz', e.refs)
 
680
        self.assertEquals('{foo}', e.string)
 
681
 
 
682
    def test_list(self):
 
683
        conf = self.get_config('''
 
684
foo=start
 
685
bar=middle
 
686
baz=end
 
687
list={foo},{bar},{baz}
 
688
''')
 
689
        self.assertEquals(['start', 'middle', 'end'],
 
690
                           conf.get_user_option('list', expand=True))
 
691
 
 
692
    def test_cascading_list(self):
 
693
        conf = self.get_config('''
 
694
foo=start,{bar}
 
695
bar=middle,{baz}
 
696
baz=end
 
697
list={foo}
 
698
''')
 
699
        self.assertEquals(['start', 'middle', 'end'],
 
700
                           conf.get_user_option('list', expand=True))
 
701
 
 
702
    def test_pathological_hidden_list(self):
 
703
        conf = self.get_config('''
 
704
foo=bin
 
705
bar=go
 
706
start={foo
 
707
middle=},{
 
708
end=bar}
 
709
hidden={start}{middle}{end}
 
710
''')
 
711
        # Nope, it's either a string or a list, and the list wins as soon as a
 
712
        # ',' appears, so the string concatenation never occur.
 
713
        self.assertEquals(['{foo', '}', '{', 'bar}'],
 
714
                          conf.get_user_option('hidden', expand=True))
 
715
 
 
716
class TestLocationConfigOptionExpansion(tests.TestCaseInTempDir):
 
717
 
 
718
    def get_config(self, location, string=None):
 
719
        if string is None:
 
720
            string = ''
 
721
        # Since we don't save the config we won't strictly require to inherit
 
722
        # from TestCaseInTempDir, but an error occurs so quickly...
 
723
        c = config.LocationConfig.from_string(string, location)
 
724
        return c
 
725
 
 
726
    def test_dont_cross_unrelated_section(self):
 
727
        c = self.get_config('/another/branch/path','''
 
728
[/one/branch/path]
 
729
foo = hello
 
730
bar = {foo}/2
 
731
 
 
732
[/another/branch/path]
 
733
bar = {foo}/2
 
734
''')
 
735
        self.assertRaises(errors.ExpandingUnknownOption,
 
736
                          c.get_user_option, 'bar', expand=True)
 
737
 
 
738
    def test_cross_related_sections(self):
 
739
        c = self.get_config('/project/branch/path','''
 
740
[/project]
 
741
foo = qu
 
742
 
 
743
[/project/branch/path]
 
744
bar = {foo}ux
 
745
''')
 
746
        self.assertEquals('quux', c.get_user_option('bar', expand=True))
 
747
 
 
748
 
556
749
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
557
750
 
558
751
    def test_cannot_reload_without_name(self):
1011
1204
        conf = self._get_empty_config()
1012
1205
        cmdline = conf.find_merge_tool('kdiff3')
1013
1206
        self.assertEquals('kdiff3 {base} {this} {other} -o {result}', cmdline)
1014
 
        
 
1207
 
1015
1208
    def test_find_merge_tool_override_known(self):
1016
1209
        conf = self._get_empty_config()
1017
1210
        conf.set_user_option('bzr.mergetool.kdiff3', 'kdiff3 blah')