Skip to content
This repository has been archived by the owner on Jul 6, 2019. It is now read-only.

Commit

Permalink
Merge pull request #128 from bgamari/ioreg-test
Browse files Browse the repository at this point in the history
Add rudimentary tests for ioreg

Reviewed-by:
  • Loading branch information
hacknbot committed Aug 18, 2014
2 parents 2af9fe6 + 11b6e7a commit 4e0b234
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 39 deletions.
17 changes: 16 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ Context.create(__FILE__, ENV['PLATFORM'])

provide_stdlibs

# shiny
compile_rust :shiny_crate, {
source: 'thirdparty/shiny/src/lib.rs'.in_root,
produce: 'thirdparty/shiny/src/lib.rs'.in_root.as_rlib.in_build,
out_dir: true,
build_for: :host,
}

# tests
desc "Run tests"
task :test
Expand Down Expand Up @@ -50,6 +58,12 @@ compile_rust :macro_ioreg, {
build_for: :host,
}

rust_tests :ioreg_test, {
source: 'ioreg/test.rs'.in_root,
deps: [:core_crate, :macro_ioreg, :shiny_crate],
produce: 'ioreg_test'.in_build,
}

# zinc crate
compile_rust :zinc_crate, {
source: 'main.rs'.in_source,
Expand Down Expand Up @@ -90,9 +104,10 @@ rust_tests :platformtree_test, {
produce: 'platformtree_test'.in_build,
}

# zinc test
rust_tests :zinc_test, {
source: 'main.rs'.in_source,
deps: [:core_crate, :macro_ioreg],
deps: [:core_crate, :macro_ioreg, :hamcrest_crate, :shiny_crate],
produce: 'zinc_test'.in_build,
recompile_on: [:platform],
build_for: :host,
Expand Down
16 changes: 8 additions & 8 deletions ioreg/builder/accessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn build_field_accessors<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
},
None => "no documentation".into_string()
};
let docstring = format!("*[{}]* Field `{}`: {}",
let docstring = format!("*[{}]* `{}` field: {}",
access_tag,
field.name.node,
field_doc);
Expand Down Expand Up @@ -111,7 +111,7 @@ fn build_get_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>, reg: &node::Reg)
impl $reg_ty {
$doc_attr
#[allow(dead_code)]
pub fn get(&'static self) -> $getter_ty {
pub fn get(&self) -> $getter_ty {
$getter_ty::new(self)
}
}
Expand All @@ -131,7 +131,7 @@ fn build_field_set_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
if field.count.node == 1 {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self, new_value: $field_ty) -> $setter_ty {
pub fn $fn_name<'a>(&'a self, new_value: $field_ty) -> $setter_ty<'a> {
let mut setter: $setter_ty = $setter_ty::new(self);
setter.$fn_name(new_value);
setter
Expand All @@ -140,7 +140,7 @@ fn build_field_set_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
} else {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self, idx: uint, new_value: $field_ty) -> $setter_ty {
pub fn $fn_name<'a>(&'a self, idx: uint, new_value: $field_ty) -> $setter_ty<'a> {
let mut setter: $setter_ty = $setter_ty::new(self);
setter.$fn_name(idx, new_value);
setter
Expand All @@ -160,14 +160,14 @@ fn build_field_get_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
if field.count.node == 1 {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self) -> $field_ty {
pub fn $fn_name(&self) -> $field_ty {
$getter_ty::new(self).$fn_name()
}
)
} else {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self, idx: uint) -> $field_ty {
pub fn $fn_name(&self, idx: uint) -> $field_ty {
$getter_ty::new(self).$fn_name(idx)
}
)
Expand All @@ -184,7 +184,7 @@ fn build_field_clear_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
if field.count.node == 1 {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self) -> $setter_ty {
pub fn $fn_name<'a>(&'a self) -> $setter_ty<'a> {
let mut setter: $setter_ty = $setter_ty::new(self);
setter.$fn_name();
setter
Expand All @@ -193,7 +193,7 @@ fn build_field_clear_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
} else {
quote_method!(cx,
#[allow(dead_code, missing_doc)]
pub fn $fn_name(&'static self, idx: uint) -> $setter_ty {
pub fn $fn_name<'a>(&'a self, idx: uint) -> $setter_ty<'a> {
let mut setter: $setter_ty = $setter_ty::new(self);
setter.$fn_name(idx);
setter
Expand Down
2 changes: 1 addition & 1 deletion ioreg/builder/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ fn build_new<'a>(cx: &'a ExtCtxt, path: &Vec<String>)
utils::getter_name(cx, path));
let item = quote_item!(cx,
#[doc = "Create a getter reflecting the current value of the given register."]
pub fn new(reg: &'static $reg_ty) -> $getter_ty {
pub fn new(reg: & $reg_ty) -> $getter_ty {
$getter_ty {
value: reg.value.get(),
}
Expand Down
41 changes: 20 additions & 21 deletions ioreg/builder/setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ fn build_type<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
let item = quote_item!(cx,
$doc_attr
#[allow(non_camel_case_types)]
pub struct $name {
pub struct $name<'a> {
value: $packed_ty,
mask: $packed_ty,
reg: &'static $reg_ty,
reg: &'a $reg_ty,
}
);
item.unwrap()
Expand All @@ -92,7 +92,7 @@ fn build_new<'a>(cx: &'a ExtCtxt, path: &Vec<String>)
utils::setter_name(cx, path));
let item = quote_item!(cx,
#[doc="Create a new updater"]
pub fn new(reg: &'static $reg_ty) -> $setter_ty {
pub fn new(reg: &'a $reg_ty) -> $setter_ty {
$setter_ty {
value: 0,
mask: 0,
Expand Down Expand Up @@ -125,7 +125,7 @@ fn build_drop<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
let item = quote_item!(cx,
#[unsafe_destructor]
#[doc = "This performs the register update"]
impl Drop for $setter_ty {
impl<'a> Drop for $setter_ty<'a> {
fn drop(&mut self) {
let clear_mask: $unpacked_ty = $clear as $unpacked_ty;
if self.mask != 0 {
Expand Down Expand Up @@ -161,7 +161,7 @@ fn build_impl<'a>(cx: &'a ExtCtxt, path: &Vec<String>, reg: &node::Reg,
let done: P<ast::Method> = build_done(cx);
let impl_ = quote_item!(cx,
#[allow(dead_code)]
impl $setter_ty {
impl<'a> $setter_ty<'a> {
$new
$methods
$done
Expand Down Expand Up @@ -206,8 +206,8 @@ fn build_field_set_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>, reg: &node::Reg,
let shift = utils::shift(cx, None, field);
quote_method!(cx,
$doc_attr
pub fn $fn_name<'a>(&'a mut self, new_value: $field_ty)
-> &'a mut $setter_ty {
pub fn $fn_name<'b>(&'b mut self, new_value: $field_ty)
-> &'b mut $setter_ty<'a> {
self.value |= (self.value & ! $mask) | ((new_value as $unpacked_ty) & $mask) << $shift;
self.mask |= $mask << $shift;
self
Expand All @@ -217,11 +217,11 @@ fn build_field_set_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>, reg: &node::Reg,
let shift = utils::shift(cx, Some(quote_expr!(cx, idx)), field);
quote_method!(cx,
$doc_attr
pub fn $fn_name<'a>(&'a mut self, idx: uint, new_value: $field_ty)
-> &'a mut $setter_ty {
self.value |= (self.value & ! $mask) | ((new_value as $unpacked_ty) & $mask) << $shift;
self.mask |= $mask << $shift;
self
pub fn $fn_name<'b>(&'b mut self, idx: uint, new_value: $field_ty)
-> &'b mut $setter_ty<'a> {
self.value |= (self.value & ! $mask) | ((new_value as $unpacked_ty) & $mask) << $shift;
self.mask |= $mask << $shift;
self
}
)
}
Expand All @@ -248,21 +248,20 @@ fn build_field_clear_fn<'a>(cx: &'a ExtCtxt, path: &Vec<String>,
let shift = utils::shift(cx, None, field);
quote_method!(cx,
$doc_attr
pub fn $fn_name<'a>(&'a mut self) -> &'a mut $setter_ty {
self.value |= $mask << $shift;
self.mask |= $mask << $shift;
self
pub fn $fn_name<'b>(&'b mut self) -> &'b mut $setter_ty<'a> {
self.value |= $mask << $shift;
self.mask |= $mask << $shift;
self
}
)
} else {
let shift = utils::shift(cx, Some(quote_expr!(cx, idx)), field);
quote_method!(cx,
$doc_attr
pub fn $fn_name<'a>(&'a mut self, idx: uint)
-> &'a mut $setter_ty {
self.value |= $mask << $shift;
self.mask |= $mask << $shift;
self
pub fn $fn_name<'b>(&'b mut self, idx: uint) -> &'b mut $setter_ty<'a> {
self.value |= $mask << $shift;
self.mask |= $mask << $shift;
self
}
)
}
Expand Down
16 changes: 8 additions & 8 deletions ioreg/ioreg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,18 @@ look at `cr` in particular,
```
impl UART_cr {
pub fn get(&'static self) -> UART_cr_Get { ... }
pub fn get(&self) -> UART_cr_Get { ... }
pub fn set_rxe(&'static self, new_value: bool) -> UART_cr_Update { ... }
pub fn rxe(&'static self) -> bool { ... }
pub fn set_rxe(&self, new_value: bool) -> UART_cr_Update { ... }
pub fn rxe(&self) -> bool { ... }
// similar methods for `txe`, `rxie`, `txie`
pub fn set_br(&'static self, new_value: u32) -> UART_cr_Update { ... }
pub fn br(&'static self) -> u32 { ... }
pub fn set_br(&self, new_value: u32) -> UART_cr_Update { ... }
pub fn br(&self) -> u32 { ... }
pub fn set_parity(&'static self, new_value: UART_cr_parity) -> UART_cr_Update { ... }
pub fn parity(&'static self) -> UART_cr_parity { ... }
pub fn set_parity(&self, new_value: UART_cr_parity) -> UART_cr_Update { ... }
pub fn parity(&self) -> UART_cr_parity { ... }
}
```
Expand Down Expand Up @@ -264,7 +264,7 @@ method is instead produced. For instance, in the case of the `sr`
register's `fe` flag,
```
pub fn clear_fe(&'static self) -> UART_sr_Update { ... }
pub fn clear_fe(&self) -> UART_sr_Update { ... }
```
### Informal grammar
Expand Down
133 changes: 133 additions & 0 deletions ioreg/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Tests for ioreg! syntax extension
#![feature(phase)]
#[phase(plugin)] extern crate macro_ioreg;
#[phase(plugin,link)] extern crate shiny;
extern crate core;


#[allow(dead_code)]
#[path="../src/lib/volatile_cell.rs"] mod volatile_cell;

#[cfg(test)]
mod test {
use std::mem::{transmute, zeroed};
use std::ptr::RawPtr;
use volatile_cell::VolatileCell;

fn get_value<'a, T>(v: &'a T, offset: uint) -> u32 {
unsafe {
let ptr: *const u32 = transmute(v);
*(ptr.offset(offset as int))
}
}

fn zeroed_safe<T: Copy>() -> T {
unsafe {
return zeroed();
}
}

ioregs!(BASIC_TEST = {
0x0 => reg32 reg1 {
0 => field1,
1..3 => field2,
16..24 => field3,
25 => field4: set_to_clear,
}
0x4 => reg32 reg2 {
0 => field1,
}
})

describe!(
before_each {
let test: BASIC_TEST = zeroed_safe();
}

it "can round_trip simple field values (1)" {
test.reg1.set_field1(true);
assert_eq!(test.reg1.field1(), true)
assert_eq!(get_value(&test, 0), 1)
assert_eq!(get_value(&test, 1), 0)
}

it "can round trip simple field values (2)" {
test.reg1.set_field3(0xde);
assert_eq!(test.reg1.field3(), 0xde)
assert_eq!(get_value(&test, 0), 0xde<<16)
}

it "sets set_to_clear fields" {
test.reg1.clear_field4();
assert_eq!(get_value(&test, 0), 1<<25)
}
)

ioregs!(GROUP_TEST = {
0x0 => group regs[5] {
0x0 => reg32 reg1 {
0..31 => field1
}
0x4 => reg32 reg2 {
0..31 => field2
}
}
})

describe!(
before_each {
let test: GROUP_TEST = zeroed_safe();
}

it "sets groups correctly" {
test.regs[0].reg1.set_field1(0xdeadbeef);
assert_eq!(test.regs[0].reg1.field1(), 0xdeadbeef)
assert_eq!(get_value(&test, 0), 0xdeadbeef)
for i in range(1, 10) {
assert_eq!(get_value(&test, i), 0)
}

test.regs[2].reg2.set_field2(0xfeedbeef);
assert_eq!(test.regs[2].reg2.field2(), 0xfeedbeef)
assert_eq!(get_value(&test, 5), 0xfeedbeef)
}
)

ioregs!(FIELD_ARRAY_TEST = {
0x0 => reg32 reg1 {
0..31 => field[16]
}
})

describe!(
before_each {
let test: FIELD_ARRAY_TEST = zeroed_safe();
}

it "sets field arrays correctly" {
test.reg1.set_field(0, 1);
assert_eq!(test.reg1.field(0), 1);
assert_eq!(get_value(&test, 0), 0x1)

test.reg1.set_field(4, 3);
assert_eq!(test.reg1.field(4), 3);
assert_eq!(get_value(&test, 0), 0x1 | 0x3<<8)
}
)
}
4 changes: 4 additions & 0 deletions support/rake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,8 @@ def provide_stdlibs
Rake::FileTask.define_task 'thirdparty/hamcrest-rust'.in_root do |t|
sh "git clone --single-branch --depth 1 https://github.com/carllerche/hamcrest-rust #{t.name}"
end.invoke

Rake::FileTask.define_task 'thirdparty/shiny'.in_root do |t|
sh "git clone --single-branch --depth 1 https://github.com/farcaller/shiny #{t.name}"
end.invoke
end

0 comments on commit 4e0b234

Please sign in to comment.