Repository: peopledoc/workalendar (python)

Issue:
Reformation Day is now in more states (Germany)
https://www.timeanddate.com/holidays/germany/reformation-day

Currently there are 9 states that celebrate it, versus the 5 or so of previous years.  

Pull request description:
Fix Germany Reformation Day computation
closes #295 

- [x] Tests with a significant number of years to be tested for your calendar.
- [x] Changelog amended with a mention describing your changes.


Patch:
diff --git a/Changelog.md b/Changelog.md
index f8dade1..b990df3 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -3,7 +3,7 @@
 ## master (unreleased)
 
 - Added DEEPAVALI days for 2019 and 2020, thx @pvalenti (#282).
-
+- Fixed Germany Reformation Day miscalculation. Some German states include Reformation Day since the "beginning" ; in 2017, all states included Reformation Day as a holiday (500th anniversary of the Reformation) ; starting of 2018, 4 states added Reformation Day (#295).
 
 ## v3.2.0 (2018-11-30)
 
diff --git a/workalendar/europe/germany.py b/workalendar/europe/germany.py
index 723100d..c03551c 100644
--- a/workalendar/europe/germany.py
+++ b/workalendar/europe/germany.py
@@ -20,8 +20,21 @@ class Germany(WesternCalendar, ChristianMixin):
     include_good_friday = True
     include_boxing_day = True
     boxing_day_label = "Second Christmas Day"
-    # German-specific holiday
-    include_reformation_day = False
+
+    # True if including reformation day for all years
+    all_time_include_reformation_day = False
+    # True if including reformation day since 2018
+    include_reformation_day_2018 = False
+
+    def include_reformation_day(self, year):
+        """
+        Return True if the Reformation Day is a holiday.
+        """
+        if self.all_time_include_reformation_day or year == 2017:
+            return True
+        if self.include_reformation_day_2018 and year >= 2018:
+            return True
+        return False
 
     def get_reformation_day(self, year):
         """
@@ -35,7 +48,7 @@ class Germany(WesternCalendar, ChristianMixin):
 
     def get_variable_days(self, year):
         days = super(Germany, self).get_variable_days(year)
-        if self.include_reformation_day or year == 2017:
+        if self.include_reformation_day(year):
             days.append(self.get_reformation_day(year))
         return days
 
@@ -67,19 +80,20 @@ class Berlin(Germany):
 @iso_register('DE-BB')
 class Brandenburg(Germany):
     'Brandenburg'
-
     include_easter_sunday = True
-    include_reformation_day = True
+    all_time_include_reformation_day = True
 
 
 @iso_register('DE-HB')
 class Bremen(Germany):
     'Bremen'
+    include_reformation_day_2018 = True
 
 
 @iso_register('DE-HH')
 class Hamburg(Germany):
     'Hamburg'
+    include_reformation_day_2018 = True
 
 
 @iso_register('DE-HE')
@@ -93,12 +107,13 @@ class Hesse(Germany):
 class MecklenburgVorpommern(Germany):
     'Mecklenburg-Western Pomerania'
 
-    include_reformation_day = True
+    all_time_include_reformation_day = True
 
 
 @iso_register('DE-NI')
 class LowerSaxony(Germany):
     'Lower Saxony'
+    include_reformation_day_2018 = True
 
 
 @iso_register('DE-NW')
@@ -130,7 +145,7 @@ class Saarland(Germany):
 class Saxony(Germany):
     'Saxony'
 
-    include_reformation_day = True
+    all_time_include_reformation_day = True
 
     def get_repentance_day(self, year):
         "Wednesday before November 23"
@@ -150,16 +165,17 @@ class SaxonyAnhalt(Germany):
     'Saxony-Anhalt'
 
     include_epiphany = True
-    include_reformation_day = True
+    all_time_include_reformation_day = True
 
 
 @iso_register('DE-SH')
 class SchleswigHolstein(Germany):
     'Schleswig-Holstein'
+    include_reformation_day_2018 = True
 
 
 @iso_register('DE-TH')
 class Thuringia(Germany):
     'Thuringia'
 
-    include_reformation_day = True
+    all_time_include_reformation_day = True


Test patch:
diff --git a/workalendar/tests/test_europe.py b/workalendar/tests/test_europe.py
index 61e7fc2..26e2247 100644
--- a/workalendar/tests/test_europe.py
+++ b/workalendar/tests/test_europe.py
@@ -36,12 +36,6 @@ from workalendar.europe import Switzerland, Vaud
 from workalendar.europe import UnitedKingdom
 from workalendar.europe import UnitedKingdomNorthernIreland
 from workalendar.europe import EuropeanCentralBank
-from workalendar.europe import (Germany, BadenWurttemberg, Bavaria, Berlin,
-                                Brandenburg, Bremen, Hamburg, Hesse,
-                                MecklenburgVorpommern, LowerSaxony,
-                                NorthRhineWestphalia, RhinelandPalatinate,
-                                Saarland, Saxony, SaxonyAnhalt,
-                                SchleswigHolstein, Thuringia)
 
 
 class AustriaTest(GenericCalendarTest):
@@ -794,264 +788,6 @@ class BelgiumTest(GenericCalendarTest):
         self.assertIn(date(2015, 12, 25), holidays)
 
 
-class GermanyTest(GenericCalendarTest):
-    cal_class = Germany
-
-    def test_year_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 1, 1), holidays)
-        self.assertIn(date(2014, 4, 18), holidays)
-        self.assertIn(date(2014, 4, 21), holidays)
-        self.assertIn(date(2014, 5, 1), holidays)
-        self.assertIn(date(2014, 5, 29), holidays)
-        self.assertIn(date(2014, 6, 9), holidays)
-        self.assertIn(date(2014, 10, 3), holidays)
-        self.assertIn(date(2014, 12, 25), holidays)
-        self.assertIn(date(2014, 12, 26), holidays)
-
-    def test_year_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 1, 1), holidays)
-        self.assertIn(date(2015, 4, 3), holidays)
-        self.assertIn(date(2015, 4, 6), holidays)
-        self.assertIn(date(2015, 5, 1), holidays)
-        self.assertIn(date(2015, 5, 14), holidays)
-        self.assertIn(date(2015, 5, 25), holidays)
-        self.assertIn(date(2015, 10, 3), holidays)
-        self.assertIn(date(2015, 12, 25), holidays)
-        self.assertIn(date(2015, 12, 26), holidays)
-
-    def test_year_reformation_day(self):
-        # Reformation Day is included each year in:
-        # Brandenburg, MecklenburgVorpommern, Saxony, SaxonyAnhalt & Thuringia
-        holidays = self.cal.holidays_set(2015)
-        if self.cal.include_reformation_day:
-            self.assertIn(date(2015, 10, 31), holidays)
-        else:
-            self.assertNotIn(date(2015, 10, 31), holidays)
-        # But in the year 2017, it's included for the whole country
-        holidays = self.cal.holidays_set(2017)
-        self.assertIn(date(2017, 10, 31), holidays)
-
-
-class BadenWurttembergTest(GermanyTest):
-    cal_class = BadenWurttemberg
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 1, 6), holidays)
-        self.assertIn(date(2014, 6, 19), holidays)
-        self.assertIn(date(2014, 11, 1), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 1, 6), holidays)
-        self.assertIn(date(2015, 6, 4), holidays)
-        self.assertIn(date(2015, 11, 1), holidays)
-
-
-class BavariaTest(GenericCalendarTest):
-    cal_class = Bavaria
-
-    def test_year_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 1, 1), holidays)
-        self.assertIn(date(2014, 1, 6), holidays)
-        self.assertIn(date(2014, 4, 18), holidays)
-        self.assertIn(date(2014, 4, 21), holidays)
-        self.assertIn(date(2014, 5, 1), holidays)
-        self.assertIn(date(2014, 5, 29), holidays)
-        self.assertIn(date(2014, 6, 9), holidays)
-        self.assertIn(date(2014, 6, 19), holidays)
-        self.assertIn(date(2014, 8, 15), holidays)
-        self.assertIn(date(2014, 10, 3), holidays)
-        self.assertIn(date(2014, 11, 1), holidays)
-        self.assertIn(date(2014, 12, 25), holidays)
-        self.assertIn(date(2014, 12, 26), holidays)
-
-    def test_year_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 1, 1), holidays)
-        self.assertIn(date(2015, 1, 6), holidays)
-        self.assertIn(date(2015, 4, 3), holidays)
-        self.assertIn(date(2015, 4, 6), holidays)
-        self.assertIn(date(2015, 5, 1), holidays)
-        self.assertIn(date(2015, 5, 14), holidays)
-        self.assertIn(date(2015, 5, 25), holidays)
-        self.assertIn(date(2015, 6, 4), holidays)
-        self.assertIn(date(2015, 8, 15), holidays)
-        self.assertIn(date(2015, 10, 3), holidays)
-        self.assertIn(date(2015, 11, 1), holidays)
-        self.assertIn(date(2015, 12, 25), holidays)
-        self.assertIn(date(2015, 12, 26), holidays)
-
-
-class BerlinTest(GermanyTest):
-    cal_class = Berlin
-
-
-class BrandenburgTest(GenericCalendarTest):
-    cal_class = Brandenburg
-
-    def test_year_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 1, 1), holidays)
-        self.assertIn(date(2014, 4, 18), holidays)
-        self.assertIn(date(2014, 4, 20), holidays)
-        self.assertIn(date(2014, 4, 21), holidays)
-        self.assertIn(date(2014, 5, 1), holidays)
-        self.assertIn(date(2014, 5, 29), holidays)
-        self.assertIn(date(2014, 6, 9), holidays)
-        self.assertIn(date(2014, 10, 3), holidays)
-        self.assertIn(date(2014, 10, 31), holidays)
-        self.assertIn(date(2014, 12, 25), holidays)
-        self.assertIn(date(2014, 12, 26), holidays)
-
-    def test_year_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 1, 1), holidays)
-        self.assertIn(date(2015, 4, 3), holidays)
-        self.assertIn(date(2015, 4, 5), holidays)
-        self.assertIn(date(2015, 4, 6), holidays)
-        self.assertIn(date(2015, 5, 1), holidays)
-        self.assertIn(date(2015, 5, 14), holidays)
-        self.assertIn(date(2015, 5, 25), holidays)
-        self.assertIn(date(2015, 10, 3), holidays)
-        self.assertIn(date(2015, 10, 31), holidays)
-        self.assertIn(date(2015, 12, 25), holidays)
-        self.assertIn(date(2015, 12, 26), holidays)
-
-
-class BremenTest(GermanyTest):
-    cal_class = Bremen
-
-
-class HamburgTest(GermanyTest):
-    cal_class = Hamburg
-
-
-class HesseTest(GermanyTest):
-    cal_class = Hesse
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 6, 19), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 6, 4), holidays)
-
-
-class MecklenburgVorpommernTest(GermanyTest):
-    cal_class = MecklenburgVorpommern
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 10, 31), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 10, 31), holidays)
-
-
-class LowerSaxonyTest(GermanyTest):
-    cal_class = LowerSaxony
-
-
-class NorthRhineWestphaliaTest(GermanyTest):
-    cal_class = NorthRhineWestphalia
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 6, 19), holidays)
-        self.assertIn(date(2014, 11, 1), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 6, 4), holidays)
-        self.assertIn(date(2015, 11, 1), holidays)
-
-
-class RhinelandPalatinateTest(GermanyTest):
-    cal_class = RhinelandPalatinate
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 6, 19), holidays)
-        self.assertIn(date(2014, 11, 1), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 6, 4), holidays)
-        self.assertIn(date(2015, 11, 1), holidays)
-
-
-class SaarlandTest(GermanyTest):
-    cal_class = Saarland
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 6, 19), holidays)
-        self.assertIn(date(2014, 8, 15), holidays)
-        self.assertIn(date(2014, 11, 1), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 6, 4), holidays)
-        self.assertIn(date(2015, 8, 15), holidays)
-        self.assertIn(date(2015, 11, 1), holidays)
-
-
-class SaxonyTest(GermanyTest):
-    cal_class = Saxony
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 11, 19), holidays)
-        self.assertIn(date(2014, 10, 31), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 11, 18), holidays)
-        self.assertIn(date(2015, 10, 31), holidays)
-
-    def test_extra_2016(self):
-        holidays = self.cal.holidays_set(2016)
-        self.assertIn(date(2016, 11, 16), holidays)
-        self.assertNotIn(date(2016, 11, 23), holidays)
-        self.assertIn(date(2016, 10, 31), holidays)
-
-
-class SaxonyAnhaltTest(GermanyTest):
-    cal_class = SaxonyAnhalt
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 10, 31), holidays)
-        self.assertIn(date(2014, 1, 6), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 10, 31), holidays)
-        self.assertIn(date(2015, 1, 6), holidays)
-
-
-class SchleswigHolsteinTest(GermanyTest):
-    cal_class = SchleswigHolstein
-
-
-class ThuringiaTest(GermanyTest):
-    cal_class = Thuringia
-
-    def test_extra_2014(self):
-        holidays = self.cal.holidays_set(2014)
-        self.assertIn(date(2014, 10, 31), holidays)
-
-    def test_extra_2015(self):
-        holidays = self.cal.holidays_set(2015)
-        self.assertIn(date(2015, 10, 31), holidays)
-
-
 class PortugalTest(GenericCalendarTest):
     cal_class = Portugal
 
diff --git a/workalendar/tests/test_germany.py b/workalendar/tests/test_germany.py
new file mode 100644
index 0000000..5ef1e7f
--- /dev/null
+++ b/workalendar/tests/test_germany.py
@@ -0,0 +1,293 @@
+from datetime import date
+from unittest import TestCase
+
+from workalendar.tests import GenericCalendarTest
+from workalendar.europe import (Germany, BadenWurttemberg, Bavaria, Berlin,
+                                Brandenburg, Bremen, Hamburg, Hesse,
+                                MecklenburgVorpommern, LowerSaxony,
+                                NorthRhineWestphalia, RhinelandPalatinate,
+                                Saarland, Saxony, SaxonyAnhalt,
+                                SchleswigHolstein, Thuringia)
+
+
+class ReformationFlagTest(TestCase):
+    def test_flags_reformation_day(self):
+        klasses = (
+            BadenWurttemberg, Bavaria, Berlin, Brandenburg, Bremen, Hamburg,
+            Hesse, MecklenburgVorpommern, LowerSaxony, NorthRhineWestphalia,
+            RhinelandPalatinate, Saarland, Saxony, SaxonyAnhalt,
+            SchleswigHolstein, Thuringia
+        )
+        for klass in klasses:
+            if klass in (Bremen, Hamburg, LowerSaxony, SchleswigHolstein):
+                self.assertTrue(klass.include_reformation_day_2018)
+            else:
+                self.assertFalse(klass.include_reformation_day_2018)
+
+
+class GermanyTest(GenericCalendarTest):
+    cal_class = Germany
+
+    def test_year_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 1, 1), holidays)
+        self.assertIn(date(2014, 4, 18), holidays)
+        self.assertIn(date(2014, 4, 21), holidays)
+        self.assertIn(date(2014, 5, 1), holidays)
+        self.assertIn(date(2014, 5, 29), holidays)
+        self.assertIn(date(2014, 6, 9), holidays)
+        self.assertIn(date(2014, 10, 3), holidays)
+        self.assertIn(date(2014, 12, 25), holidays)
+        self.assertIn(date(2014, 12, 26), holidays)
+
+    def test_year_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 1, 1), holidays)
+        self.assertIn(date(2015, 4, 3), holidays)
+        self.assertIn(date(2015, 4, 6), holidays)
+        self.assertIn(date(2015, 5, 1), holidays)
+        self.assertIn(date(2015, 5, 14), holidays)
+        self.assertIn(date(2015, 5, 25), holidays)
+        self.assertIn(date(2015, 10, 3), holidays)
+        self.assertIn(date(2015, 12, 25), holidays)
+        self.assertIn(date(2015, 12, 26), holidays)
+
+    def test_year_reformation_day(self):
+        # Reformation Day is included each year in:
+        # Brandenburg, MecklenburgVorpommern, Saxony, SaxonyAnhalt & Thuringia
+        holidays = self.cal.holidays_set(2015)
+        if self.cal.include_reformation_day(2015):
+            self.assertIn(date(2015, 10, 31), holidays)
+        else:
+            self.assertNotIn(date(2015, 10, 31), holidays)
+
+        # But in the year 2017, it's included for the whole country
+        holidays = self.cal.holidays_set(2017)
+        self.assertTrue(self.cal.include_reformation_day(2017))
+        self.assertIn(date(2017, 10, 31), holidays)
+
+        # In 2018, Four more states have added it:
+        # Bremen, Hamburg, Lower Saxony and Schleswig-Holstein
+        holidays = self.cal.holidays_set(2018)
+        if self.cal.include_reformation_day(2018):
+            self.assertIn(date(2018, 10, 31), holidays)
+        else:
+            self.assertNotIn(date(2018, 10, 31), holidays)
+
+
+class BadenWurttembergTest(GermanyTest):
+    cal_class = BadenWurttemberg
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 1, 6), holidays)
+        self.assertIn(date(2014, 6, 19), holidays)
+        self.assertIn(date(2014, 11, 1), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 1, 6), holidays)
+        self.assertIn(date(2015, 6, 4), holidays)
+        self.assertIn(date(2015, 11, 1), holidays)
+
+
+class BavariaTest(GenericCalendarTest):
+    cal_class = Bavaria
+
+    def test_year_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 1, 1), holidays)
+        self.assertIn(date(2014, 1, 6), holidays)
+        self.assertIn(date(2014, 4, 18), holidays)
+        self.assertIn(date(2014, 4, 21), holidays)
+        self.assertIn(date(2014, 5, 1), holidays)
+        self.assertIn(date(2014, 5, 29), holidays)
+        self.assertIn(date(2014, 6, 9), holidays)
+        self.assertIn(date(2014, 6, 19), holidays)
+        self.assertIn(date(2014, 8, 15), holidays)
+        self.assertIn(date(2014, 10, 3), holidays)
+        self.assertIn(date(2014, 11, 1), holidays)
+        self.assertIn(date(2014, 12, 25), holidays)
+        self.assertIn(date(2014, 12, 26), holidays)
+
+    def test_year_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 1, 1), holidays)
+        self.assertIn(date(2015, 1, 6), holidays)
+        self.assertIn(date(2015, 4, 3), holidays)
+        self.assertIn(date(2015, 4, 6), holidays)
+        self.assertIn(date(2015, 5, 1), holidays)
+        self.assertIn(date(2015, 5, 14), holidays)
+        self.assertIn(date(2015, 5, 25), holidays)
+        self.assertIn(date(2015, 6, 4), holidays)
+        self.assertIn(date(2015, 8, 15), holidays)
+        self.assertIn(date(2015, 10, 3), holidays)
+        self.assertIn(date(2015, 11, 1), holidays)
+        self.assertIn(date(2015, 12, 25), holidays)
+        self.assertIn(date(2015, 12, 26), holidays)
+
+
+class BerlinTest(GermanyTest):
+    cal_class = Berlin
+
+
+class BrandenburgTest(GenericCalendarTest):
+    cal_class = Brandenburg
+
+    def test_year_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 1, 1), holidays)
+        self.assertIn(date(2014, 4, 18), holidays)
+        self.assertIn(date(2014, 4, 20), holidays)
+        self.assertIn(date(2014, 4, 21), holidays)
+        self.assertIn(date(2014, 5, 1), holidays)
+        self.assertIn(date(2014, 5, 29), holidays)
+        self.assertIn(date(2014, 6, 9), holidays)
+        self.assertIn(date(2014, 10, 3), holidays)
+        self.assertIn(date(2014, 10, 31), holidays)
+        self.assertIn(date(2014, 12, 25), holidays)
+        self.assertIn(date(2014, 12, 26), holidays)
+
+    def test_year_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 1, 1), holidays)
+        self.assertIn(date(2015, 4, 3), holidays)
+        self.assertIn(date(2015, 4, 5), holidays)
+        self.assertIn(date(2015, 4, 6), holidays)
+        self.assertIn(date(2015, 5, 1), holidays)
+        self.assertIn(date(2015, 5, 14), holidays)
+        self.assertIn(date(2015, 5, 25), holidays)
+        self.assertIn(date(2015, 10, 3), holidays)
+        self.assertIn(date(2015, 10, 31), holidays)
+        self.assertIn(date(2015, 12, 25), holidays)
+        self.assertIn(date(2015, 12, 26), holidays)
+
+
+class BremenTest(GermanyTest):
+    cal_class = Bremen
+
+
+class HamburgTest(GermanyTest):
+    cal_class = Hamburg
+
+
+class HesseTest(GermanyTest):
+    cal_class = Hesse
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 6, 19), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 6, 4), holidays)
+
+
+class MecklenburgVorpommernTest(GermanyTest):
+    cal_class = MecklenburgVorpommern
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 10, 31), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 10, 31), holidays)
+
+
+class LowerSaxonyTest(GermanyTest):
+    cal_class = LowerSaxony
+
+
+class NorthRhineWestphaliaTest(GermanyTest):
+    cal_class = NorthRhineWestphalia
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 6, 19), holidays)
+        self.assertIn(date(2014, 11, 1), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 6, 4), holidays)
+        self.assertIn(date(2015, 11, 1), holidays)
+
+
+class RhinelandPalatinateTest(GermanyTest):
+    cal_class = RhinelandPalatinate
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 6, 19), holidays)
+        self.assertIn(date(2014, 11, 1), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 6, 4), holidays)
+        self.assertIn(date(2015, 11, 1), holidays)
+
+
+class SaarlandTest(GermanyTest):
+    cal_class = Saarland
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 6, 19), holidays)
+        self.assertIn(date(2014, 8, 15), holidays)
+        self.assertIn(date(2014, 11, 1), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 6, 4), holidays)
+        self.assertIn(date(2015, 8, 15), holidays)
+        self.assertIn(date(2015, 11, 1), holidays)
+
+
+class SaxonyTest(GermanyTest):
+    cal_class = Saxony
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 11, 19), holidays)
+        self.assertIn(date(2014, 10, 31), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 11, 18), holidays)
+        self.assertIn(date(2015, 10, 31), holidays)
+
+    def test_extra_2016(self):
+        holidays = self.cal.holidays_set(2016)
+        self.assertIn(date(2016, 11, 16), holidays)
+        self.assertNotIn(date(2016, 11, 23), holidays)
+        self.assertIn(date(2016, 10, 31), holidays)
+
+
+class SaxonyAnhaltTest(GermanyTest):
+    cal_class = SaxonyAnhalt
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 10, 31), holidays)
+        self.assertIn(date(2014, 1, 6), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 10, 31), holidays)
+        self.assertIn(date(2015, 1, 6), holidays)
+
+
+class SchleswigHolsteinTest(GermanyTest):
+    cal_class = SchleswigHolstein
+
+
+class ThuringiaTest(GermanyTest):
+    cal_class = Thuringia
+
+    def test_extra_2014(self):
+        holidays = self.cal.holidays_set(2014)
+        self.assertIn(date(2014, 10, 31), holidays)
+
+    def test_extra_2015(self):
+        holidays = self.cal.holidays_set(2015)
+        self.assertIn(date(2015, 10, 31), holidays)