What do round brackets mean in the output of clojure.test failures? - unit-testing

I have the following output in one of my tests:
Assertion failed:
Expected :[[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] ["seq07"] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []]
Actual :[() () () () () () () () () () () () () () () () () () () () () () () () () () ("seq07") () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()]
What do () and ("seq07") mean in this output?

As noted in another answer, () is an empty list and [] is an empty vector.
Note however that = compares the contents of lists and vectors, it ignores the type of the container:
(= '("seq07") ["seq07"]) ;; => true
(= '(()) [[]]) ;; => true
The assertion failure in the question is due to the actual vector having fewer elements than the expected vector:
(= ['("seq07")] ['("seq07") '()]) ;; => false

() is a notation for list whereas [] is a notation for vectors
() is an empty list and ("seq07") is a list that contains a single member - the string seq07
you can read more about clojure lists here
EDIT: just found this interesting SO question about lists vs vectors

Related

Append to Node to an Empty LinkedList in Rust, self.head.borrow_next() is None and not self.tail

I have tried to reimplement LinkedList in Rust, below are my codes:
#![allow(dead_code)]
use std::cell::{RefCell, Ref, RefMut};
use std::rc::Rc;
type WrappedNode<T> = Rc<RefCell<Node<T>>>;
#[derive(Debug, PartialOrd, PartialEq, Clone)]
pub struct Node<T> where
T: Clone
{
next: Option<WrappedNode<T>>,
data: T,
}
#[derive(Debug, PartialOrd, PartialEq)]
pub struct LinkedList<T> where
T: Clone
{
head: Option<WrappedNode<T>>,
tail: Option<WrappedNode<T>>,
}
impl<T> Iterator for LinkedList<T> where
T: Clone
{
type Item = WrappedNode<T>;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
impl<T> Node<T> where
T: Clone
{
pub fn new(data: T) -> Self {
Self {
next: None,
data,
}
}
pub fn borrow_data(self: &Self) -> &T {
&self.data
}
pub fn borrow_next(self: &Self) -> Option<Ref<Node<T>>> {
match &self.next {
Some(next_exists) => {
Some(next_exists.borrow())
},
None => {
None
}
}
}
pub fn borrow_mut_next(self: &Self) -> Option<RefMut<Node<T>>> {
match &self.next {
Some(next_exists) => {
Some(next_exists.borrow_mut())
},
None => {
None
}
}
}
pub fn set_next(self: &mut Self, next: Node<T>) {
let next_node = Rc::new(RefCell::new(next));
self.next = Some(next_node);
}
}
impl<T> LinkedList<T> where
T: Clone
{
pub fn new_empty() -> Self {
Self {
head: None,
tail: None,
}
}
pub fn new_with_node(first_node: Node<T>) -> Self {
let mut new_ll = Self::new_empty();
Self::append(&mut new_ll, first_node);
new_ll
}
pub fn append(&mut self, node: Node<T>) {
assert!(node.next.is_none()); // make sure its not joining two linkedlists
match self.tail.take() {
Some(old_tail) => {
old_tail
.borrow_mut()
.set_next(node.clone());
},
None => {
let mut node_clone = node.clone();
node_clone.next = self.tail.clone();
self.head = Some(Rc::new(RefCell::new(node_clone)));
}
}
self.tail = Some(Rc::new(RefCell::new(node)));
}
}
// CRUD -> create new, add to head tail, read head tail, update anywhere, delete anywhere, delete head tail
#[cfg(test)]
mod tests {
use super:: {Node, LinkedList};
use std::rc::Rc;
use std::cell::RefCell;
#[test]
fn test_node_ref_data() {
let node = Node::new(5);
assert_eq!(node.borrow_data(), &5);
}
#[test]
fn test_node_ref_next() {
let node = Node::new(5);
assert!(node.borrow_next().is_none());
}
#[test]
fn test_node_set_next() {
let mut node = Node::new(33);
let next_node = Node::new(34);
Node::set_next(&mut node,
next_node);
assert_eq!(node
.borrow_next()
.unwrap()
.borrow_data(), &34);
}
#[test]
fn test_ll_new_empty() {
#[derive(Debug, PartialEq, PartialOrd, Clone)]
struct NTH;
let new_ll = LinkedList::<NTH>::new_empty();
assert_eq!(new_ll, LinkedList{head: None, tail: None})
}
#[test]
fn test_ll_new_with_node() {
let new_node = Node::new(45);
let new_node_two = new_node.clone();
let new_node_three = new_node.clone();
let new_ll = LinkedList::new_with_node(new_node);
let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
let new_node_three = Some(Rc::new(RefCell::new(new_node_three)));
assert_eq!(new_ll, LinkedList{head: new_node_two, tail: new_node_three})
}
#[test]
fn test_ll_new_with_node_head_borrow_next_is_tail() {
let new_node = Node::new(45);
let new_node_two = new_node.clone();
let new_ll = LinkedList::new_with_node(new_node);
let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
assert_eq!(new_ll
.head
.unwrap()
.borrow()
.borrow_next()
.unwrap()
.borrow_data(), new_node_two.unwrap().borrow().borrow_data());
}
#[test]
fn test_ll_append_tail() {
let new_node = Node::new(45);
let new_node_two = new_node.clone();
let mut new_ll = LinkedList::new_with_node(new_node);
let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
let append_node = Node::new(77);
LinkedList::append(&mut new_ll, append_node);
assert_eq!(new_ll
.tail
.unwrap()
.borrow()
.borrow_data(), &77)
}
#[test]
fn test_ll_append_first_borrow_next() {
let new_node = Node::new(45);
let new_node_two = new_node.clone();
let mut new_ll = LinkedList::new_with_node(new_node);
let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
let append_node = Node::new(77);
LinkedList::append(&mut new_ll, append_node);
assert_eq!(new_ll
.head
.unwrap()
.borrow()
.borrow_next()
.unwrap()
.borrow_data(), &77)
}
// end of tests
}
Two tests failed, as shown below:
running 8 tests
test same_type_linked_list::tests::test_ll_new_empty ... ok
test same_type_linked_list::tests::test_ll_append_tail ... ok
test same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail ... FAILED
test same_type_linked_list::tests::test_ll_append_first_borrow_next ... FAILED
test same_type_linked_list::tests::test_ll_new_with_node ... ok
test same_type_linked_list::tests::test_node_ref_data ... ok
test same_type_linked_list::tests::test_node_set_next ... ok
test same_type_linked_list::tests::test_node_ref_next ... ok
failures:
---- same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail stdout ----
thread 'same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail' panicked at 'called `Option::unwrap()` on a `None` value', src/same_type_linked_list.rs:176:14
---- same_type_linked_list::tests::test_ll_append_first_borrow_next stdout ----
thread 'same_type_linked_list::tests::test_ll_append_first_borrow_next' panicked at 'called `Option::unwrap()` on a `None` value', src/same_type_linked_list.rs:210:16
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
same_type_linked_list::tests::test_ll_append_first_borrow_next
same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail
I suspect during the appending of a new Node<T>, concretely Node<u64>, to an empty LinkedList the self.head.next is not pointing to self.tail, despite me setting it explicitly. The error occurs when I call unwrap() on the None value which is returned from borrow_next(), an associated method of Node<T> to return a reference of the field .next. That means that new_ll.head.borrow_next() which ideally should return a reference to new_ll.tail instead returns a None, meaning that it is not pointing to new_ll.tail when a first node is appended/inserted into a completely empty LinkedList.
Looking at your code the head node is the one that you give to in
LinkedList::new_with_node()
Its calling
pub fn new_empty() -> Self {
Self {
head: None,
tail: None,
}
i.e. its initialized with no head node. So when you construct your list with a node you are adding a head
pub fn new_with_node(first_node: Node<T>) -> Self {
let mut new_ll = Self::new_empty();
Self::append(&mut new_ll, first_node);
new_ll
}
pub fn append(&mut self, node: Node<T>) {
assert!(node.next.is_none()); // make sure its not joining two linkedlists
match self.tail.take() {
Some(old_tail) => {
old_tail
.borrow_mut()
.set_next(node.clone());
},
None => {
let mut node_clone = node.clone();
node_clone.next = self.tail.clone();
self.head = Some(Rc::new(RefCell::new(node_clone)));
}
}
You are also calling append by explicitly passing the newly created list as self.
Self::append(&mut new_ll, first_node);
You could have called it
new_ll.append(first_node)
You are assuming there is another node beyond the head in your test:
assert_eq!(new_ll
.head
.unwrap()
.borrow()
.borrow_next()
.unwrap()
.borrow_data(), &77)

Flutter Unhandled Exception: type 'Future<Group>' is not a subtype of type 'Group'

While working with Firebase Firestore, I am coming across the following error:
E/flutter ( 4477): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: type 'Future<Group>' is not a subtype of type 'Group', stack trace: #0 new List.from (dart:core-patch/array_patch.dart:41:5)
E/flutter ( 4477): #1 GroupService.getGroups (package:money_manager/core/services/group_service.dart:56:21)
E/flutter ( 4477): <asynchronous suspension>
E/flutter ( 4477): #2 GroupViewModel._getAllGroups (package:money_manager/core/view_models/group_viewmodel.dart:44:26)
E/flutter ( 4477): <asynchronous suspension>
E/flutter ( 4477):
Though I think I have made proper use of async-await wherever necessary, I am not being able to figure out this error. Relevant code:
in group-service.dart :
Future<List<Group>> getGroups() async {
final userData = await getUserData();
List<Group> groups = [];
if (userData['groups'] != null) {
List<String> groupIds = List.from(userData['groups'].map((e) => e['id']));
groups = List.from(groupIds.map((e) async {
return await getGroupFromId(e);
}));
}
return groups;
}
Future<Group> getGroupFromId(String groupId) async {
final groupData = await getGroupData(groupId);
return Group.fromJson(groupData);
}
Future<Map<String, dynamic>> getGroupData(String groupId) async {
DocumentReference groupDoc =
FirebaseFirestore.instance.collection('groups').doc(groupId);
final snapshot = await groupDoc.get();
Map<String, dynamic> groupData = snapshot.data() as Map<String, dynamic>;
return groupData;
}
in group_viewmodel.dart:
List<Group> _userGroups = [];
void _getAllGroups() async {
List<Group> groups = await _groupService.getGroups();
_userGroups = groups;
}
The problem is in the following line:
groups = List.from(groupIds.map((e) async {
return await getGroupFromId(e);
}));
Even though you're using await before the return of the map() function, it will still return a Future. map() is a synchronous function, and it doesn't run the inner function asynchronously. Thus, it will return an Iterable<Future<Group>>, which fails to be converted into a List<Group> in the List.from() function.
There is a handy function that takes an iterable of futures and waits for each one of them, Future.wait(). Here's how your code will look like with it:
groups = List.from(await Future.wait(groupIds.map((e) async {
return await getGroupFromId(e);
})));
And even better with tear-offs:
groups = List.from(await Future.wait(groupIds.map(getGroupFromId)));

SQS Lambda function returns "Task timed out after 10.01s"

I have a simple use case where I insert a message into a standard SQS queue and return the message back via api call.
I send a couple messages to the sqs queue which triggers the lambda function shown below:
import json
import requests
def lambda_handler(event, context):
print('start')
resp = requests.get("http://fe35-103-210-33-254.ngrok.io/receive-message").json()
print(resp)
print('end')
return {
'status':200,
'message':resp
}
The function calls an api which basically recieves the messages and deletes them after returning it
#app.get('/receive-message')
def receive_message():
client = boto3.resource('sqs')
queue = client.get_queue_by_name(QueueName='transactions')
messages = queue.receive_messages(QueueUrl=queue.url, WaitTimeSeconds=10, MaxNumberOfMessages=10, VisibilityTimeout=60)
context = []
for message in messages:
context.append(message.body)
queue.delete_messages(QueueUrl=queue.url, Entries=[{'Id':message.message_id,'ReceiptHandle':message.receipt_handle}])
print(context)
return ','.join(context)
Here is the output i am returning on the terminal
←[33mWARNING←[0m: WatchGodReload detected file change in '['C:\\Work\\payments\\sqs_poc.py']'. Reloading...
←[32mINFO←[0m: Started server process [←[36m46472←[0m]
←[32mINFO←[0m: Waiting for application startup.
←[32mINFO←[0m: Application startup complete.
['hello']
[]
[]
[]
[]
[]
[]
[]
[]
[]
['pqr']
[]
[]
[]
[]
[]
['Testing']
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
['pqr']
←[32mINFO←[0m: 13.127.17.123:0 - "←[1mGET /receive-message HTTP/1.1←[0m" ←[32m200 OK←[0m
And here is the output from the lambda test execution
Response
{
"errorMessage": "2021-10-06T08:12:36.466Z aff8f3ac-683d-40cc-b80e-92d18ec2c9f1 Task timed out after 10.01 seconds"
}
Function Logs
START RequestId: aff8f3ac-683d-40cc-b80e-92d18ec2c9f1 Version: $LATEST
start
END RequestId: aff8f3ac-683d-40cc-b80e-92d18ec2c9f1
REPORT RequestId: aff8f3ac-683d-40cc-b80e-92d18ec2c9f1 Duration: 10010.58 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 19 MB
2021-10-06T08:12:36.466Z aff8f3ac-683d-40cc-b80e-92d18ec2c9f1 Task timed out after 10.01 seconds
Also, is there a way where I can get the whole queue and stop the polling when the queue is empty?

How to write a service that either displays HTML or redirects to another page

In web programming, a common pattern for form submission is:
If the form is valid, redirect to another page (Post/Redirect/Get).
If the form is not valid, redisplay the form (possibly including error messages this time).
How do I express this in Ocsigen?
I've been reading the documentation, but could not figure out how to accomplish this simple (and very common) task.
Example use case:
Suppose I have a login form that guards against unauthorized access to the admin panel (a page that should only be accessed by administrators). If the user provides the correct credentials at the login form, the user should be redirected to the admin panel. If the credentials are incorrect, the user should be redirected back to the login form. So far, I have successfully implemented this functionality.
However, I am at loss when it comes to implementing the following: if the user is already logged in and tries to access the login form, the user should be redirected to the admin panel. Also, if the user is not logged in and tries to access the admin panel, the user should be redirected to the login form.
Below is my code up the point I got stuck:
(* Secret login credentials. *)
let username = "admin"
let password = "123456"
(* Create Eliom services. *)
let login_form_service = Eliom_service.create
~path:(Eliom_service.Path ["login"])
~meth:(Eliom_service.Get Eliom_parameter.unit)
()
let login_service = Eliom_service.create_attached_post
~fallback:login_form_service
~post_params:Eliom_parameter.(string "user" ** string "pass")
()
let admin_panel_service = Eliom_service.create
~path:(Eliom_service.Path ["admin-panel"])
~meth:(Eliom_service.Get Eliom_parameter.unit)
()
let session_username : string option Eliom_reference.eref =
Eliom_reference.eref ~scope:Eliom_common.default_session_scope None
(* Register Eliom services. *)
let () = Eliom_content.Html.D.(
Eliom_registration.Html.register
~service:login_form_service
(fun () () -> Lwt.return
(Eliom_tools.D.html
~title:"Login"
(body [h1 [pcdata "Login"];
Form.post_form
~service:login_service
(fun (user, pass) ->
[fieldset
[label [pcdata "Username: "];
Form.input ~input_type:`Text
~name:user
Form.string;
br ();
label [pcdata "Password: "];
Form.input ~input_type:`Password
~name:pass
Form.string;
br ();
Form.input ~input_type:`Submit
~value:"Login"
Form.string
]]) ()])));
Eliom_registration.Redirection.register
~service:login_service
(fun () (user, pass) ->
if user = username && pass = password then (
Eliom_reference.set session_username (Some username);
Lwt.return (Eliom_registration.Redirection admin_panel_service))
else
Lwt.return (Eliom_registration.Redirection login_form_service));
Eliom_registration.Html.register
~service:admin_panel_service
(fun () () ->
(* Admin panel html here ... *))
);
What is the proper method of solving this problem?
Thank you.
I don't know if you found the solution as your question is kind of old by now but here is what I found:
I used "Registering services that decide what they want to send" from https://ocsigen.org/eliom/6.3/manual/server-outputs#redirections
The idea is to register you services with Eliom_registration.Any, this allows the handler attached to the service to decide on the fly the type of answer to provide by using the appropriate send function.
(* Secret login credentials. *)
let username = "admin"
let password = "123456"
(* Create Eliom services. *)
let login_form_service = Eliom_service.create
~path:(Eliom_service.Path ["login"])
~meth:(Eliom_service.Get Eliom_parameter.unit)
()
let login_service = Eliom_service.create_attached_post
~fallback:login_form_service
~post_params:Eliom_parameter.(string "user" ** string "pass")
()
let admin_panel_service = Eliom_service.create
~path:(Eliom_service.Path ["admin-panel"])
~meth:(Eliom_service.Get Eliom_parameter.unit)
()
let session_username : string option Eliom_reference.eref =
Eliom_reference.eref ~scope:Eliom_common.default_session_scope None
let login_panel () = Eliom_content.Html.D.(
Eliom_tools.D.html
~title:"Login"
(body [
h1 [pcdata "Login"];
Form.post_form
~service:login_service
(fun (user, pass) ->
[fieldset
[label [pcdata "Username: "];
Form.input ~input_type:`Text
~name:user
Form.string;
br ();
label [pcdata "Password: "];
Form.input ~input_type:`Password
~name:pass
Form.string;
br ();
Form.input ~input_type:`Submit
~value:"Login"
Form.string
]]) ()])
)
let admin_panel () = Eliom_content.Html.F.(
Eliom_tools.F.html
~title:"Fake Admin Panel"
(body [h1 [pcdata "Fake Admin Panel"];])
)
(* Some helper functions *)
let admin_credentials ~user_is_admin ~user_is_not_admin =
let%lwt usr = Eliom_reference.get session_username in
if usr = Some username then user_is_admin ()
else user_is_not_admin ()
let send_redirection service =
Eliom_registration.Redirection.send (Eliom_registration.Redirection service)
let send_page page =
Eliom_registration.Html.send page
(* Register Eliom services. *)
let () = Eliom_content.Html.D.(
Eliom_registration.Any.register
~service:login_form_service
(fun () () ->
admin_credentials
~user_is_admin:(fun () -> send_redirection admin_panel_service)
~user_is_not_admin:(fun () -> send_page (login_panel ()))
);
Eliom_registration.Redirection.register
~service:login_service
(fun () (user, pass) ->
if user = username && pass = password then (
let%lwt _ = Eliom_reference.set session_username (Some username) in
Lwt.return (Eliom_registration.Redirection admin_panel_service))
else
Lwt.return (Eliom_registration.Redirection login_form_service));
Eliom_registration.Any.register
~service:admin_panel_service
(fun () () ->
admin_credentials
~user_is_admin:(fun () -> send_page (admin_panel ()))
~user_is_not_admin:(fun () -> send_redirection login_form_service))
)

Return from function fails C++

I have a problem and I don't know why is it occurs.
My Qt project includes class AllExceptions. It has the following constructor:
AllExceptions::AllExceptions(std::string errName){
errorMessage = errName;
} //<<<---
I call constructor in the following way:
throw AllExceptions(response);
where response is a string that represents smtp server answer.
Problem: program stucks at constructing object. I debbuged and figured out that it stucks at point that I marked <<<---.
Any advice, please.
EDIT: stack at that point
AllExceptions::AllExceptions (this=0xaf47d0, errName={static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7fffffffca10 \"\\330;\\257\"}})
Email::sendMessage (this=0xa2e950)
NewMailWindow::sendMail (this=0x885bb0)
NewMailWindow::qt_static_metacall (_o=0x885bb0, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffffffcdb0)
QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
QAbstractButton::clicked(bool) ()
?? ()
?? ()
QAbstractButton::mouseReleaseEvent(QMouseEvent*) ()
QWidget::event(QEvent*) ()
QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
QApplication::notify(QObject*, QEvent*) ()
QCoreApplication::notifyInternal(QObject*, QEvent*) ()
QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) ()
?? ()
QApplication::x11ProcessEvent(_XEvent*) ()
?? ()
g_main_context_dispatch ()
?? ()
g_main_context_iteration ()
QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
?? ()
QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
QCoreApplication::exec() ()
main (argc=1, argv=0x7fffffffe478)
Header file:
class AllExceptions{
public:
AllExceptions(std::string errName);
std::string getErrMess() {return errorMessage;};
void displayError();
private:
std::string errorMessage;
};