Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Range of fixed-length integer generators differs from documentation #32

Open
szktty opened this issue Feb 25, 2024 · 0 comments
Open

Range of fixed-length integer generators differs from documentation #32

szktty opened this issue Feb 25, 2024 · 0 comments

Comments

@szktty
Copy link

szktty commented Feb 25, 2024

Description

The range of integers generated by fixed-length integer generators does not match the documentation, or an assertion error occurs. For example, any.uint8 is supposed to generate integers ranging from 0 to 255 inclusive, but in reality, it generates integers ranging from 0 to 511 inclusive.

The affected generators include:

  • any.uint8
  • any.uint16
  • any.uint32
  • any.int8
  • any.int16
  • any.int32
  • any.int64 (causes an assertion error)

Environment

  • macOS 14.2.1
  • Dart 3.2.6
  • Glados 1.1.7

Current behavior

  • any.uint8 generates integers from 0 (inclusive) to 512 (exclusive).
  • any.uint16 generates integers from 0 (inclusive) to 131072 (exclusive).
  • any.uint32 generates integers from 0 (inclusive) to 8589934592 (exclusive).
  • any.int8 generates integers from -256 (inclusive) to 256 (exclusive).
  • any.int16 generates integers from -65536 (inclusive) to 65536 (exclusive).
  • any.int32 generates integers from -4294967296 (inclusive) to 4294967296 (exclusive).
  • any.int64 is causing an assertion error.

The assertion error caused by using any.int64 is as follows:

00:00 +0 -1: loading test/glados_report_test.dart [E]                       
  Failed to load "test/glados_report_test.dart": 'package:glados/src/anys.dart': Failed assertion: line 27 pos 44: 'min < max': is not true.
  dart:core                           _AssertionError._throwNew
  package:glados/src/anys.dart 27:44  IntAnys.intInRange
  package:glados/src/anys.dart 81:36  IntAnys.int64
  test/glados_report_test.dart 30:14  main

Expected behavior

The range of integers generated by the generators matches the documentation.

  • any.uint8 generates integers from 0 (inclusive) to 256 (exclusive).
  • any.uint16 generates integers from 0 (inclusive) to 65536 (exclusive).
  • any.uint32 generates integers from 0 (inclusive) to 4294967296 (exclusive).
  • any.int8 generates integers from -128 (inclusive) to 128 (exclusive).
  • any.int16 generates integers from -32768 (inclusive) to 32768 (exclusive).
  • any.int32 generates integers from -2147483648 (inclusive) to 2147483648 (exclusive).
  • any.int64 generates integers from -9223372036854775808 (inclusive) to 9223372036854775808 (exclusive).

The current implementation uses a bit shift of 2 where it should use a bit shift of 1. The assertion error when using any.int64 occurs because the specified minimum value -(2 << 63) and the maximum value 2 << 63 both result in 0. Changing from a bit shift of 2 to a bit shift of 1 should fix the issue.

The current implementation is as follows:

https://github.com/MarcelGarus/glados/blob/d86f83ba0701bbed7ec39090f18e737a5893d305/glados/lib/src/anys.dart#L56C1-L81C68

/// A generator that returns [int]s between `0`, inclusive, to `256`, exclusive.
Generator<core.int> get uint8 => intInRange(0, 2 << 8);

/// A generator that returns [int]s between `0`, inclusive, to `65536`,
/// exclusive.
Generator<core.int> get uint16 => intInRange(0, 2 << 16);

/// A generator that returns [int]s between `0`, inclusive, to `4294967296`,
/// exclusive.
Generator<core.int> get uint32 => intInRange(0, 2 << 32);

/// A generator that returns [int]s between `-128`, inclusive, to `128`,
/// exclusive.
Generator<core.int> get int8 => intInRange(-(2 << 7), 2 << 7);

/// A generator that returns [int]s between `-32768`, inclusive, to `32768`,
/// exclusive.
Generator<core.int> get int16 => intInRange(-(2 << 15), 2 << 15);

/// A generator that returns [int]s between `-2147483648`, inclusive, to
/// `2147483648`, exclusive.
Generator<core.int> get int32 => intInRange(-(2 << 31), 2 << 31);

/// A generator that returns [int]s between `-9223372036854775808`, inclusive,
/// to `9223372036854775808`, exclusive.
Generator<core.int> get int64 => intInRange(-(2 << 63), 2 << 63);

The tests are also implemented using the same bit shift expressions, so the tests need to be corrected as well.

Glados(any.uint8).test('uint8', (number) {

Glados(any.uint8).test('uint8', (number) {
  expect(number, greaterThanOrEqualTo(0));
  expect(number, lessThan(2 << 8));
});
Glados(any.uint16).test('uint16', (number) {
  expect(number, greaterThanOrEqualTo(0));
  expect(number, lessThan(2 << 16));
});
Glados(any.uint32).test('uint32', (number) {
  expect(number, greaterThanOrEqualTo(0));
  expect(number, lessThan(2 << 32));
});

Steps to reproduce

Unit tests verifying the range of integers generated by the generators are shown below.

import 'package:glados/glados.dart';

void main() {
  Glados(any.uint8).test('uint8: 0 to 255', (value) {
    expect(0 <= value && value <= 255, true);
  });

  Glados(any.uint16).test('uint16: 0 to 65535', (value) {
    expect(0 <= value && value <= 65535, true);
  });

  Glados(any.uint32).test('uint32: 0 to 4294967294', (value) {
    expect(0 <= value && value <= 4294967295, true);
  });

  Glados(any.int8).test('int8: -128 to 127', (value) {
    expect(-128 <= value && value <= 127, true);
  });

  Glados(any.int16).test('int16: -32768 to 32767', (value) {
    expect(-32768 <= value && value <= 32767, true);
  });

  Glados(any.int32).test('int32: -2147483648 to 2147483647', (value) {
    expect(-2147483648 <= value && value <= 2147483647, true);
  });

  // This code will fail due to an assertion error
  /*
  Glados(any.int64).test('int64: -9223372036854775808 to 9223372036854775807',
      (value) {
    expect(-9223372036854775808 <= value && value <= 9223372036854775807, true);
  });
  */
}

The test results are as follows:

% dart test --no-fail-fast
00:00 +0: loading test/glados_report_test.dart                              
intInRange(0, 0);
00:00 +0: test/glados_report_test.dart: uint8: 0 to 255 (testing 100 inputs)
Tested 2 inputs, shrunk 175 times.
Failing for input: 256
00:00 +0 -1: test/glados_report_test.dart: uint8: 0 to 255 (testing 100 inputs) [E]
  Expected: <true>
    Actual: <false>
  
  package:matcher                        expect
  test/glados_report_test.dart 7:5       main.<fn>
  package:glados/src/glados.dart 178:28  Glados.test.<fn>
  

To run this test again: dart test test/glados_report_test.dart -p vm --plain-name 'uint8: 0 to 255 (testing 100 inputs)'
00:00 +0 -1: test/glados_report_test.dart: uint16: 0 to 65535 (testing 100 inputs)
Tested 2 inputs, shrunk 58799 times.
Failing for input: 65536
00:00 +0 -2: test/glados_report_test.dart: uint16: 0 to 65535 (testing 100 inputs) [E]
  Expected: <true>
    Actual: <false>
  
  package:matcher                        expect
  test/glados_report_test.dart 11:5      main.<fn>
  package:glados/src/glados.dart 178:28  Glados.test.<fn>
  

To run this test again: dart test test/glados_report_test.dart -p vm --plain-name 'uint16: 0 to 65535 (testing 100 inputs)'
00:00 +1 -2: test/glados_report_test.dart: int8: -128 to 127 (testing 100 inputs)
Tested 1 input, shrunk 77 times.
Failing for input: -129
00:00 +1 -3: test/glados_report_test.dart: int8: -128 to 127 (testing 100 inputs) [E]
  Expected: <true>
    Actual: <false>
  
  package:matcher                        expect
  test/glados_report_test.dart 19:5      main.<fn>
  package:glados/src/glados.dart 178:28  Glados.test.<fn>
  

To run this test again: dart test test/glados_report_test.dart -p vm --plain-name 'int8: -128 to 127 (testing 100 inputs)'
00:00 +1 -3: test/glados_report_test.dart: int16: -32768 to 32767 (testing 100 inputs)
Tested 2 inputs, shrunk 26031 times.
Failing for input: 32768
00:00 +1 -4: test/glados_report_test.dart: int16: -32768 to 32767 (testing 100 inputs) [E]
  Expected: <true>
    Actual: <false>
  
  package:matcher                        expect
  test/glados_report_test.dart 23:5      main.<fn>
  package:glados/src/glados.dart 178:28  Glados.test.<fn>
  

To run this test again: dart test test/glados_report_test.dart -p vm --plain-name 'int16: -32768 to 32767 (testing 100 inputs)'
00:08 +1 -4: ... int32: -2147483648 to 2147483647 (testing 100 inputs)      
63:09 +1 -4: test/glados_report_test.dart: int32: -2147483648 to 2147483647 (testing 100 inputs)
Tested 1 input, shrunk 2147483648 times.
Failing for input: -2147483649
63:09 +1 -5: test/glados_report_test.dart: int32: -2147483648 to 2147483647 (testing 100 inputs) [E]
  Expected: <true>
    Actual: <false>
  
  package:matcher                        expect
  test/glados_report_test.dart 27:5      main.<fn>
  package:glados/src/glados.dart 178:28  Glados.test.<fn>
  

To run this test again: dart test test/glados_report_test.dart -p vm --plain-name 'int32: -2147483648 to 2147483647 (testing 100 inputs)'
63:09 +1 -5: Some tests failed.    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant