import dimod

from collections import Mapping

__all__ = ['SamplerAPITestCaseMixin']


class SamplerAPITestCaseMixin(object):
    """Provides a series of generic API tests that all samplers should pass.
    """
    def test_instantiation(self):
        sampler = self.sampler_factory()

        # check that is has all of the expected attritubes
        self.assertTrue(hasattr(sampler, 'sample'),
                        "sampler must have a 'sample' method")
        self.assertTrue(callable(sampler.sample),
                        "sampler must have a 'sample' method")

        self.assertTrue(hasattr(sampler, 'sample_ising'),
                        "sampler must have a 'sample_ising' method")
        self.assertTrue(callable(sampler.sample_ising),
                        "sampler must have a 'sample_ising' method")

        self.assertTrue(hasattr(sampler, 'sample_qubo'),
                        "sampler must have a 'sample_qubo' method")
        self.assertTrue(callable(sampler.sample_qubo),
                        "sampler must have a 'sample_qubo' method")

        self.assertTrue(hasattr(sampler, 'sample_kwargs'),
                        "sampler must have a 'sample_kwargs' property")

        self.assertTrue(hasattr(sampler, 'properties'),
                        "sampler must have a 'properties' property")
        self.assertTrue(isinstance(sampler.properties, dict),
                        "sampler's 'properties' property should be a dict")

    def test_sample_response_form(self):
        sampler = self.sampler_factory()

        bqm = dimod.BinaryQuadraticModel({'b': 2}, {('a', 'b'): -1.}, 1.0, dimod.SPIN)

        try:
            response = sampler.sample(bqm)
        except dimod.exceptions.BinaryQuadraticModelValueError:
            return  # the sampler has responded that it cannot handle the give bqm

        self.assertIs(response.vartype, bqm.vartype, "response's vartype does not match the bqm's vartype")

        for sample in response:
            self.assertIsInstance(sample, Mapping, "'for sample in response', each sample should be a Mapping")
            for v, value in sample.items():
                self.assertIn(v, bqm.linear, 'sample contains a variable not in the given bqm')
                self.assertIn(value, bqm.vartype.value, 'sample contains a value not of the correct type')

                for v in bqm.linear:
                    self.assertIn(v, sample)

@@ -221,21 +221,30 @@
 est_
-instantiation
+properties_and_methods
 (sel
@@ -1071,32 +1071,54 @@
 qubo' method%22)%0A%0A
+        # properties%0A%0A
         self.ass
@@ -1147,25 +1147,147 @@
 r, '
-sample_kwargs'
+parameters'),%0A                        %22sampler must have a 'parameters' property%22)%0A        self.assertFalse(callable(sampler.parameters
 ),%0A
+ 
     
@@ -1332,20 +1332,17 @@
  a '
-sample_kwarg
+parameter
 s' p
@@ -1350,16 +1350,72 @@
 operty%22)
+%0A        self.assertIsInstance(sampler.parameters, dict)
 %0A%0A      
@@ -1556,22 +1556,21 @@
 sert
-True(isinstanc
+False(callabl
 e(sa
@@ -1589,17 +1589,12 @@
 ties
-, dict
 ),%0A
+ 
     
@@ -1621,18 +1621,28 @@
 %22sampler
-'s
+ must have a
  'proper
@@ -1659,32 +1659,73 @@
 erty
- should be a
+%22)%0A        self.assertIsInstance(sampler.properties,
  dict
-%22
 )%0A%0A   
+ #
  def
@@ -1753,32 +1753,34 @@
 _form(self):%0A   
+ #
      sampler = s
@@ -1801,24 +1801,26 @@
 ctory()%0A%0A   
+ #
      bqm = d
@@ -1891,24 +1891,26 @@
 d.SPIN)%0A%0A   
+ #
      try:%0A  
@@ -1911,24 +1911,25 @@
 ry:%0A    
+#
         
 response
@@ -1920,16 +1920,17 @@
         
+ 
 response
@@ -1951,24 +1951,26 @@
 ple(bqm)%0A   
+ #
      except 
@@ -2017,24 +2017,26 @@
 ueError:%0A   
+ #
          ret
@@ -2104,28 +2104,30 @@
 ve bqm%0A%0A    
+#
     
+ 
 self.assertI
@@ -2214,24 +2214,26 @@
 rtype%22)%0A%0A   
+ #
      for sam
@@ -2248,24 +2248,26 @@
 esponse:%0A   
+ #
          sel
@@ -2362,24 +2362,26 @@
 apping%22)%0A   
+ #
          for
@@ -2408,24 +2408,26 @@
 items():%0A   
+ #
             
@@ -2507,24 +2507,25 @@
 n bqm')%0A    
+#
             
@@ -2516,32 +2516,33 @@
    #            
+ 
 self.assertIn(va
@@ -2616,24 +2616,26 @@
  type')%0A%0A   
+ #
             
@@ -2655,24 +2655,26 @@
 .linear:%0A   
+ #
             

Update APItests to reflect new Sampler abc