コード例 #1
0
 def test_from_rfc3339_wo_fraction():
     timestamp = "2016-12-20T21:13:47Z"
     expected = datetime_helpers.DatetimeWithNanoseconds(
         2016, 12, 20, 21, 13, 47, tzinfo=pytz.UTC
     )
     stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
     assert stamp == expected
コード例 #2
0
 def test_from_rfc3339_w_partial_precision():
     timestamp = "2016-12-20T21:13:47.1Z"
     expected = datetime_helpers.DatetimeWithNanoseconds(
         2016, 12, 20, 21, 13, 47, microsecond=100000, tzinfo=pytz.UTC
     )
     stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
     assert stamp == expected
コード例 #3
0
 def test_from_rfc3339_w_full_precision():
     timestamp = "2016-12-20T21:13:47.123456789Z"
     expected = datetime_helpers.DatetimeWithNanoseconds(
         2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
     )
     stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
     assert stamp == expected
コード例 #4
0
 def test_timestamp_pb_w_nanos():
     stamp = datetime_helpers.DatetimeWithNanoseconds(
         2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
     )
     delta = stamp - datetime_helpers._UTC_EPOCH
     timestamp = timestamp_pb2.Timestamp(
         seconds=int(delta.total_seconds()), nanos=123456789)
     assert stamp.timestamp_pb() == timestamp
コード例 #5
0
 def test_timestamp_pb_wo_nanos_naive():
     stamp = datetime_helpers.DatetimeWithNanoseconds(
         2016, 12, 20, 21, 13, 47, 123456)
     delta = stamp.replace(tzinfo=pytz.UTC) - datetime_helpers._UTC_EPOCH
     seconds = int(delta.total_seconds())
     nanos = 123456000
     timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)
     assert stamp.timestamp_pb() == timestamp
コード例 #6
0
 def test_rfc3339_w_nanos_w_leading_zero_and_no_trailing_zeros():
     stamp = datetime_helpers.DatetimeWithNanoseconds(2016,
                                                      12,
                                                      20,
                                                      21,
                                                      13,
                                                      47,
                                                      nanosecond=1234500)
     assert stamp.rfc3339() == "2016-12-20T21:13:47.0012345Z"
コード例 #7
0
def test_datetimewithnanos_rfc339_w_nanos():
    stamp = datetime_helpers.DatetimeWithNanoseconds(2016,
                                                     12,
                                                     20,
                                                     21,
                                                     13,
                                                     47,
                                                     nanosecond=123456789)
    assert stamp.rfc3339() == "2016-12-20T21:13:47.123456789Z"
コード例 #8
0
def test_datetimewithnanos_rfc339_w_nanos_no_trailing_zeroes():
    stamp = datetime_helpers.DatetimeWithNanoseconds(2016,
                                                     12,
                                                     20,
                                                     21,
                                                     13,
                                                     47,
                                                     nanosecond=100000000)
    assert stamp.rfc3339() == "2016-12-20T21:13:47.1Z"
コード例 #9
0
 def test_ctor_wo_nanos():
     stamp = datetime_helpers.DatetimeWithNanoseconds(2016, 12, 20, 21, 13, 47, 123456)
     assert stamp.year == 2016
     assert stamp.month == 12
     assert stamp.day == 20
     assert stamp.hour == 21
     assert stamp.minute == 13
     assert stamp.second == 47
     assert stamp.microsecond == 123456
     assert stamp.nanosecond == 0
コード例 #10
0
 def test_ctor_w_micros_positional_and_nanos():
     with pytest.raises(TypeError):
         datetime_helpers.DatetimeWithNanoseconds(2016,
                                                  12,
                                                  20,
                                                  21,
                                                  13,
                                                  47,
                                                  123456,
                                                  nanosecond=123456789)
コード例 #11
0
def test_datetimewithnanos_ctor_w_micros_keyword_and_nanos():
    with pytest.raises(TypeError):
        datetime_helpers.DatetimeWithNanoseconds(2016,
                                                 12,
                                                 20,
                                                 21,
                                                 13,
                                                 47,
                                                 microsecond=123456,
                                                 nanosecond=123456789)
コード例 #12
0
def get_timestamp_with_nanoseconds(timestamp_string):
    from google.api_core import datetime_helpers
    from datetime import datetime

    date_tmp = None
    if "." in timestamp_string:
        date_tmp = datetime.strptime(timestamp_string, '%Y-%m-%d %H:%M:%S.%f')
    else:
        date_tmp = datetime.strptime(timestamp_string, '%Y-%m-%d %H:%M:%S')
    timestamp=datetime_helpers.DatetimeWithNanoseconds(date_tmp.year, date_tmp.month, date_tmp.day, date_tmp.hour, date_tmp.minute, date_tmp.second, date_tmp.microsecond)
    return timestamp
コード例 #13
0
    def test_w_timestamp_w_nanos(self):
        import pytz
        from google.protobuf.struct_pb2 import Value
        from google.api_core import datetime_helpers

        when = datetime_helpers.DatetimeWithNanoseconds(
            2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
        )
        value_pb = self._callFUT(when)
        self.assertIsInstance(value_pb, Value)
        self.assertEqual(value_pb.string_value, when.rfc3339())
コード例 #14
0
    def test_w_timestamp_w_nanos(self):
        import pytz
        from google.api_core import datetime_helpers
        from google.cloud.spanner_v1 import Type
        from google.cloud.spanner_v1 import TypeCode

        field_type = Type(code=TypeCode.TIMESTAMP)
        value = "2016-12-20T21:13:47.123456789Z"
        expected_value = datetime_helpers.DatetimeWithNanoseconds(
            2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC)

        parsed = self._callFUT(value, field_type)
        self.assertIsInstance(parsed, datetime_helpers.DatetimeWithNanoseconds)
        self.assertEqual(parsed, expected_value)
コード例 #15
0
    def test_w_timestamp_w_nanos(self):
        import pytz
        from google.protobuf.struct_pb2 import Value
        from google.api_core import datetime_helpers
        from google.cloud.spanner_v1 import Type
        from google.cloud.spanner_v1 import TypeCode

        value = datetime_helpers.DatetimeWithNanoseconds(
            2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
        )
        field_type = Type(code=TypeCode.TIMESTAMP)
        value_pb = Value(string_value=datetime_helpers.to_rfc3339(value))

        parsed = self._callFUT(value_pb, field_type)
        self.assertIsInstance(parsed, datetime_helpers.DatetimeWithNanoseconds)
        self.assertEqual(parsed, value)
コード例 #16
0
 def test_rfc3339_wo_nanos():
     stamp = datetime_helpers.DatetimeWithNanoseconds(2016, 12, 20, 21, 13, 47, 123456)
     assert stamp.rfc3339() == "2016-12-20T21:13:47.123456Z"
コード例 #17
0
class ConditionTest(
    spanner_emulator_testlib.TestCase,
    parameterized.TestCase,
):

  def setUp(self):
    super().setUp()
    self.run_orm_migrations(
        os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            'migrations_for_emulator_test',
        ))

  @parameterized.parameters(
      (True, type_pb2.Type(code=type_pb2.BOOL)),
      (0, type_pb2.Type(code=type_pb2.INT64)),
      (0.0, type_pb2.Type(code=type_pb2.FLOAT64)),
      (
          datetime_helpers.DatetimeWithNanoseconds(2021, 1, 5),
          type_pb2.Type(code=type_pb2.TIMESTAMP),
      ),
      (datetime.datetime(2021, 1, 5), type_pb2.Type(code=type_pb2.TIMESTAMP)),
      (datetime.date(2021, 1, 5), type_pb2.Type(code=type_pb2.DATE)),
      (b'\x01', type_pb2.Type(code=type_pb2.BYTES)),
      ('foo', type_pb2.Type(code=type_pb2.STRING)),
      (decimal.Decimal('1.23'), type_pb2.Type(code=type_pb2.NUMERIC)),
      (
          (0, 1),
          type_pb2.Type(
              code=type_pb2.ARRAY,
              array_element_type=type_pb2.Type(code=type_pb2.INT64),
          ),
      ),
      (
          ['a', None, 'b'],
          type_pb2.Type(
              code=type_pb2.ARRAY,
              array_element_type=type_pb2.Type(code=type_pb2.STRING),
          ),
      ),
  )
  def test_param_from_value(self, value, expected_type):
    param = condition.Param.from_value(value)
    self.assertEqual(expected_type, param.type)
    # Test that the value and inferred type are compatible. This will raise an
    # exception if they're not.
    self.assertEmpty(
        models.SmallTestModel.where(
            condition.ArbitraryCondition(
                '$param IS NULL',
                dict(param=param),
                segment=condition.Segment.WHERE,
            )))

  @parameterized.parameters(
      (None, 'Cannot infer type of None'),
      ((0, 'some-string'), 'elements of exactly one type'),
      ((0, 'some-string', None), 'elements of exactly one type'),
      (object(), 'Unknown type'),
  )
  def test_param_from_value_error(self, value, error_regex):
    with self.assertRaisesRegex(TypeError, error_regex):
      condition.Param.from_value(value)

  @parameterized.named_parameters(
      (
          'bytes',
          condition.ArbitraryCondition(
              '$param = b"\x01\x02"',
              dict(param=condition.Param.from_value(b'\x01\x02')),
              segment=condition.Segment.WHERE,
          ),
      ),
      (
          'array_of_bytes',
          condition.ArbitraryCondition(
              '${param}[OFFSET(0)] = b"\x01\x02"',
              dict(param=condition.Param.from_value([b'\x01\x02'])),
              segment=condition.Segment.WHERE,
          ),
      ),
      (
          'array_of_bytes_and_null',
          condition.ArbitraryCondition(
              '${param}[OFFSET(0)] IS NULL',
              dict(param=condition.Param.from_value((None, b'\x01\x02'))),
              segment=condition.Segment.WHERE,
          ),
      ),
  )
  def test_param_from_value_correctly_encodes(self, tautology):
    test_model = models.SmallTestModel(
        dict(
            key='some-key',
            value_1='some-value',
            value_2='other-value',
        ))
    test_model.save()
    self.assertCountEqual((test_model,), models.SmallTestModel.where(tautology))

  @parameterized.named_parameters(
      (
          'minimal',
          condition.ArbitraryCondition(
              'FALSE',
              segment=condition.Segment.WHERE,
          ),
          {},
          {},
          'FALSE',
          (),
      ),
      (
          'full',
          condition.ArbitraryCondition(
              '$key = IF($true_param, ${key_param}, $value_1)',
              dict(
                  key=models.SmallTestModel.key,
                  true_param=condition.Param.from_value(True),
                  key_param=condition.Param.from_value('some-key'),
                  value_1=condition.Column('value_1'),
              ),
              segment=condition.Segment.WHERE,
          ),
          dict(
              true_param0=True,
              key_param0='some-key',
          ),
          dict(
              true_param0=type_pb2.Type(code=type_pb2.BOOL),
              key_param0=type_pb2.Type(code=type_pb2.STRING),
          ),
          ('SmallTestModel.key = '
           'IF(@true_param0, @key_param0, SmallTestModel.value_1)'),
          ('some-key',),
      ),
  )
  def test_arbitrary_condition(
      self,
      condition_,
      expected_params,
      expected_types,
      expected_sql,
      expected_row_keys,
  ):
    models.SmallTestModel(
        dict(
            key='some-key',
            value_1='some-value',
            value_2='other-value',
        )).save()
    rows = models.SmallTestModel.where(condition_)
    self.assertEqual(expected_params, condition_.params())
    self.assertEqual(expected_types, condition_.types())
    self.assertEqual(expected_sql, condition_.sql())
    self.assertCountEqual(expected_row_keys, tuple(row.key for row in rows))

  @parameterized.named_parameters(
      ('key_not_found', '$not_found', KeyError, 'not_found'),
      ('invalid_template', '$', ValueError, 'Invalid placeholder'),
  )
  def test_arbitrary_condition_template_error(
      self,
      template,
      error_class,
      error_regex,
  ):
    with self.assertRaisesRegex(error_class, error_regex):
      condition.ArbitraryCondition(template, segment=condition.Segment.WHERE)

  @parameterized.named_parameters(
      (
          'field_from_wrong_model',
          models.ChildTestModel.key,
          'does not belong to the Model',
      ),
      (
          'column_not_found',
          condition.Column('not_found'),
          'does not exist in the Model',
      ),
  )
  def test_arbitrary_condition_validation_error(
      self,
      substitution,
      error_regex,
  ):
    condition_ = condition.ArbitraryCondition(
        '$substitution',
        dict(substitution=substitution),
        segment=condition.Segment.WHERE,
    )
    with self.assertRaisesRegex(error.ValidationError, error_regex):
      models.SmallTestModel.where(condition_)

  @parameterized.named_parameters(
      (
          'empty_or',
          condition.OrCondition(),
          {},
          {},
          'FALSE',
          '',
      ),
      (
          'empty_and',
          condition.OrCondition([]),
          {},
          {},
          '(TRUE)',
          'ab',
      ),
      (
          'single',
          condition.OrCondition(
              [condition.equal_to(models.SmallTestModel.key, 'a')]),
          dict(key0='a'),
          dict(key0=type_pb2.Type(code=type_pb2.STRING)),
          '((SmallTestModel.key = @key0))',
          'a',
      ),
      (
          'multiple',
          condition.OrCondition(
              [
                  condition.equal_to(models.SmallTestModel.key, 'a'),
                  condition.equal_to(models.SmallTestModel.value_1, 'a'),
              ],
              [
                  condition.equal_to(models.SmallTestModel.key, 'b'),
                  condition.equal_to(models.SmallTestModel.value_1, 'b'),
              ],
          ),
          dict(
              key0='a',
              value_11='a',
              key2='b',
              value_13='b',
          ),
          dict(
              key0=type_pb2.Type(code=type_pb2.STRING),
              value_11=type_pb2.Type(code=type_pb2.STRING),
              key2=type_pb2.Type(code=type_pb2.STRING),
              value_13=type_pb2.Type(code=type_pb2.STRING),
          ),
          ('('
           '(SmallTestModel.key = @key0 AND SmallTestModel.value_1 = @value_11)'
           ' OR '
           '(SmallTestModel.key = @key2 AND SmallTestModel.value_1 = @value_13)'
           ')'),
          'ab',
      ),
  )
  def test_or_condition(
      self,
      condition_,
      expected_params,
      expected_types,
      expected_sql,
      expected_row_keys,
  ):
    models.SmallTestModel(dict(key='a', value_1='a', value_2='a')).save()
    models.SmallTestModel(dict(key='b', value_1='b', value_2='b')).save()
    rows = models.SmallTestModel.where(condition_)
    self.assertEqual(expected_params, condition_.params())
    self.assertEqual(expected_types, condition_.types())
    self.assertEqual(expected_sql, condition_.sql())
    self.assertCountEqual(expected_row_keys, tuple(row.key for row in rows))

  @parameterized.parameters(
      ('ABCD', 'BC', True),
      ('ABCD', 'bc', False),
      ('ABCD', 'CB', False),
      (b'ABCD', b'BC', True),
      (b'ABCD', b'bc', False),
      (b'ABCD', b'CB', False),
      ('ABCD', 'BC', True, dict(case_sensitive=False)),
      ('ABCD', 'bc', True, dict(case_sensitive=False)),
      ('ABCD', 'CB', False, dict(case_sensitive=False)),
      (b'ABCD', b'BC', True, dict(case_sensitive=False)),
      (b'ABCD', b'bc', True, dict(case_sensitive=False)),
      (b'ABCD', b'CB', False, dict(case_sensitive=False)),
  )
  def test_contains(
      self,
      haystack,
      needle,
      expect_results,
      kwargs={},
  ):
    test_model = models.SmallTestModel(dict(key='a', value_1='a', value_2='a'))
    test_model.save()
    self.assertCountEqual(
        ((test_model,) if expect_results else ()),
        models.SmallTestModel.where(
            spanner_orm.contains(
                condition.Param.from_value(haystack),
                condition.Param.from_value(needle),
                **kwargs,
            )),
    )
コード例 #18
0
 def test_rfc3339_wo_nanos_w_leading_zero():
     stamp = datetime_helpers.DatetimeWithNanoseconds(2016, 12, 20, 21, 13, 47, 1234)
     assert stamp.rfc3339() == "2016-12-20T21:13:47.001234Z"