Skip to content

Commit

Permalink
all-your-base: sync
Browse files Browse the repository at this point in the history
  • Loading branch information
senekor committed Aug 9, 2024
1 parent 2a66d7d commit c755111
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 20 deletions.
1 change: 1 addition & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ There are some custom tera filters in [`rust-tooling`](/rust-tooling/generate/sr
Here's the hopefully up-to-date list:
- `to_hex` formats ints in hexadecimal
- `snake_case` massages an arbitrary string into a decent Rust identifier
- `make_test_ident` is like snake case, but prepends `test_` if the string starts with a digit

Feel free to add your own in the crate `rust-tooling`.
Hopefully you'll remember to update the list here as well. 🙂
Expand Down
26 changes: 26 additions & 0 deletions exercises/practice/all-your-base/.meta/test_template.tera
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use allyourbase as ayb;

{% for test in cases %}
#[test]
#[ignore]
fn {{ test.description | make_test_ident }}() {
let input_base = {{ test.input.inputBase }};
let input_digits = &{{ test.input.digits | json_encode() }};
let output_base = {{ test.input.outputBase }};
{%- if not test.expected is object %}
let output_digits = vec!{{ test.expected | json_encode() }};
{%- endif %}
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
{%- if not test.expected is object %}
Ok(output_digits)
{%- elif test.expected.error == "input base must be >= 2" %}
Err(ayb::Error::InvalidInputBase)
{%- elif test.expected.error == "all digits must satisfy 0 <= d < input base" %}
Err(ayb::Error::InvalidDigit(2))
{%- elif test.expected.error == "output base must be >= 2" %}
Err(ayb::Error::InvalidOutputBase)
{%- endif %}
);
}
{% endfor -%}
36 changes: 33 additions & 3 deletions exercises/practice/all-your-base/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[5ce422f9-7a4b-4f44-ad29-49c67cb32d2c]
description = "single bit one to decimal"
Expand All @@ -23,6 +30,9 @@ description = "trinary to hexadecimal"
[d3901c80-8190-41b9-bd86-38d988efa956]
description = "hexadecimal to trinary"

[5d42f85e-21ad-41bd-b9be-a3e8e4258bbf]
description = "15-bit integer"

[d68788f7-66dd-43f8-a543-f15b6d233f83]
description = "empty list"

Expand All @@ -41,6 +51,16 @@ description = "input base is one"
[e21a693a-7a69-450b-b393-27415c26a016]
description = "input base is zero"

[54a23be5-d99e-41cc-88e0-a650ffe5fcc2]
description = "input base is negative"
include = false
comment = "we use unsigned integers"

[9eccf60c-dcc9-407b-95d8-c37b8be56bb6]
description = "negative digit"
include = false
comment = "we use unsigned integers"

[232fa4a5-e761-4939-ba0c-ed046cd0676a]
description = "invalid positive digit"

Expand All @@ -49,3 +69,13 @@ description = "output base is one"

[73dac367-da5c-4a37-95fe-c87fad0a4047]
description = "output base is zero"

[13f81f42-ff53-4e24-89d9-37603a48ebd9]
description = "output base is negative"
include = false
comment = "we use unsigned integers"

[0e6c895d-8a5d-4868-a345-309d094cfe8d]
description = "both bases are negative"
include = false
comment = "we use unsigned integers"
32 changes: 16 additions & 16 deletions exercises/practice/all-your-base/tests/all-your-base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn hexadecimal_to_trinary() {

#[test]
#[ignore]
fn fifteen_bit_integer() {
fn test_15_bit_integer() {
let input_base = 97;
let input_digits = &[3, 46, 60];
let output_base = 73;
Expand Down Expand Up @@ -157,20 +157,20 @@ fn leading_zeros() {

#[test]
#[ignore]
fn invalid_positive_digit() {
let input_base = 2;
let input_digits = &[1, 2, 1, 0, 1, 0];
fn input_base_is_one() {
let input_base = 1;
let input_digits = &[0];
let output_base = 10;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidDigit(2))
Err(ayb::Error::InvalidInputBase)
);
}

#[test]
#[ignore]
fn input_base_is_one() {
let input_base = 1;
fn input_base_is_zero() {
let input_base = 0;
let input_digits = &[];
let output_base = 10;
assert_eq!(
Expand All @@ -181,25 +181,25 @@ fn input_base_is_one() {

#[test]
#[ignore]
fn output_base_is_one() {
fn invalid_positive_digit() {
let input_base = 2;
let input_digits = &[1, 0, 1, 0, 1, 0];
let output_base = 1;
let input_digits = &[1, 2, 1, 0, 1, 0];
let output_base = 10;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidOutputBase)
Err(ayb::Error::InvalidDigit(2))
);
}

#[test]
#[ignore]
fn input_base_is_zero() {
let input_base = 0;
let input_digits = &[];
let output_base = 10;
fn output_base_is_one() {
let input_base = 2;
let input_digits = &[1, 0, 1, 0, 1, 0];
let output_base = 1;
assert_eq!(
ayb::convert(input_digits, input_base, output_base),
Err(ayb::Error::InvalidInputBase)
Err(ayb::Error::InvalidOutputBase)
);
}

Expand Down
21 changes: 20 additions & 1 deletion rust-tooling/generate/src/custom_filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use tera::{Result, Value};

type Filter = fn(&Value, &HashMap<String, Value>) -> Result<Value>;

pub static CUSTOM_FILTERS: &[(&str, Filter)] = &[("to_hex", to_hex), ("snake_case", snake_case)];
pub static CUSTOM_FILTERS: &[(&str, Filter)] = &[
("to_hex", to_hex),
("snake_case", snake_case),
("make_test_ident", make_test_ident),
];

pub fn to_hex(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
let Some(value) = value.as_u64() else {
Expand All @@ -28,3 +32,18 @@ pub fn snake_case(value: &Value, _args: &HashMap<String, Value>) -> Result<Value
slug::slugify(value).replace('-', "_"),
))
}

pub fn make_test_ident(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
let value = snake_case(value, _args)?;
let Some(value) = value.as_str() else {
return Err(tera::Error::call_filter(
"make_test_ident filter expects a string",
"serde_json::value::Value::as_str",
));
};
if !value.chars().next().unwrap_or_default().is_alphabetic() {
// identifiers cannot start with digits etc.
return Ok(Value::String(format!("test_{value}")));
}
Ok(Value::String(value.into()))
}

0 comments on commit c755111

Please sign in to comment.