rpn_cli/
engine.rs

1use crate::calc::context::{Context, Format};
2use crate::calc::undo::Undo;
3use crate::calc::value::{Value, ValueRef};
4use crate::config::Config;
5use crate::core::action;
6use crate::core::action::{Action, Actions};
7use crate::core::count::Count;
8use crate::core::helper::CommandEditor;
9use crate::core::interface::{Directive, Interface, Operation};
10use crate::core::stack::{BracketChars, StackItem, ValueStack};
11use crate::error::{EngineError, MyError, MyResult};
12use crate::util::text::create_padding;
13use fileinput::FileInput;
14use itertools::Itertools;
15use std::cell::RefCell;
16use std::fs::File;
17use std::io::{BufRead, BufReader, Write};
18use std::rc::Rc;
19use std::slice::Iter;
20
21const PAGE_LIMIT: usize = 10;
22
23pub struct Engine<W: Write> {
24    config: Config,
25    editor: CommandEditor,
26    interface: Rc<RefCell<Interface<W>>>,
27    context: Rc<RefCell<Context>>,
28    undos: Vec<Undo>,
29    redos: Vec<Undo>,
30    clip: Option<ValueRef>,
31    dirty: bool,
32    interact: bool,
33    chars: BracketChars,
34}
35
36// noinspection RsLift
37impl<W: Write> Engine<W> {
38    pub fn new(config: Config, chars: BracketChars) -> MyResult<Self> {
39        let interface = Rc::new(RefCell::new(Interface::build()));
40        let editor = interface.borrow().create_editor()?;
41        let context = Rc::new(RefCell::new(Context::new()));
42        let undos = Vec::new();
43        let redos = Vec::new();
44        let engine = Self {
45            config,
46            editor,
47            interface,
48            context,
49            undos,
50            redos,
51            clip: None,
52            dirty: false,
53            interact: false,
54            chars,
55        };
56        Ok(engine)
57    }
58
59    pub fn parse_input(&mut self, writer: &mut W) -> MyResult<()> {
60        let mut stack = ValueStack::new(Vec::new());
61        if let Some(import) = &self.config.import {
62            let import = vec![String::from(import)];
63            self.import_file(writer, &mut stack, import)?;
64        }
65        if !self.config.values.is_empty() {
66            self.parse_values(writer, &mut stack)?;
67            if !self.config.mock {
68                self.show_simple(writer, &mut stack)?;
69            }
70        } else if !self.config.paths.is_empty() || atty::isnt(atty::Stream::Stdin) || atty::isnt(atty::Stream::Stdout) {
71            let reader = FileInput::new(&self.config.paths);
72            self.parse_files(writer, &mut stack, reader)?;
73            self.show_simple(writer, &mut stack)?;
74        } else {
75            self.parse_loop(writer, &mut stack)?;
76        }
77        Ok(())
78    }
79
80    fn parse_values(
81        &mut self,
82        writer: &mut W,
83        stack: &mut ValueStack,
84    ) -> MyResult<()> {
85        let values = self.config.values.drain(..).collect::<Vec<String>>();
86        if self.config.mock {
87            for (index, value) in values.iter().enumerate() {
88                self.interact = index + 1 == values.len();
89                self.interact_line(writer, stack, &value)?;
90            }
91        } else {
92            for value in values {
93                self.parse_line(writer, stack, &value)?;
94            }
95        }
96        Ok(())
97    }
98
99    fn parse_files(
100        &mut self,
101        writer: &mut W,
102        stack: &mut ValueStack,
103        reader: FileInput,
104    ) -> MyResult<()> {
105        let mut undo = Undo::default();
106        let mut redo = Undo::default();
107        let reader = BufReader::new(reader);
108        for line in reader.lines() {
109            let line = line?;
110            self.parse_inner(writer, stack, &mut undo, &mut redo, &line)?;
111        }
112        self.commit_undo(undo, redo);
113        Ok(())
114    }
115
116    fn parse_loop(
117        &mut self,
118        writer: &mut W,
119        stack: &mut ValueStack,
120    ) -> MyResult<()> {
121        self.interact = true;
122        loop {
123            let line = self.editor.readline("rpn> ")?;
124            self.editor.add_history_entry(&line)?;
125            self.interact_line(writer, stack, &line)?;
126        }
127    }
128
129    fn interact_line(
130        &mut self,
131        writer: &mut W,
132        stack: &mut ValueStack,
133        line: &str,
134    ) -> MyResult<()> {
135        let result = match self.parse_line(writer, stack, line) {
136            Ok(()) => {
137                if self.interact && self.dirty {
138                    self.limit_stack(writer, stack, Some(PAGE_LIMIT))?;
139                }
140                Ok(())
141            }
142            Err(MyError::Engine(error)) => {
143                if self.interact {
144                    writeln!(writer, "  {}", error)?;
145                }
146                Ok(())
147            }
148            Err(error) => {
149                Err(error)
150            }
151        };
152        self.dirty = false;
153        result
154    }
155
156    fn parse_line(
157        &mut self,
158        writer: &mut W,
159        stack: &mut ValueStack,
160        line: &str,
161    ) -> MyResult<()> {
162        let mut undo = Undo::default();
163        let mut redo = Undo::default();
164        self.parse_inner(writer, stack, &mut undo, &mut redo, line)?;
165        self.commit_undo(undo, redo);
166        Ok(())
167    }
168
169    fn parse_inner(
170        &mut self,
171        writer: &mut W,
172        stack: &mut ValueStack,
173        undo: &mut Undo,
174        redo: &mut Undo,
175        line: &str,
176    ) -> MyResult<()> {
177        let mut empty = true;
178        let (line, comment) = Self::split_comment(line);
179        let actions = Actions::new(&self.interface, line.split_ascii_whitespace());
180        for action in actions {
181            let action = match action {
182                Ok((action, keyword)) => self.apply_action(
183                    writer,
184                    stack,
185                    undo,
186                    redo,
187                    action,
188                    Some(keyword),
189                ),
190                Err(error) => Err(error),
191            };
192            if let Err(error) = action {
193                undo.apply_to(stack);
194                return Err(error);
195            }
196            empty = false;
197        }
198        if let Some(comment) = comment {
199            if let Err(error) = self.apply_comment(stack, comment) {
200                undo.apply_to(stack);
201                return Err(error);
202            }
203            empty = false;
204        }
205        self.dirty |= empty;
206        Ok(())
207    }
208
209    fn split_comment(line: &str) -> (&str, Option<&str>) {
210        if let Some(stop) = line.find('#') {
211            let start = stop + 1;
212            let values = line[..stop].trim();
213            let comment = line[start..].trim();
214            let comment = if comment.is_empty() { None } else { Some(comment) };
215            (values, comment)
216        } else {
217            let values = line.trim();
218            (values, None)
219        }
220    }
221
222    fn apply_action(
223        &mut self,
224        writer: &mut W,
225        stack: &mut ValueStack,
226        undo: &mut Undo,
227        redo: &mut Undo,
228        action: Action<W>,
229        keyword: Option<&str>,
230    ) -> MyResult<()> {
231        match action {
232            Action::Operation(operation) => {
233                match operation.as_ref() {
234                    Operation::ValueNone(function) => {
235                        let result = function()?;
236                        stack.push_single(undo, result, keyword);
237                        self.dirty = true;
238                    }
239                    Operation::ValueOne(function) => {
240                        let value = stack.pop_single(undo, None)?;
241                        let result = function(value)?;
242                        stack.push_single(undo, result, keyword);
243                        self.dirty = true;
244                    }
245                    Operation::ValueTwo(function) => {
246                        let (value1, value2) = stack.pop_double(undo, None)?;
247                        let result = function(value1, value2)?;
248                        stack.push_single(undo, result, keyword);
249                        self.dirty = true;
250                    }
251                    Operation::ValueAll(function) => {
252                        let (values, _) = stack.pop_series(undo, None);
253                        let result = function(values)?;
254                        stack.push_single(undo, result, keyword);
255                        self.dirty = true;
256                    }
257                    Operation::SeriesTwo(function) => {
258                        let (value1, value2) = stack.pop_double(undo, None)?;
259                        let results = function(value1, value2)?;
260                        self.dirty |= stack.push_series(undo, results, keyword);
261                    }
262                    Operation::SeriesThree(function) => {
263                        let (value1, value2, value3) = stack.pop_triple(undo, None)?;
264                        let results = function(value1, value2, value3)?;
265                        self.dirty |= stack.push_series(undo, results, keyword);
266                    }
267                    Operation::SeriesAll(function) => {
268                        let (values, as_series) = stack.pop_series(undo, None);
269                        let results = function(values)?;
270                        if as_series {
271                            self.dirty |= stack.push_series(undo, results, keyword);
272                        } else {
273                            self.dirty |= stack.push_singles(undo, results, keyword);
274                        }
275                    }
276                    Operation::TimeNow(function) => {
277                        let result = function(&self.config.now)?;
278                        stack.push_single(undo, result, keyword);
279                        self.dirty = true;
280                    }
281                    Operation::TimeCast(function) => {
282                        let value = stack.pop_single(undo, None)?;
283                        let result = function(value)?;
284                        stack.push_single(undo, result, keyword);
285                        self.dirty = true;
286                    }
287                    Operation::ContextNone(function) => {
288                        function(&mut self.context.borrow_mut());
289                        self.dirty = true;
290                    }
291                    Operation::ContextOne(function) => {
292                        let value = stack.pop_single(undo, keyword)?;
293                        function(&mut self.context.borrow_mut(), value);
294                        self.dirty = true;
295                    }
296                    Operation::EngineNone(function) => {
297                        if let Some(dirty) = function(self, writer, stack)? {
298                            self.dirty = dirty;
299                        }
300                    }
301                    Operation::EngineUndo(function, _, _) => {
302                        if let Some(dirty) = function(self, stack, undo, redo, keyword)? {
303                            self.dirty = dirty;
304                        }
305                    }
306                }
307            }
308            Action::Directive(directive, tokens) => {
309                match directive.as_ref() {
310                    Directive::EngineOne(function, _) => {
311                        let token = tokens.into_iter().next();
312                        self.dirty |= function(self, writer, stack, token)?;
313                    }
314                    Directive::EngineAll(function, _) => {
315                        self.dirty |= function(self, writer, stack, tokens)?;
316                    }
317                    Directive::EngineApply(function, _) => {
318                        self.dirty |= function(self, writer, keyword, stack, undo, redo, tokens)?;
319                    }
320                }
321            }
322            Action::Definition(actions) => {
323                for action in actions {
324                    self.apply_action(writer, stack, undo, redo, action, None)?;
325                }
326                undo.merge(0, vec![], keyword);
327            }
328            Action::Value(value, dirty) => {
329                stack.push_single(undo, value, keyword);
330                self.dirty |= dirty;
331            }
332        }
333        Ok(())
334    }
335
336    fn apply_comment(
337        &mut self,
338        stack: &ValueStack,
339        comment: &str,
340    ) -> MyResult<()> {
341        let value = stack.peek_single()?;
342        value.borrow_mut().set_comment(comment);
343        self.dirty = true;
344        Ok(())
345    }
346
347    fn commit_undo(
348        &mut self,
349        undo: Undo,
350        redo: Undo,
351    ) {
352        if !undo.is_empty() {
353            self.undos.push(undo);
354            self.redos.clear();
355        } else if !redo.is_empty() {
356            self.redos.push(redo);
357        }
358    }
359
360    pub fn flat_values(
361        &mut self,
362        stack: &mut ValueStack,
363        undo: &mut Undo,
364        redo: &mut Undo,
365        keyword: Option<&str>,
366    ) -> MyResult<Option<bool>> {
367        if stack.items.iter().any(|item| matches!(item, StackItem::Series(_))) {
368            let items = stack.pop_stack(undo, None);
369            redo.clear();
370            stack.push_singles(undo, items, keyword);
371            Ok(Some(true))
372        } else {
373            Ok(None)
374        }
375    }
376
377    pub fn clear_values(
378        &mut self,
379        stack: &mut ValueStack,
380        undo: &mut Undo,
381        redo: &mut Undo,
382        keyword: Option<&str>,
383    ) -> MyResult<Option<bool>> {
384        let items = stack.wrapped_drain(..).collect();
385        undo.merge(0, items, keyword);
386        redo.clear();
387        Ok(Some(true))
388    }
389
390    pub fn pop_value(
391        &mut self,
392        stack: &mut ValueStack,
393        undo: &mut Undo,
394        redo: &mut Undo,
395        keyword: Option<&str>,
396    ) -> MyResult<Option<bool>> {
397        stack.pop_single(undo, keyword)?;
398        redo.clear();
399        Ok(Some(true))
400    }
401
402    pub fn dup_value(
403        &mut self,
404        stack: &mut ValueStack,
405        undo: &mut Undo,
406        redo: &mut Undo,
407        keyword: Option<&str>,
408    ) -> MyResult<Option<bool>> {
409        let value = stack.peek_single()?;
410        let value = Rc::new(RefCell::new(value.borrow().clone()));
411        stack.push_single(undo, value, keyword);
412        redo.clear();
413        Ok(Some(true))
414    }
415
416    pub fn swap_values(
417        &mut self,
418        stack: &mut ValueStack,
419        undo: &mut Undo,
420        redo: &mut Undo,
421        keyword: Option<&str>,
422    ) -> MyResult<Option<bool>> {
423        let (value1, value2) = stack.pop_double(undo, None)?;
424        stack.push_single(undo, value2, None);
425        stack.push_single(undo, value1, keyword);
426        redo.clear();
427        Ok(Some(true))
428    }
429
430    pub fn cut_value(
431        &mut self,
432        stack: &mut ValueStack,
433        undo: &mut Undo,
434        redo: &mut Undo,
435        keyword: Option<&str>,
436    ) -> MyResult<Option<bool>> {
437        let value = stack.pop_single(undo, keyword)?;
438        self.clip = Some(value);
439        redo.clear();
440        Ok(Some(true))
441    }
442
443    pub fn copy_value(
444        &mut self,
445        stack: &mut ValueStack,
446        _undo: &mut Undo,
447        _redo: &mut Undo,
448        _keyword: Option<&str>,
449    ) -> MyResult<Option<bool>> {
450        let value = stack.peek_single()?;
451        let value = Rc::new(RefCell::new(value.borrow().clone()));
452        self.clip = Some(value);
453        Ok(None)
454    }
455
456    pub fn paste_value(
457        &mut self,
458        stack: &mut ValueStack,
459        undo: &mut Undo,
460        redo: &mut Undo,
461        keyword: Option<&str>,
462    ) -> MyResult<Option<bool>> {
463        if let Some(clip) = &self.clip {
464            stack.push_single(undo, Rc::clone(clip), keyword);
465            redo.clear();
466            Ok(Some(true))
467        } else {
468            Err(MyError::from(EngineError::MissingClip))
469        }
470    }
471
472    pub fn import_file(
473        &mut self,
474        writer: &mut W,
475        stack: &mut ValueStack,
476        tokens: Vec<String>,
477    ) -> MyResult<bool> {
478        let reader = FileInput::new(&tokens);
479        self.parse_files(writer, stack, reader)?;
480        Ok(true)
481    }
482
483    pub fn export_file(
484        &mut self,
485        _writer: &mut W,
486        stack: &mut ValueStack,
487        tokens: Vec<String>,
488    ) -> MyResult<bool> {
489        if let Some(path) = tokens.first() {
490            let mut writer = File::create(path)?;
491            let sep = self.context.borrow_mut().swap_sep(false);
492            let result = self.write_simple(&mut writer, stack);
493            self.context.borrow_mut().swap_sep(sep);
494            result?;
495        }
496        Ok(false)
497    }
498
499    pub fn set_variable(
500        &mut self,
501        writer: &mut W,
502        stack: &mut ValueStack,
503        token: Option<String>,
504    ) -> MyResult<bool> {
505        if let Some(token) = token {
506            let value = stack.peek_single()?;
507            if self.interface.borrow_mut().insert_variable(token.clone(), Rc::clone(&value)) {
508                for (value, _) in stack.iter_stack() {
509                    Self::unassign_variable(value, &token);
510                }
511            }
512            self.reassign_variable(value, token);
513            self.interface.borrow().adjust_editor(&mut self.editor);
514            Ok(true)
515        } else {
516            let items = self.interface.borrow()
517                .get_variables()
518                .iter()
519                .sorted_by(|(lhs, _), (rhs, _)| String::cmp(lhs, rhs))
520                .map(|(_, value)| Rc::clone(value))
521                .map(|value| StackItem::Single(value))
522                .collect::<Vec<_>>();
523            let mut stack = ValueStack::new(items);
524            self.show_stack(writer, &mut stack)?;
525            Ok(false)
526        }
527    }
528
529    fn unassign_variable(value: ValueRef, token: &str) {
530        let mut inner = value.borrow_mut();
531        if let Some(previous) = &inner.variable {
532            if previous == token {
533                inner.variable = None;
534            }
535        }
536    }
537
538    fn reassign_variable(&mut self, value: ValueRef, token: String) {
539        let mut inner = value.borrow_mut();
540        if let Some(previous) = &inner.variable {
541            if previous != &token {
542                self.interface.borrow_mut().remove_variable(previous);
543            }
544        }
545        inner.variable = Some(token);
546    }
547
548    pub fn define_function(
549        &mut self,
550        writer: &mut W,
551        _stack: &mut ValueStack,
552        tokens: Vec<String>,
553    ) -> MyResult<bool> {
554        let mut tokens = tokens.iter();
555        if let Some(keyword) = tokens.next() {
556            let description = tokens.clone().join(" ");
557            let actions = self.parse_actions(tokens)?;
558            if !actions.is_empty() {
559                let (input, output) = action::fold_actions(&actions);
560                self.interface.borrow_mut().insert_definition(
561                    keyword,
562                    actions,
563                    input,
564                    output,
565                    description,
566                );
567            } else {
568                self.interface.borrow_mut().remove_definition(keyword);
569            }
570            self.interface.borrow().adjust_editor(&mut self.editor);
571        } else {
572            self.interface.borrow().show_definitions(writer, self.interact)?;
573        }
574        Ok(false)
575    }
576
577    pub fn apply_all(
578        &mut self,
579        writer: &mut W,
580        keyword: Option<&str>,
581        stack: &mut ValueStack,
582        undo: &mut Undo,
583        _redo: &mut Undo,
584        tokens: Vec<String>,
585    ) -> MyResult<bool> {
586        let actions = self.parse_actions(tokens.iter())?;
587        if let (Count::N(1), Count::N(1)) = action::fold_actions(&actions) {
588            let (input_values, as_series) = stack.pop_series(undo, None);
589            let mut output_values = Vec::new();
590            let mut temp_undo = Undo::new(0, vec![], vec![]);
591            let mut temp_redo = Undo::new(0, vec![], vec![]);
592            for value in input_values {
593                let mut temp_stack = ValueStack::new(Vec::new());
594                temp_stack.push_single(&mut temp_undo, value, None);
595                for action in &actions {
596                    self.apply_action(
597                        writer,
598                        &mut temp_stack,
599                        &mut temp_undo,
600                        &mut temp_redo,
601                        action.clone(),
602                        None,
603                    )?;
604                }
605                let (mut temp_values, _) = temp_stack.pop_series(&mut temp_undo, None);
606                output_values.append(&mut temp_values);
607            }
608            if !output_values.is_empty() {
609                if as_series {
610                    stack.push_series(undo, output_values, None);
611                } else {
612                    stack.push_singles(undo, output_values, None);
613                }
614                undo.add_tokens(keyword, tokens);
615                Ok(true)
616            } else {
617                Ok(false)
618            }
619        } else {
620            Err(MyError::Engine(EngineError::BadApplyOp))
621        }
622    }
623
624    fn parse_actions(
625        &mut self,
626        tokens: Iter<String>,
627    ) -> MyResult<Vec<Action<W>>> {
628        let tokens = tokens.map(String::as_ref);
629        let actions = Actions::new(&self.interface, tokens);
630        actions
631            .map(|result| result.map(|(x, _)| x))
632            .collect::<MyResult<Vec<Action<W>>>>()
633    }
634
635    pub fn undo_stack(
636        &mut self,
637        stack: &mut ValueStack,
638        undo: &mut Undo,
639        redo: &mut Undo,
640        _keyword: Option<&str>,
641    ) -> MyResult<Option<bool>> {
642        if !undo.is_empty() {
643            self.redos.push(undo.apply_to(stack));
644            redo.clear();
645            Ok(Some(true))
646        } else if let Some(mut undo) = self.undos.pop() {
647            self.redos.push(undo.apply_to(stack));
648            redo.clear();
649            Ok(Some(true))
650        } else {
651            Err(MyError::from(EngineError::MissingUndo))
652        }
653    }
654
655    pub fn redo_stack(
656        &mut self,
657        stack: &mut ValueStack,
658        undo: &mut Undo,
659        redo: &mut Undo,
660        _keyword: Option<&str>,
661    ) -> MyResult<Option<bool>> {
662        if undo.is_empty() {
663            if !redo.is_empty() {
664                self.undos.push(redo.apply_to(stack));
665                return Ok(Some(true));
666            } else if let Some(mut redo) = self.redos.pop() {
667                self.undos.push(redo.apply_to(stack));
668                return Ok(Some(true));
669            }
670        }
671        Err(MyError::from(EngineError::MissingRedo))
672    }
673
674    pub fn show_history(
675        &mut self,
676        writer: &mut W,
677        _stack: &mut ValueStack,
678    ) -> MyResult<Option<bool>> {
679        if self.interact {
680            self.limit_history(writer, PAGE_LIMIT)?;
681        }
682        Ok(Some(false))
683    }
684
685    fn limit_history(&mut self, writer: &mut W, limit: usize) -> MyResult<()> {
686        if self.undos.is_empty() {
687            writeln!(writer, "  <==")?;
688        } else {
689            if self.undos.len() > limit {
690                writeln!(writer, "  ...")?;
691            }
692            for (index, undo) in self.undos.iter().rev().enumerate().take(limit).rev() {
693                if index == 0 {
694                    writeln!(writer, "  {} <==", undo)?;
695                } else {
696                    writeln!(writer, "  {}", undo)?;
697                }
698            }
699        }
700        for redo in self.redos.iter().rev().take(limit) {
701            writeln!(writer, "  {}", redo)?;
702        }
703        if self.redos.len() > limit {
704            writeln!(writer, "  ...")?;
705        }
706        Ok(())
707    }
708
709    fn show_simple(
710        &mut self,
711        writer: &mut W,
712        stack: &mut ValueStack,
713    ) -> Result<(), MyError> {
714        if self.config.sum {
715            let mut undo = Undo::new(0, vec![], vec![]);
716            let (values, _) = stack.pop_series(&mut undo, None);
717            let result = Value::calc_sum(values)?;
718            stack.push_single(&mut undo, result, None);
719        }
720        if self.config.hex {
721            self.context.borrow_mut().set_hex();
722        }
723        if self.config.sep {
724            self.context.borrow_mut().set_sep();
725        }
726        if let Some(dp) = self.config.dp {
727            self.context.borrow_mut().set_dp_u8(dp);
728        }
729        self.write_simple(writer, stack)?;
730        Ok(())
731    }
732
733    fn write_simple<V: Write>(
734        &mut self,
735        writer: &mut V,
736        stack: &mut ValueStack,
737    ) -> MyResult<()> {
738        self.measure_hexadecimal(stack);
739        let context = self.context.borrow();
740        for (value, _) in stack.iter_stack() {
741            let (integer, fraction, _, _) = value.borrow().to_strings(&context);
742            writeln!(writer, "{}{}", integer, fraction)?;
743        }
744        Ok(())
745    }
746
747    pub fn show_stack(
748        &mut self,
749        writer: &mut W,
750        stack: &mut ValueStack,
751    ) -> MyResult<Option<bool>> {
752        self.limit_stack(writer, stack, None)?;
753        Ok(Some(false))
754    }
755
756    fn limit_stack(
757        &mut self,
758        writer: &mut W,
759        stack: &mut ValueStack,
760        limit: Option<usize>,
761    ) -> MyResult<()> {
762        if self.interact {
763            self.measure_hexadecimal(stack);
764            let context = self.context.borrow();
765            let table = match limit {
766                Some(limit) if limit < stack.total_len() => {
767                    // It is necessary to collect intermediate results
768                    // into a vector, or the double ended iterator is
769                    // not called.
770                    writeln!(writer, "  ...")?;
771                    stack.iter_stack()
772                        .rev()
773                        .take(limit)
774                        .collect::<Vec<_>>()
775                        .into_iter()
776                        .rev()
777                        .map(|(value, style)| (value.borrow().to_strings(&context), style))
778                        .collect::<Vec<_>>()
779                }
780                _ => {
781                    stack.iter_stack()
782                        .map(|(value, style)| (value.borrow().to_strings(&context), style))
783                        .collect::<Vec<_>>()
784                }
785            };
786            let integer_width = table.iter()
787                .map(|((x, _, _, _), _)| x.len())
788                .max()
789                .unwrap_or_default();
790            let fraction_width = table.iter()
791                .map(|((_, x, _, _), _)| x.len())
792                .max()
793                .unwrap_or_default();
794            for ((integer, fraction, variable, comment), style) in table {
795                let padding = create_padding(' ', integer_width + 1, integer.len(), 0);
796                let prefix = self.chars.get_prefix(style).unwrap_or(' ');
797                let suffix = self.chars.get_suffix(style);
798                write!(writer, "{}{}{}{}", prefix, padding, integer, fraction)?;
799                if suffix.is_some() || variable.is_some() || comment.is_some() {
800                    let padding = create_padding(' ', fraction_width, fraction.len(), 0);
801                    write!(writer, "{}", padding)?;
802                }
803                if let Some(suffix) = suffix {
804                    write!(writer, " {}", suffix)?;
805                }
806                if let Some(variable) = variable {
807                    write!(writer, " = {}", variable)?;
808                }
809                if let Some(comment) = comment {
810                    write!(writer, " # {}", comment)?;
811                }
812                writeln!(writer)?;
813            }
814        }
815        Ok(())
816    }
817
818    fn measure_hexadecimal(&mut self, stack: &ValueStack) {
819        let mut context = self.context.borrow_mut();
820        if let Format::Base16(_) = context.format {
821            let chunks = stack.iter_stack()
822                .map(|(value, _)| value.borrow().measure_hexadecimal())
823                .max()
824                .unwrap_or_default();
825            context.format = Format::Base16(chunks);
826        }
827    }
828
829    pub fn show_help(
830        &mut self,
831        writer: &mut W,
832        _stack: &mut ValueStack,
833    ) -> MyResult<Option<bool>> {
834        self.interface.borrow().show_help(writer, self.interact)?;
835        Ok(Some(false))
836    }
837}
838
839// noinspection DuplicatedCode
840#[cfg(test)]
841pub mod tests {
842    use crate::calc::context::Format;
843    use crate::calc::undo::tests::create_undo;
844    use crate::calc::value::tests::parse_value;
845    use crate::config::Config;
846    use crate::core::stack::tests::{parse_item, parse_items, parse_series};
847    use crate::core::stack::{BracketChars, ValueStack};
848    use crate::engine::Engine;
849    use crate::error::MyResult;
850    use crate::util::text::tests::BufferWriter;
851    use pretty_assertions::assert_eq;
852    use std::collections::HashMap;
853    use std::io::Write;
854
855    #[test]
856    fn test_split_comment_finds_first_hash() {
857        assert_eq!(Engine::<BufferWriter>::split_comment("\tone two three\t"), ("one two three", None));
858        assert_eq!(Engine::<BufferWriter>::split_comment("\tone two three #\t"), ("one two three", None));
859        assert_eq!(Engine::<BufferWriter>::split_comment("\tone # two # three\t"), ("one", Some("two # three")));
860    }
861
862    // VALUE CREATION
863
864    #[test]
865    fn test_create_values_modifies_stack() {
866        let expected_items = parse_items(vec!["1", "2", "3", "4", "5", "6"]);
867        let expected_undos = vec![
868            create_undo(3, vec![], vec!["1", "2", "3"]),
869            create_undo(3, vec![], vec!["4", "5", "6"]),
870        ];
871        let expected_redos = vec![];
872        let mut engine = create_engine();
873        let mut writer = BufferWriter::new();
874        let mut stack = ValueStack::new(Vec::new());
875        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
876        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
877        assert_eq!(stack.items, expected_items);
878        assert_eq!(engine.undos, expected_undos);
879        assert_eq!(engine.redos, expected_redos);
880        assert_eq!(writer.buffer, "");
881    }
882
883    #[test]
884    fn test_comment_modifies_current_line() {
885        let expected_items = vec![
886            parse_item("1"),
887            parse_item("2"),
888            parse_item("3"),
889            parse_item("42 # the answer"),
890        ];
891        let expected_undos = vec![
892            create_undo(2, vec![], vec!["1", "2"]),
893            create_undo(2, vec![], vec!["3", "42"]),
894        ];
895        let expected_redos = vec![];
896        let mut engine = create_engine();
897        let mut writer = BufferWriter::new();
898        let mut stack = ValueStack::new(Vec::new());
899        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
900        assert!(parse_line(&mut engine, &mut writer, &mut stack, "3 42 # the answer").is_ok());
901        assert_eq!(stack.items, expected_items);
902        assert_eq!(engine.undos, expected_undos);
903        assert_eq!(engine.redos, expected_redos);
904        assert_eq!(writer.buffer, "");
905    }
906
907    #[test]
908    fn test_comment_modifies_previous_line() {
909        let expected_items = vec![
910            parse_item("1"),
911            parse_item("2"),
912            parse_item("3"),
913            parse_item("42 # the answer"),
914        ];
915        let expected_undos = vec![
916            create_undo(4, vec![], vec!["1", "2", "3", "42"]),
917        ];
918        let expected_redos = vec![];
919        let mut engine = create_engine();
920        let mut writer = BufferWriter::new();
921        let mut stack = ValueStack::new(Vec::new());
922        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 42").is_ok());
923        assert!(parse_line(&mut engine, &mut writer, &mut stack, "# the answer").is_ok());
924        assert_eq!(stack.items, expected_items);
925        assert_eq!(engine.undos, expected_undos);
926        assert_eq!(engine.redos, expected_redos);
927        assert_eq!(writer.buffer, "");
928    }
929
930    #[test]
931    fn test_comment_fails_cleanly() {
932        let expected_items = vec![];
933        let expected_undos = vec![];
934        let expected_redos = vec![];
935        let mut engine = create_engine();
936        let mut writer = BufferWriter::new();
937        let mut stack = ValueStack::new(Vec::new());
938        assert!(parse_line(&mut engine, &mut writer, &mut stack, "# the answer").is_err());
939        assert_eq!(stack.items, expected_items);
940        assert_eq!(engine.undos, expected_undos);
941        assert_eq!(engine.redos, expected_redos);
942        assert_eq!(writer.buffer, "Not enough values on stack\n");
943    }
944
945    // UNKNOWN OPERATIONS
946
947    #[test]
948    fn test_unknown_operation_fails_cleanly() {
949        let expected_items = parse_items(vec!["1", "2", "3"]);
950        let expected_undos = vec![
951            create_undo(3, vec![], vec!["1", "2", "3"]),
952        ];
953        let expected_redos = vec![];
954        let mut engine = create_engine();
955        let mut writer = BufferWriter::new();
956        let mut stack = ValueStack::new(Vec::new());
957        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
958        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 xyz 999").is_err());
959        assert_eq!(stack.items, expected_items);
960        assert_eq!(engine.undos, expected_undos);
961        assert_eq!(engine.redos, expected_redos);
962        assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
963    }
964
965    // NULLARY OPERATIONS
966
967    #[test]
968    fn test_nullary_operation_modifies_stack() {
969        let expected_undos = vec![
970            create_undo(1, vec![], vec!["now"]),
971        ];
972        let expected_redos = vec![];
973        let mut engine = create_engine();
974        let mut writer = BufferWriter::new();
975        let mut stack = ValueStack::new(Vec::new());
976        assert!(parse_line(&mut engine, &mut writer, &mut stack, "now").is_ok());
977        assert_eq!(stack.wrapped_len(), 1);
978        assert_eq!(engine.undos, expected_undos);
979        assert_eq!(engine.redos, expected_redos);
980        assert_eq!(writer.buffer, "");
981    }
982
983    // UNARY OPERATIONS
984
985    #[test]
986    fn test_unary_operation_modifies_stack() {
987        let expected_items = parse_items(vec!["1", "-2"]);
988        let expected_undos = vec![
989            create_undo(3, vec![], vec!["1", "2", "3"]),
990            create_undo(1, vec!["2", "3"], vec!["pop", "neg"]),
991        ];
992        let expected_redos = vec![];
993        let mut engine = create_engine();
994        let mut writer = BufferWriter::new();
995        let mut stack = ValueStack::new(Vec::new());
996        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
997        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop neg").is_ok());
998        assert_eq!(stack.items, expected_items);
999        assert_eq!(engine.undos, expected_undos);
1000        assert_eq!(engine.redos, expected_redos);
1001        assert_eq!(writer.buffer, "");
1002    }
1003
1004    #[test]
1005    fn test_unary_operation_fails_cleanly() {
1006        let expected_items = parse_items(vec!["1", "2", "3"]);
1007        let expected_undos = vec![
1008            create_undo(3, vec![], vec!["1", "2", "3"]),
1009        ];
1010        let expected_redos = vec![];
1011        let mut engine = create_engine();
1012        let mut writer = BufferWriter::new();
1013        let mut stack = ValueStack::new(Vec::new());
1014        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1015        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop neg 999").is_err());
1016        assert_eq!(stack.items, expected_items);
1017        assert_eq!(engine.undos, expected_undos);
1018        assert_eq!(engine.redos, expected_redos);
1019        assert_eq!(writer.buffer, "Not enough values on stack\n");
1020    }
1021
1022    // BINARY OPERATIONS
1023
1024    #[test]
1025    fn test_binary_operation_modifies_stack() {
1026        let expected_items = parse_items(vec!["1", "5"]);
1027        let expected_undos = vec![
1028            create_undo(3, vec![], vec!["1", "2", "3"]),
1029            create_undo(1, vec!["2", "3"], vec!["add"]),
1030        ];
1031        let expected_redos = vec![];
1032        let mut engine = create_engine();
1033        let mut writer = BufferWriter::new();
1034        let mut stack = ValueStack::new(Vec::new());
1035        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1036        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1037        assert_eq!(stack.items, expected_items);
1038        assert_eq!(engine.undos, expected_undos);
1039        assert_eq!(engine.redos, expected_redos);
1040        assert_eq!(writer.buffer, "");
1041    }
1042
1043    #[test]
1044    fn test_binary_operation_fails_cleanly() {
1045        let expected_items = parse_items(vec!["1", "2", "3"]);
1046        let expected_undos = vec![
1047            create_undo(3, vec![], vec!["1", "2", "3"]),
1048        ];
1049        let expected_redos = vec![];
1050        let mut engine = create_engine();
1051        let mut writer = BufferWriter::new();
1052        let mut stack = ValueStack::new(Vec::new());
1053        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1054        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop add 999").is_err());
1055        assert_eq!(stack.items, expected_items);
1056        assert_eq!(engine.undos, expected_undos);
1057        assert_eq!(engine.redos, expected_redos);
1058        assert_eq!(writer.buffer, "Not enough values on stack\n");
1059    }
1060
1061    // SERIES OPERATIONS
1062
1063    #[test]
1064    fn test_series_to_value_operation_modifies_stack() {
1065        let expected_items = parse_items(vec!["6"]);
1066        let expected_undos = vec![
1067            create_undo(3, vec![], vec!["1", "2", "3"]),
1068            create_undo(1, vec!["1", "2", "3"], vec!["sum"]),
1069        ];
1070        let expected_redos = vec![];
1071        let mut engine = create_engine();
1072        let mut writer = BufferWriter::new();
1073        let mut stack = ValueStack::new(Vec::new());
1074        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1075        assert!(parse_line(&mut engine, &mut writer, &mut stack, "sum").is_ok());
1076        assert_eq!(stack.items, expected_items);
1077        assert_eq!(engine.undos, expected_undos);
1078        assert_eq!(engine.redos, expected_redos);
1079        assert_eq!(writer.buffer, "");
1080    }
1081
1082    #[test]
1083    fn test_binary_to_series_operation_modifies_stack() {
1084        let expected_items = parse_items(vec!["[1 2 3 4 5]"]);
1085        let expected_undos = vec![
1086            create_undo(2, vec![], vec!["1", "5"]),
1087            create_undo(1, vec!["1", "5"], vec!["seq"]),
1088        ];
1089        let expected_redos = vec![];
1090        let mut engine = create_engine();
1091        let mut writer = BufferWriter::new();
1092        let mut stack = ValueStack::new(Vec::new());
1093        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 5").is_ok());
1094        assert!(parse_line(&mut engine, &mut writer, &mut stack, "seq").is_ok());
1095        assert_eq!(stack.items, expected_items);
1096        assert_eq!(engine.undos, expected_undos);
1097        assert_eq!(engine.redos, expected_redos);
1098        assert_eq!(writer.buffer, "");
1099    }
1100
1101    #[test]
1102    fn test_binary_to_series_operation_fails_cleanly() {
1103        let expected_items = parse_items(vec!["1", "5"]);
1104        let expected_undos = vec![
1105            create_undo(2, vec![], vec!["1", "5"]),
1106        ];
1107        let expected_redos = vec![];
1108        let mut engine = create_engine();
1109        let mut writer = BufferWriter::new();
1110        let mut stack = ValueStack::new(Vec::new());
1111        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 5").is_ok());
1112        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop seq 999").is_err());
1113        assert_eq!(stack.items, expected_items);
1114        assert_eq!(engine.undos, expected_undos);
1115        assert_eq!(engine.redos, expected_redos);
1116        assert_eq!(writer.buffer, "Not enough values on stack\n");
1117    }
1118
1119    #[test]
1120    fn test_series_to_series_operation_modifies_stack() {
1121        let expected_items = parse_items(vec!["5", "4", "3", "2", "1"]);
1122        let expected_undos = vec![
1123            create_undo(5, vec![], vec!["1", "2", "3", "4", "5"]),
1124            create_undo(5, vec!["1", "2", "3", "4", "5"], vec!["rev"]),
1125        ];
1126        let expected_redos = vec![];
1127        let mut engine = create_engine();
1128        let mut writer = BufferWriter::new();
1129        let mut stack = ValueStack::new(Vec::new());
1130        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 5").is_ok());
1131        assert!(parse_line(&mut engine, &mut writer, &mut stack, "rev").is_ok());
1132        assert_eq!(stack.items, expected_items);
1133        assert_eq!(engine.undos, expected_undos);
1134        assert_eq!(engine.redos, expected_redos);
1135        assert_eq!(writer.buffer, "");
1136    }
1137
1138    #[test]
1139    fn test_series_to_series_operation_modifies_series() {
1140        let expected_items = parse_items(vec!["1", "2", "[5 4 3]"]);
1141        let expected_undos = vec![
1142            create_undo(3, vec![], vec!["1", "2", "3", "5", "seq"]),
1143            create_undo(1, vec!["[3 4 5]"], vec!["rev"]),
1144        ];
1145        let expected_redos = vec![];
1146        let mut engine = create_engine();
1147        let mut writer = BufferWriter::new();
1148        let mut stack = ValueStack::new(Vec::new());
1149        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 5 seq").is_ok());
1150        assert!(parse_line(&mut engine, &mut writer, &mut stack, "rev").is_ok());
1151        assert_eq!(stack.items, expected_items);
1152        assert_eq!(engine.undos, expected_undos);
1153        assert_eq!(engine.redos, expected_redos);
1154        assert_eq!(writer.buffer, "");
1155    }
1156
1157    // APPLY OPERATIONS
1158
1159    #[test]
1160    fn test_apply_unary_operation_modifies_empty() {
1161        let expected_items = vec![];
1162        let expected_undos = vec![];
1163        let expected_redos = vec![];
1164        let mut engine = create_engine();
1165        let mut writer = BufferWriter::new();
1166        let mut stack = ValueStack::new(Vec::new());
1167        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1168        assert_eq!(stack.items, expected_items);
1169        assert_eq!(engine.undos, expected_undos);
1170        assert_eq!(engine.redos, expected_redos);
1171        assert_eq!(writer.buffer, "");
1172    }
1173
1174    #[test]
1175    fn test_apply_unary_operation_modifies_stack() {
1176        let expected_items = parse_items(vec!["1", "4", "9", "16", "25", "36"]);
1177        let expected_undos = vec![
1178            create_undo(3, vec![], vec!["1", "2", "5", "seq", "6"]),
1179            create_undo(6, vec!["1", "[2 3 4 5]", "6"], vec!["apply", "2", "pow"]),
1180        ];
1181        let expected_redos = vec![];
1182        let mut engine = create_engine();
1183        let mut writer = BufferWriter::new();
1184        let mut stack = ValueStack::new(Vec::new());
1185        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 5 seq 6").is_ok());
1186        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1187        assert_eq!(stack.items, expected_items);
1188        assert_eq!(engine.undos, expected_undos);
1189        assert_eq!(engine.redos, expected_redos);
1190        assert_eq!(writer.buffer, "");
1191    }
1192
1193    #[test]
1194    fn test_apply_unary_operation_modifies_series() {
1195        let expected_items = parse_items(vec!["1", "2", "3", "[16 25 36]"]);
1196        let expected_undos = vec![
1197            create_undo(4, vec![], vec!["1", "2", "3", "4", "6", "seq"]),
1198            create_undo(1, vec!["[4 5 6]"], vec!["apply", "2", "pow"]),
1199        ];
1200        let expected_redos = vec![];
1201        let mut engine = create_engine();
1202        let mut writer = BufferWriter::new();
1203        let mut stack = ValueStack::new(Vec::new());
1204        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 6 seq").is_ok());
1205        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply 2 pow").is_ok());
1206        assert_eq!(stack.items, expected_items);
1207        assert_eq!(engine.undos, expected_undos);
1208        assert_eq!(engine.redos, expected_redos);
1209        assert_eq!(writer.buffer, "");
1210    }
1211
1212    #[test]
1213    fn test_apply_nullary_operation_fails_cleanly() {
1214        let expected_items = vec![];
1215        let expected_undos = vec![];
1216        let expected_redos = vec![];
1217        let mut engine = create_engine();
1218        let mut writer = BufferWriter::new();
1219        let mut stack = ValueStack::new(Vec::new());
1220        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply now").is_err());
1221        assert_eq!(stack.items, expected_items);
1222        assert_eq!(engine.undos, expected_undos);
1223        assert_eq!(engine.redos, expected_redos);
1224        assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1225    }
1226
1227    #[test]
1228    fn test_apply_binary_operation_fails_cleanly() {
1229        let expected_items = vec![];
1230        let expected_undos = vec![];
1231        let expected_redos = vec![];
1232        let mut engine = create_engine();
1233        let mut writer = BufferWriter::new();
1234        let mut stack = ValueStack::new(Vec::new());
1235        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply add").is_err());
1236        assert_eq!(stack.items, expected_items);
1237        assert_eq!(engine.undos, expected_undos);
1238        assert_eq!(engine.redos, expected_redos);
1239        assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1240    }
1241
1242    #[test]
1243    fn test_apply_series_operation_fails_cleanly() {
1244        let expected_items = vec![];
1245        let expected_undos = vec![];
1246        let expected_redos = vec![];
1247        let mut engine = create_engine();
1248        let mut writer = BufferWriter::new();
1249        let mut stack = ValueStack::new(Vec::new());
1250        assert!(parse_line(&mut engine, &mut writer, &mut stack, "apply sum").is_err());
1251        assert_eq!(stack.items, expected_items);
1252        assert_eq!(engine.undos, expected_undos);
1253        assert_eq!(engine.redos, expected_redos);
1254        assert_eq!(writer.buffer, "Unsupported apply operation (must be unary)\n");
1255    }
1256
1257    // CAST OPERATIONS
1258
1259    #[test]
1260    fn test_cast_modifies_current_line() {
1261        let expected_items = vec![
1262            parse_item("1"),
1263            parse_item("2"),
1264            parse_item("3"),
1265            parse_item("5025.678 [delta]"),
1266        ];
1267        let expected_undos = vec![
1268            create_undo(2, vec![], vec!["1", "2"]),
1269            create_undo(2, vec![], vec!["3", "5025.678", "delta"]),
1270        ];
1271        let expected_redos = vec![];
1272        let mut engine = create_engine();
1273        let mut writer = BufferWriter::new();
1274        let mut stack = ValueStack::new(Vec::new());
1275        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1276        assert!(parse_line(&mut engine, &mut writer, &mut stack, "3 5025.678 delta").is_ok());
1277        assert_eq!(stack.items, expected_items);
1278        assert_eq!(engine.undos, expected_undos);
1279        assert_eq!(engine.redos, expected_redos);
1280        assert_eq!(writer.buffer, "");
1281    }
1282
1283    #[test]
1284    fn test_cast_modifies_previous_line() {
1285        let expected_items = vec![
1286            parse_item("1"),
1287            parse_item("2"),
1288            parse_item("3"),
1289            parse_item("5025.678 [delta]"),
1290        ];
1291        let expected_undos = vec![
1292            create_undo(4, vec![], vec!["1", "2", "3", "5025.678"]),
1293            create_undo(1, vec!["5025.678"], vec!["delta"]),
1294        ];
1295        let expected_redos = vec![];
1296        let mut engine = create_engine();
1297        let mut writer = BufferWriter::new();
1298        let mut stack = ValueStack::new(Vec::new());
1299        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 5025.678").is_ok());
1300        assert!(parse_line(&mut engine, &mut writer, &mut stack, "delta").is_ok());
1301        assert_eq!(stack.items, expected_items);
1302        assert_eq!(engine.undos, expected_undos);
1303        assert_eq!(engine.redos, expected_redos);
1304        assert_eq!(writer.buffer, "");
1305    }
1306
1307    #[test]
1308    fn test_cast_fails_cleanly() {
1309        let expected_items = vec![];
1310        let expected_undos = vec![];
1311        let expected_redos = vec![];
1312        let mut engine = create_engine();
1313        let mut writer = BufferWriter::new();
1314        let mut stack = ValueStack::new(Vec::new());
1315        assert!(parse_line(&mut engine, &mut writer, &mut stack, "delta").is_err());
1316        assert_eq!(stack.items, expected_items);
1317        assert_eq!(engine.undos, expected_undos);
1318        assert_eq!(engine.redos, expected_redos);
1319        assert_eq!(writer.buffer, "Not enough values on stack\n");
1320    }
1321
1322    // FLAT OPERATIONS
1323
1324    #[test]
1325    fn test_flat_operation_leaves_stack_no_series() {
1326        let expected_items = parse_items(vec!["1", "2", "3", "4", "5"]);
1327        let expected_undos = vec![
1328            create_undo(5, vec![], vec!["1", "2", "3", "4", "5"]),
1329        ];
1330        let expected_redos = vec![];
1331        let mut engine = create_engine();
1332        let mut writer = BufferWriter::new();
1333        let mut stack = ValueStack::new(Vec::new());
1334        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 4 5").is_ok());
1335        assert!(parse_line(&mut engine, &mut writer, &mut stack, "flat").is_ok());
1336        assert_eq!(stack.items, expected_items);
1337        assert_eq!(engine.undos, expected_undos);
1338        assert_eq!(engine.redos, expected_redos);
1339        assert_eq!(writer.buffer, "");
1340    }
1341
1342    #[test]
1343    fn test_flat_operation_modifies_stack_with_series() {
1344        let expected_items = parse_items(vec!["1", "2", "3", "4", "5", "6", "7", "8"]);
1345        let expected_undos = vec![
1346            create_undo(5, vec![], vec!["1", "2", "3", "seq", "4", "5", "7", "seq", "8"]),
1347            create_undo(8, vec!["1", "[2 3]", "4", "[5 6 7]", "8"], vec!["flat"]),
1348        ];
1349        let expected_redos = vec![];
1350        let mut engine = create_engine();
1351        let mut writer = BufferWriter::new();
1352        let mut stack = ValueStack::new(Vec::new());
1353        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 seq 4 5 7 seq 8").is_ok());
1354        assert!(parse_line(&mut engine, &mut writer, &mut stack, "flat").is_ok());
1355        assert_eq!(stack.items, expected_items);
1356        assert_eq!(engine.undos, expected_undos);
1357        assert_eq!(engine.redos, expected_redos);
1358        assert_eq!(writer.buffer, "");
1359    }
1360
1361    // CLEAR OPERATIONS
1362
1363    #[test]
1364    fn test_clear_operation_modifies_stack() {
1365        let expected_items = vec![];
1366        let expected_undos = vec![
1367            create_undo(3, vec![], vec!["1", "2", "3"]),
1368            create_undo(0, vec!["1", "2", "3"], vec!["clear"]),
1369        ];
1370        let expected_redos = vec![];
1371        let mut engine = create_engine();
1372        let mut writer = BufferWriter::new();
1373        let mut stack = ValueStack::new(Vec::new());
1374        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1375        assert!(parse_line(&mut engine, &mut writer, &mut stack, "clear").is_ok());
1376        assert_eq!(stack.items, expected_items);
1377        assert_eq!(engine.undos, expected_undos);
1378        assert_eq!(engine.redos, expected_redos);
1379        assert_eq!(writer.buffer, "");
1380    }
1381
1382    // POP OPERATIONS
1383
1384    #[test]
1385    fn test_pop_operation_modifies_stack() {
1386        let expected_items = parse_items(vec!["1", "2"]);
1387        let expected_undos = vec![
1388            create_undo(3, vec![], vec!["1", "2", "3"]),
1389            create_undo(0, vec!["3"], vec!["pop"]),
1390        ];
1391        let expected_redos = vec![];
1392        let mut engine = create_engine();
1393        let mut writer = BufferWriter::new();
1394        let mut stack = ValueStack::new(Vec::new());
1395        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1396        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop").is_ok());
1397        assert_eq!(stack.items, expected_items);
1398        assert_eq!(engine.undos, expected_undos);
1399        assert_eq!(engine.redos, expected_redos);
1400        assert_eq!(writer.buffer, "");
1401    }
1402
1403    #[test]
1404    fn test_pop_operation_fails_cleanly() {
1405        let expected_items = parse_items(vec!["1", "2", "3"]);
1406        let expected_undos = vec![
1407            create_undo(3, vec![], vec!["1", "2", "3"]),
1408        ];
1409        let expected_redos = vec![];
1410        let mut engine = create_engine();
1411        let mut writer = BufferWriter::new();
1412        let mut stack = ValueStack::new(Vec::new());
1413        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1414        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop pop 999").is_err());
1415        assert_eq!(stack.items, expected_items);
1416        assert_eq!(engine.undos, expected_undos);
1417        assert_eq!(engine.redos, expected_redos);
1418        assert_eq!(writer.buffer, "Not enough values on stack\n");
1419    }
1420
1421    // DUP OPERATIONS
1422
1423    #[test]
1424    fn test_dup_operation_modifies_stack() {
1425        let expected_items = vec![
1426            parse_item("1"),
1427            parse_item("2"),
1428            parse_item("3 = x # comment"),
1429            parse_item("3 # comment"),
1430        ];
1431        let expected_undos = vec![
1432            create_undo(3, vec![], vec!["1", "2", "3"]),
1433            create_undo(1, vec![], vec!["dup"]),
1434        ];
1435        let expected_redos = vec![];
1436        let mut engine = create_engine();
1437        let mut writer = BufferWriter::new();
1438        let mut stack = ValueStack::new(Vec::new());
1439        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 = x # comment").is_ok());
1440        assert!(parse_line(&mut engine, &mut writer, &mut stack, "dup").is_ok());
1441        assert_eq!(stack.items, expected_items);
1442        assert_eq!(engine.undos, expected_undos);
1443        assert_eq!(engine.redos, expected_redos);
1444        assert_eq!(writer.buffer, "");
1445    }
1446
1447    #[test]
1448    fn test_dup_operation_fails_cleanly() {
1449        let expected_items = vec![
1450            parse_item("1"),
1451            parse_item("2"),
1452            parse_item("3 = x # comment"),
1453        ];
1454        let expected_undos = vec![
1455            create_undo(3, vec![], vec!["1", "2", "3"]),
1456        ];
1457        let expected_redos = vec![];
1458        let mut engine = create_engine();
1459        let mut writer = BufferWriter::new();
1460        let mut stack = ValueStack::new(Vec::new());
1461        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3 = x # comment").is_ok());
1462        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop pop dup 999").is_err());
1463        assert_eq!(stack.items, expected_items);
1464        assert_eq!(engine.undos, expected_undos);
1465        assert_eq!(engine.redos, expected_redos);
1466        assert_eq!(writer.buffer, "Not enough values on stack\n");
1467    }
1468
1469    // SWAP OPERATIONS
1470
1471    #[test]
1472    fn test_swap_operation_modifies_stack() {
1473        let expected_items = parse_items(vec!["1", "3", "2"]);
1474        let expected_undos = vec![
1475            create_undo(3, vec![], vec!["1", "2", "3"]),
1476            create_undo(2, vec!["2", "3"], vec!["swap"]),
1477        ];
1478        let expected_redos = vec![];
1479        let mut engine = create_engine();
1480        let mut writer = BufferWriter::new();
1481        let mut stack = ValueStack::new(Vec::new());
1482        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1483        assert!(parse_line(&mut engine, &mut writer, &mut stack, "swap").is_ok());
1484        assert_eq!(stack.items, expected_items);
1485        assert_eq!(engine.undos, expected_undos);
1486        assert_eq!(engine.redos, expected_redos);
1487        assert_eq!(writer.buffer, "");
1488    }
1489
1490    #[test]
1491    fn test_swap_operation_fails_cleanly() {
1492        let expected_items = parse_items(vec!["1", "2", "3"]);
1493        let expected_undos = vec![
1494            create_undo(3, vec![], vec!["1", "2", "3"]),
1495        ];
1496        let expected_redos = vec![];
1497        let mut engine = create_engine();
1498        let mut writer = BufferWriter::new();
1499        let mut stack = ValueStack::new(Vec::new());
1500        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1501        assert!(parse_line(&mut engine, &mut writer, &mut stack, "pop pop swap 999").is_err());
1502        assert_eq!(stack.items, expected_items);
1503        assert_eq!(engine.undos, expected_undos);
1504        assert_eq!(engine.redos, expected_redos);
1505        assert_eq!(writer.buffer, "Not enough values on stack\n");
1506    }
1507
1508    // CUT OPERATIONS
1509
1510    #[test]
1511    fn test_cut_operation_copies_value() {
1512        let expected_items = vec![];
1513        let expected_undos = vec![
1514            create_undo(1, vec![], vec!["42"]),
1515            create_undo(0, vec!["42"], vec!["cut"]),
1516        ];
1517        let expected_redos = vec![];
1518        let mut engine = create_engine();
1519        let mut writer = BufferWriter::new();
1520        let mut stack = ValueStack::new(Vec::new());
1521        assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1522        assert!(parse_line(&mut engine, &mut writer, &mut stack, "cut").is_ok());
1523        assert_eq!(stack.items, expected_items);
1524        assert_eq!(engine.undos, expected_undos);
1525        assert_eq!(engine.redos, expected_redos);
1526        assert_eq!(engine.clip, Some(parse_value("42")));
1527        assert_eq!(writer.buffer, "");
1528    }
1529
1530    #[test]
1531    fn test_cut_operation_fails_cleanly() {
1532        let expected_items = vec![];
1533        let expected_undos = vec![];
1534        let expected_redos = vec![];
1535        let mut engine = create_engine();
1536        let mut writer = BufferWriter::new();
1537        let mut stack = ValueStack::new(Vec::new());
1538        assert!(parse_line(&mut engine, &mut writer, &mut stack, "cut").is_err());
1539        assert_eq!(stack.items, expected_items);
1540        assert_eq!(engine.undos, expected_undos);
1541        assert_eq!(engine.redos, expected_redos);
1542        assert_eq!(engine.clip, None);
1543        assert_eq!(writer.buffer, "Not enough values on stack\n");
1544    }
1545
1546    // COPY OPERATIONS
1547
1548    #[test]
1549    fn test_copy_operation_copies_value() {
1550        let expected_items = parse_items(vec!["42 = x # comment"]);
1551        let expected_undos = vec![
1552            create_undo(1, vec![], vec!["42"]),
1553        ];
1554        let expected_redos = vec![];
1555        let mut engine = create_engine();
1556        let mut writer = BufferWriter::new();
1557        let mut stack = ValueStack::new(Vec::new());
1558        assert!(parse_line(&mut engine, &mut writer, &mut stack, "42 = x # comment").is_ok());
1559        assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_ok());
1560        assert_eq!(stack.items, expected_items);
1561        assert_eq!(engine.undos, expected_undos);
1562        assert_eq!(engine.redos, expected_redos);
1563        assert_eq!(engine.clip, Some(parse_value("42 # comment")));
1564        assert_eq!(writer.buffer, "");
1565    }
1566
1567    #[test]
1568    fn test_copy_operation_fails_cleanly() {
1569        let expected_items = vec![];
1570        let expected_undos = vec![];
1571        let expected_redos = vec![];
1572        let mut engine = create_engine();
1573        let mut writer = BufferWriter::new();
1574        let mut stack = ValueStack::new(Vec::new());
1575        assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_err());
1576        assert_eq!(stack.items, expected_items);
1577        assert_eq!(engine.undos, expected_undos);
1578        assert_eq!(engine.redos, expected_redos);
1579        assert_eq!(engine.clip, None);
1580        assert_eq!(writer.buffer, "Not enough values on stack\n");
1581    }
1582
1583    // PASTE OPERATIONS
1584
1585    #[test]
1586    fn test_paste_operation_copies_value() {
1587        let expected_items = parse_items(vec!["42", "42"]);
1588        let expected_undos = vec![
1589            create_undo(1, vec![], vec!["42"]),
1590            create_undo(1, vec![], vec!["paste"]),
1591        ];
1592        let expected_redos = vec![];
1593        let mut engine = create_engine();
1594        let mut writer = BufferWriter::new();
1595        let mut stack = ValueStack::new(Vec::new());
1596        assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1597        assert!(parse_line(&mut engine, &mut writer, &mut stack, "copy").is_ok());
1598        assert!(parse_line(&mut engine, &mut writer, &mut stack, "paste").is_ok());
1599        assert_eq!(stack.items, expected_items);
1600        assert_eq!(engine.undos, expected_undos);
1601        assert_eq!(engine.redos, expected_redos);
1602        assert_eq!(engine.clip, Some(parse_value("42")));
1603        assert_eq!(writer.buffer, "");
1604    }
1605
1606    #[test]
1607    fn test_paste_operation_fails_cleanly() {
1608        let expected_items = parse_items(vec!["42"]);
1609        let expected_undos = vec![
1610            create_undo(1, vec![], vec!["42"]),
1611        ];
1612        let expected_redos = vec![];
1613        let mut engine = create_engine();
1614        let mut writer = BufferWriter::new();
1615        let mut stack = ValueStack::new(Vec::new());
1616        assert!(parse_line(&mut engine, &mut writer, &mut stack, "42").is_ok());
1617        assert!(parse_line(&mut engine, &mut writer, &mut stack, "paste").is_err());
1618        assert_eq!(stack.items, expected_items);
1619        assert_eq!(engine.undos, expected_undos);
1620        assert_eq!(engine.redos, expected_redos);
1621        assert_eq!(engine.clip, None);
1622        assert_eq!(writer.buffer, "No value on clipboard\n");
1623    }
1624
1625    // UNDO OPERATIONS
1626
1627    #[test]
1628    fn test_single_undo_resets_previous_line() {
1629        let expected_items = parse_items(vec!["4", "5", "6"]);
1630        let expected_undos = vec![
1631            create_undo(3, vec![], vec!["4", "5", "6"]),
1632        ];
1633        let expected_redos = vec![
1634            create_undo(2, vec!["11"], vec!["add"]),
1635        ];
1636        let mut engine = create_engine();
1637        let mut writer = BufferWriter::new();
1638        let mut stack = ValueStack::new(Vec::new());
1639        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1640        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1641        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo").is_ok());
1642        assert_eq!(stack.items, expected_items);
1643        assert_eq!(engine.undos, expected_undos);
1644        assert_eq!(engine.redos, expected_redos);
1645        assert_eq!(writer.buffer, "");
1646    }
1647
1648    #[test]
1649    fn test_double_undo_resets_previous_lines() {
1650        let expected_items = vec![];
1651        let expected_undos = vec![];
1652        let expected_redos = vec![
1653            create_undo(2, vec!["11"], vec!["add"]),
1654            create_undo(0, vec!["4", "5", "6"], vec!["4", "5", "6"]),
1655        ];
1656        let mut engine = create_engine();
1657        let mut writer = BufferWriter::new();
1658        let mut stack = ValueStack::new(Vec::new());
1659        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1660        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1661        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1662        assert_eq!(stack.items, expected_items);
1663        assert_eq!(engine.undos, expected_undos);
1664        assert_eq!(engine.redos, expected_redos);
1665        assert_eq!(writer.buffer, "");
1666    }
1667
1668    #[test]
1669    fn test_single_undo_with_suffix_resets_previous_line() {
1670        let expected_items = parse_items(vec!["4", "30"]);
1671        let expected_undos = vec![
1672            create_undo(3, vec![], vec!["4", "5", "6"]),
1673            create_undo(1, vec!["5", "6"], vec!["mul"]),
1674        ];
1675        let expected_redos = vec![];
1676        let mut engine = create_engine();
1677        let mut writer = BufferWriter::new();
1678        let mut stack = ValueStack::new(Vec::new());
1679        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1680        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1681        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo mul").is_ok());
1682        assert_eq!(stack.items, expected_items);
1683        assert_eq!(engine.undos, expected_undos);
1684        assert_eq!(engine.redos, expected_redos);
1685        assert_eq!(writer.buffer, "");
1686    }
1687
1688    #[test]
1689    fn test_double_undo_with_suffix_resets_previous_lines() {
1690        let expected_items = parse_items(vec!["1", "6"]);
1691        let expected_undos = vec![
1692            create_undo(3, vec![], vec!["1", "2", "3"]),
1693            create_undo(1, vec!["2", "3"], vec!["mul"]),
1694        ];
1695        let expected_redos = vec![];
1696        let mut engine = create_engine();
1697        let mut writer = BufferWriter::new();
1698        let mut stack = ValueStack::new(Vec::new());
1699        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1700        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1701        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1702        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo mul").is_ok());
1703        assert_eq!(stack.items, expected_items);
1704        assert_eq!(engine.undos, expected_undos);
1705        assert_eq!(engine.redos, expected_redos);
1706        assert_eq!(writer.buffer, "");
1707    }
1708
1709    #[test]
1710    fn test_single_undo_with_prefix_resets_current_line() {
1711        let expected_items = parse_items(vec!["4", "11"]);
1712        let expected_undos = vec![
1713            create_undo(3, vec![], vec!["4", "5", "6"]),
1714            create_undo(1, vec!["5", "6"], vec!["add"]),
1715        ];
1716        let expected_redos = vec![
1717            create_undo(2, vec!["15"], vec!["add"]),
1718        ];
1719        let mut engine = create_engine();
1720        let mut writer = BufferWriter::new();
1721        let mut stack = ValueStack::new(Vec::new());
1722        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1723        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1724        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo").is_ok());
1725        assert_eq!(stack.items, expected_items);
1726        assert_eq!(engine.undos, expected_undos);
1727        assert_eq!(engine.redos, expected_redos);
1728        assert_eq!(writer.buffer, "");
1729    }
1730
1731    #[test]
1732    fn test_double_undo_with_prefix_resets_current_and_previous_lines() {
1733        let expected_items = parse_items(vec!["4", "5", "6"]);
1734        let expected_undos = vec![
1735            create_undo(3, vec![], vec!["4", "5", "6"]),
1736        ];
1737        let expected_redos = vec![
1738            create_undo(2, vec!["15"], vec!["add"]),
1739            create_undo(2, vec!["11"], vec!["add"]),
1740        ];
1741        let mut engine = create_engine();
1742        let mut writer = BufferWriter::new();
1743        let mut stack = ValueStack::new(Vec::new());
1744        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1745        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1746        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo undo").is_ok());
1747        assert_eq!(stack.items, expected_items);
1748        assert_eq!(engine.undos, expected_undos);
1749        assert_eq!(engine.redos, expected_redos);
1750        assert_eq!(writer.buffer, "");
1751    }
1752
1753    #[test]
1754    fn test_single_undo_with_prefix_and_suffix_resets_current_line() {
1755        let expected_items = parse_items(vec!["44"]);
1756        let expected_undos = vec![
1757            create_undo(3, vec![], vec!["4", "5", "6"]),
1758            create_undo(1, vec!["5", "6"], vec!["add"]),
1759            create_undo(1, vec!["4", "11"], vec!["mul"]),
1760        ];
1761        let expected_redos = vec![];
1762        let mut engine = create_engine();
1763        let mut writer = BufferWriter::new();
1764        let mut stack = ValueStack::new(Vec::new());
1765        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1766        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1767        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo mul").is_ok());
1768        assert_eq!(stack.items, expected_items);
1769        assert_eq!(engine.undos, expected_undos);
1770        assert_eq!(engine.redos, expected_redos);
1771        assert_eq!(writer.buffer, "");
1772    }
1773
1774    #[test]
1775    fn test_double_undo_with_prefix_and_suffix_resets_current_and_previous_lines() {
1776        let expected_items = parse_items(vec!["4", "30"]);
1777        let expected_undos = vec![
1778            create_undo(3, vec![], vec!["4", "5", "6"]),
1779            create_undo(1, vec!["5", "6"], vec!["mul"]),
1780        ];
1781        let expected_redos = vec![];
1782        let mut engine = create_engine();
1783        let mut writer = BufferWriter::new();
1784        let mut stack = ValueStack::new(Vec::new());
1785        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1786        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1787        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add undo undo mul").is_ok());
1788        assert_eq!(stack.items, expected_items);
1789        assert_eq!(engine.undos, expected_undos);
1790        assert_eq!(engine.redos, expected_redos);
1791        assert_eq!(writer.buffer, "");
1792    }
1793
1794    #[test]
1795    fn test_triple_undo_operation_fails_cleanly() {
1796        let expected_items = vec![];
1797        let expected_undos = vec![];
1798        let expected_redos = vec![
1799            create_undo(2, vec!["11"], vec!["add"]),
1800            create_undo(0, vec!["4", "5", "6"], vec!["4", "5", "6"]),
1801        ];
1802        let mut engine = create_engine();
1803        let mut writer = BufferWriter::new();
1804        let mut stack = ValueStack::new(Vec::new());
1805        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1806        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1807        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo undo").is_err());
1808        assert_eq!(stack.items, expected_items);
1809        assert_eq!(engine.undos, expected_undos);
1810        assert_eq!(engine.redos, expected_redos);
1811        assert_eq!(writer.buffer, "Start of undo history\n");
1812    }
1813
1814    // REDO OPERATIONS
1815
1816    #[test]
1817    fn test_single_redo_operation_modifies_stack() {
1818        let expected_items = parse_items(vec!["4", "11"]);
1819        let expected_undos = vec![
1820            create_undo(3, vec![], vec!["4", "5", "6"]),
1821            create_undo(1, vec!["5", "6"], vec!["add"]),
1822        ];
1823        let expected_redos = vec![
1824            create_undo(2, vec!["15"], vec!["add"]),
1825        ];
1826        let mut engine = create_engine();
1827        let mut writer = BufferWriter::new();
1828        let mut stack = ValueStack::new(Vec::new());
1829        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1830        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1831        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1832        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1833        assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo").is_ok());
1834        assert_eq!(stack.items, expected_items);
1835        assert_eq!(engine.undos, expected_undos);
1836        assert_eq!(engine.redos, expected_redos);
1837        assert_eq!(writer.buffer, "");
1838    }
1839
1840    #[test]
1841    fn test_double_redo_operation_modifies_stack() {
1842        let expected_items = parse_items(vec!["15"]);
1843        let expected_undos = vec![
1844            create_undo(3, vec![], vec!["4", "5", "6"]),
1845            create_undo(1, vec!["5", "6"], vec!["add"]),
1846            create_undo(1, vec!["4", "11"], vec!["add"]),
1847        ];
1848        let expected_redos = vec![];
1849        let mut engine = create_engine();
1850        let mut writer = BufferWriter::new();
1851        let mut stack = ValueStack::new(Vec::new());
1852        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1853        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1854        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1855        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1856        assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo redo").is_ok());
1857        assert_eq!(stack.items, expected_items);
1858        assert_eq!(engine.undos, expected_undos);
1859        assert_eq!(engine.redos, expected_redos);
1860        assert_eq!(writer.buffer, "");
1861    }
1862
1863    #[test]
1864    fn test_single_redo_operation_with_prefix_fails_cleanly() {
1865        let expected_items = parse_items(vec!["4", "5", "6"]);
1866        let expected_undos = vec![
1867            create_undo(3, vec![], vec!["4", "5", "6"]),
1868        ];
1869        let expected_redos = vec![
1870            create_undo(2, vec!["15"], vec!["add"]),
1871            create_undo(2, vec!["11"], vec!["add"]),
1872        ];
1873        let mut engine = create_engine();
1874        let mut writer = BufferWriter::new();
1875        let mut stack = ValueStack::new(Vec::new());
1876        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1877        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1878        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1879        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1880        assert!(parse_line(&mut engine, &mut writer, &mut stack, "mul redo 999").is_err());
1881        assert_eq!(stack.items, expected_items);
1882        assert_eq!(engine.undos, expected_undos);
1883        assert_eq!(engine.redos, expected_redos);
1884        assert_eq!(writer.buffer, "End of undo history\n");
1885    }
1886
1887    #[test]
1888    fn test_triple_redo_operation_fails_cleanly() {
1889        let expected_items = parse_items(vec!["15"]);
1890        let expected_undos = vec![
1891            create_undo(3, vec![], vec!["4", "5", "6"]),
1892            create_undo(1, vec!["5", "6"], vec!["add"]),
1893            create_undo(1, vec!["4", "11"], vec!["add"]),
1894        ];
1895        let expected_redos = vec![];
1896        let mut engine = create_engine();
1897        let mut writer = BufferWriter::new();
1898        let mut stack = ValueStack::new(Vec::new());
1899        assert!(parse_line(&mut engine, &mut writer, &mut stack, "4 5 6").is_ok());
1900        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1901        assert!(parse_line(&mut engine, &mut writer, &mut stack, "add").is_ok());
1902        assert!(parse_line(&mut engine, &mut writer, &mut stack, "undo undo").is_ok());
1903        assert!(parse_line(&mut engine, &mut writer, &mut stack, "redo redo redo 999").is_err());
1904        assert_eq!(stack.items, expected_items);
1905        assert_eq!(engine.undos, expected_undos);
1906        assert_eq!(engine.redos, expected_redos);
1907        assert_eq!(writer.buffer, "End of undo history\n");
1908    }
1909
1910    // VARIABLE ASSIGNMENT
1911
1912    #[test]
1913    fn test_variable_not_assigned_by_default() {
1914        let expected_items = vec![
1915            parse_item("1"),
1916            parse_item("2"),
1917            parse_item("3"),
1918        ];
1919        let expected_variables = HashMap::new();
1920        let mut engine = create_engine();
1921        let mut writer = BufferWriter::new();
1922        let mut stack = ValueStack::new(Vec::new());
1923        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1924        assert_eq!(stack.items, expected_items);
1925        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1926    }
1927
1928    #[test]
1929    fn test_variable_is_assigned_to_new_entry() {
1930        let expected_items = vec![
1931            parse_item("1"),
1932            parse_item("2 = foo"),
1933            parse_item("3"),
1934        ];
1935        let expected_variables = HashMap::from([
1936            (String::from("foo"), parse_value("2 = foo")),
1937        ]);
1938        let mut engine = create_engine();
1939        let mut writer = BufferWriter::new();
1940        let mut stack = ValueStack::new(Vec::new());
1941        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1942        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1943        assert!(parse_line(&mut engine, &mut writer, &mut stack, "3").is_ok());
1944        assert_eq!(stack.items, expected_items);
1945        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1946    }
1947
1948    #[test]
1949    fn test_variable_is_reassigned_to_new_entry() {
1950        let expected_items = vec![
1951            parse_item("1"),
1952            parse_item("2"),
1953            parse_item("3 = foo"),
1954        ];
1955        let expected_variables = HashMap::from([
1956            (String::from("foo"), parse_value("3 = foo")),
1957        ]);
1958        let mut engine = create_engine();
1959        let mut writer = BufferWriter::new();
1960        let mut stack = ValueStack::new(Vec::new());
1961        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2").is_ok());
1962        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1963        assert!(parse_line(&mut engine, &mut writer, &mut stack, "3").is_ok());
1964        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1965        assert_eq!(stack.items, expected_items);
1966        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1967    }
1968
1969    #[test]
1970    fn test_variable_is_replaced_with_same_name() {
1971        let expected_items = vec![
1972            parse_item("1"),
1973            parse_item("2"),
1974            parse_item("3 = foo"),
1975        ];
1976        let expected_variables = HashMap::from([
1977            (String::from("foo"), parse_value("3 = foo")),
1978        ]);
1979        let mut engine = create_engine();
1980        let mut writer = BufferWriter::new();
1981        let mut stack = ValueStack::new(Vec::new());
1982        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
1983        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1984        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
1985        assert_eq!(stack.items, expected_items);
1986        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
1987    }
1988
1989    #[test]
1990    fn test_variable_is_replaced_with_new_name() {
1991        let expected_items = vec![
1992            parse_item("1"),
1993            parse_item("2"),
1994            parse_item("3 = bar"),
1995        ];
1996        let expected_variables = HashMap::from([
1997            (String::from("bar"), parse_value("3 = bar")),
1998        ]);
1999        let mut engine = create_engine();
2000        let mut writer = BufferWriter::new();
2001        let mut stack = ValueStack::new(Vec::new());
2002        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 2 3").is_ok());
2003        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_ok());
2004        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set bar").is_ok());
2005        assert_eq!(stack.items, expected_items);
2006        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2007    }
2008
2009    #[test]
2010    fn test_variable_assignment_fails_cleanly() {
2011        let expected_variables = HashMap::new();
2012        let mut engine = create_engine();
2013        let mut writer = BufferWriter::new();
2014        let mut stack = ValueStack::new(Vec::new());
2015        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set foo").is_err());
2016        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2017        assert_eq!(writer.buffer, "Not enough values on stack\n");
2018    }
2019
2020    #[test]
2021    fn test_variables_are_assigned_on_same_line() {
2022        let expected_items = vec![
2023            parse_item("1 = foo"),
2024            parse_item("2 = bar"),
2025            parse_item("3 = baz"),
2026        ];
2027        let expected_variables = HashMap::from([
2028            (String::from("foo"), parse_value("1 = foo")),
2029            (String::from("bar"), parse_value("2 = bar")),
2030            (String::from("baz"), parse_value("3 = baz")),
2031        ]);
2032        let mut engine = create_engine();
2033        let mut writer = BufferWriter::new();
2034        let mut stack = ValueStack::new(Vec::new());
2035        assert!(parse_line(&mut engine, &mut writer, &mut stack, "1 = foo 2 = bar 3 = baz").is_ok());
2036        assert_eq!(stack.items, expected_items);
2037        assert_eq!(engine.interface.borrow().get_variables(), &expected_variables);
2038    }
2039
2040    // TEXT OUTPUT
2041
2042    #[test]
2043    fn test_prints_error_on_invalid_decimal() {
2044        let mut engine = create_engine();
2045        let mut writer = BufferWriter::new();
2046        let mut stack = ValueStack::new(Vec::new());
2047        assert!(parse_line(&mut engine, &mut writer, &mut stack, "xyz").is_err());
2048        assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
2049    }
2050
2051    #[test]
2052    fn test_prints_error_on_invalid_hexadecimal() {
2053        let mut engine = create_engine();
2054        let mut writer = BufferWriter::new();
2055        let mut stack = ValueStack::new(Vec::new());
2056        engine.context.borrow_mut().set_hex();
2057        assert!(parse_line(&mut engine, &mut writer, &mut stack, "xyz").is_err());
2058        assert_eq!(writer.buffer, "Invalid number or keyword: xyz\n");
2059    }
2060
2061    #[test]
2062    fn test_shows_history_from_start() {
2063        let expected = "\
2064<==
2065111
2066222
2067333 444 555
2068666 777
2069...
2070";
2071        let mut engine = create_engine();
2072        let mut writer = BufferWriter::new();
2073        engine.redos.insert(0, create_undo(0, vec![], vec!["111"]));
2074        engine.redos.insert(0, create_undo(0, vec![], vec!["222"]));
2075        engine.redos.insert(0, create_undo(0, vec![], vec!["333", "444", "555"]));
2076        engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2077        engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2078        engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2079        assert!(engine.limit_history(&mut writer, 4).is_ok());
2080        assert_eq!(writer.buffer, indent_multiline(expected));
2081    }
2082
2083    #[test]
2084    fn test_shows_history_with_lower_limit() {
2085        let expected = "\
2086...
2087222
2088333 444 555 <==
2089666 777
2090888
2091...
2092";
2093        let mut engine = create_engine();
2094        let mut writer = BufferWriter::new();
2095        engine.undos.push(create_undo(0, vec![], vec!["111"]));
2096        engine.undos.push(create_undo(0, vec![], vec!["222"]));
2097        engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2098        engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2099        engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2100        engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2101        assert!(engine.limit_history(&mut writer, 2).is_ok());
2102        assert_eq!(writer.buffer, indent_multiline(expected));
2103    }
2104
2105    #[test]
2106    fn test_shows_history_with_equal_limit() {
2107        let expected = "\
2108111
2109222
2110333 444 555 <==
2111666 777
2112888
2113999
2114";
2115        let mut engine = create_engine();
2116        let mut writer = BufferWriter::new();
2117        engine.undos.push(create_undo(0, vec![], vec!["111"]));
2118        engine.undos.push(create_undo(0, vec![], vec!["222"]));
2119        engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2120        engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2121        engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2122        engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2123        assert!(engine.limit_history(&mut writer, 3).is_ok());
2124        assert_eq!(writer.buffer, indent_multiline(expected));
2125    }
2126
2127    #[test]
2128    fn test_shows_history_with_higher_limit() {
2129        let expected = "\
2130111
2131222
2132333 444 555 <==
2133666 777
2134888
2135999
2136";
2137        let mut engine = create_engine();
2138        let mut writer = BufferWriter::new();
2139        engine.undos.push(create_undo(0, vec![], vec!["111"]));
2140        engine.undos.push(create_undo(0, vec![], vec!["222"]));
2141        engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2142        engine.redos.insert(0, create_undo(0, vec![], vec!["666", "777"]));
2143        engine.redos.insert(0, create_undo(0, vec![], vec!["888"]));
2144        engine.redos.insert(0, create_undo(0, vec![], vec!["999"]));
2145        assert!(engine.limit_history(&mut writer, 4).is_ok());
2146        assert_eq!(writer.buffer, indent_multiline(expected));
2147    }
2148
2149    #[test]
2150    fn test_shows_history_to_end() {
2151        let expected = "\
2152...
2153333 444 555
2154666 777
2155888
2156999 <==
2157";
2158        let mut engine = create_engine();
2159        let mut writer = BufferWriter::new();
2160        engine.undos.push(create_undo(0, vec![], vec!["111"]));
2161        engine.undos.push(create_undo(0, vec![], vec!["222"]));
2162        engine.undos.push(create_undo(0, vec![], vec!["333", "444", "555"]));
2163        engine.undos.push(create_undo(0, vec![], vec!["666", "777"]));
2164        engine.undos.push(create_undo(0, vec![], vec!["888"]));
2165        engine.undos.push(create_undo(0, vec![], vec!["999"]));
2166        assert!(engine.limit_history(&mut writer, 4).is_ok());
2167        assert_eq!(writer.buffer, indent_multiline(expected));
2168    }
2169
2170    #[test]
2171    fn test_shows_stack_with_no_values() {
2172        let mut engine = create_engine();
2173        let mut writer = BufferWriter::new();
2174        let mut stack = ValueStack::new(Vec::new());
2175        assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2176        assert_eq!(writer.buffer, "");
2177    }
2178
2179    #[test]
2180    fn test_shows_stack_as_decimal() {
2181        let expected = "\
218299999
218399999     # integer value
218499999     = foo
218599999     = bar # integer value
2186  123.45
2187  123.45  # decimal value
2188  123.45  = baz
2189  123.45  = qux # decimal value
2190    3.142
2191    3.142 # decimal value
2192    3.142 = quux
2193    3.142 = quuux # decimal value
2194";
2195        let mut engine = create_engine();
2196        let mut writer = BufferWriter::new();
2197        let mut stack = ValueStack::new(Vec::new());
2198        stack.wrapped_push(parse_item("99999"));
2199        stack.wrapped_push(parse_item("99999 # integer value"));
2200        stack.wrapped_push(parse_item("99999 = foo"));
2201        stack.wrapped_push(parse_item("99999 = bar # integer value"));
2202        stack.wrapped_push(parse_item("123.45"));
2203        stack.wrapped_push(parse_item("123.45 # decimal value"));
2204        stack.wrapped_push(parse_item("123.45 = baz"));
2205        stack.wrapped_push(parse_item("123.45 = qux # decimal value"));
2206        stack.wrapped_push(parse_item("3.142"));
2207        stack.wrapped_push(parse_item("3.142 # decimal value"));
2208        stack.wrapped_push(parse_item("3.142 = quux"));
2209        stack.wrapped_push(parse_item("3.142 = quuux # decimal value"));
2210        assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2211        assert_eq!(writer.buffer, indent_multiline(expected));
2212    }
2213
2214    #[test]
2215    fn test_shows_stack_as_single_hexadecimal_no_sep() {
2216        let expected = "\
22170x7fffffff
22180x7fffffff # large value
22190x7fffffff = foo
22200x7fffffff = bar # large value
22210x00000001
22220x00000001 # small value
22230x00000001 = baz
22240x00000001 = qux # small value
2225";
2226        let mut engine = create_engine();
2227        let mut writer = BufferWriter::new();
2228        let mut stack = ValueStack::new(Vec::new());
2229        engine.context.borrow_mut().format = Format::Base16(0);
2230        engine.context.borrow_mut().sep = false;
2231        stack.wrapped_push(parse_item("2147483647"));
2232        stack.wrapped_push(parse_item("2147483647 # large value"));
2233        stack.wrapped_push(parse_item("2147483647 = foo"));
2234        stack.wrapped_push(parse_item("2147483647 = bar # large value"));
2235        stack.wrapped_push(parse_item("1"));
2236        stack.wrapped_push(parse_item("1 # small value"));
2237        stack.wrapped_push(parse_item("1 = baz"));
2238        stack.wrapped_push(parse_item("1 = qux # small value"));
2239        assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2240        assert_eq!(writer.buffer, indent_multiline(expected));
2241    }
2242
2243    #[test]
2244    fn test_shows_stack_as_double_hexadecimal_with_sep() {
2245        let expected = "\
22460x,00000001,00000000
22470x,00000001,00000000 # large value
22480x,00000001,00000000 = foo
22490x,00000001,00000000 = bar # large value
22500x,00000000,00000001
22510x,00000000,00000001 # small value
22520x,00000000,00000001 = baz
22530x,00000000,00000001 = qux # small value
2254";
2255        let mut engine = create_engine();
2256        let mut writer = BufferWriter::new();
2257        let mut stack = ValueStack::new(Vec::new());
2258        engine.context.borrow_mut().format = Format::Base16(0);
2259        engine.context.borrow_mut().sep = true;
2260        stack.wrapped_push(parse_item("4294967296"));
2261        stack.wrapped_push(parse_item("4294967296 # large value"));
2262        stack.wrapped_push(parse_item("4294967296 = foo"));
2263        stack.wrapped_push(parse_item("4294967296 = bar # large value"));
2264        stack.wrapped_push(parse_item("1"));
2265        stack.wrapped_push(parse_item("1 # small value"));
2266        stack.wrapped_push(parse_item("1 = baz"));
2267        stack.wrapped_push(parse_item("1 = qux # small value"));
2268        assert!(engine.show_stack(&mut writer, &mut stack).is_ok());
2269        assert_eq!(writer.buffer, indent_multiline(expected));
2270    }
2271
2272    #[test]
2273    fn test_shows_stack_with_lower_limit() {
2274        let expected = "\
2275_ ...
2276| 0.25  |
2277[ 0.375 ]
2278( 0.5   )
2279[ 0.625 ]
2280_ 0.75
2281_ 0.875
2282";
2283        let mut engine = create_engine();
2284        let mut writer = BufferWriter::new();
2285        let mut stack = ValueStack::new(Vec::new());
2286        stack.wrapped_push(parse_item("-0.25"));
2287        stack.wrapped_push(parse_item("-0.125"));
2288        stack.wrapped_push(parse_series(vec![
2289            "0",
2290            "0.125",
2291            "0.25",
2292            "0.375",
2293        ]));
2294        stack.wrapped_push(parse_series(vec![
2295            "0.5",
2296            "0.625",
2297        ]));
2298        stack.wrapped_push(parse_item("0.75"));
2299        stack.wrapped_push(parse_item("0.875"));
2300        assert!(engine.limit_stack(&mut writer, &mut stack, Some(6)).is_ok());
2301        assert_eq!(writer.buffer, replace_multiline(expected));
2302    }
2303
2304    #[test]
2305    fn test_shows_stack_with_equal_limit() {
2306        let expected = "\
2307_ -0.25
2308_ -0.125
2309(  0     )
2310|  0.125 |
2311|  0.25  |
2312[  0.375 ]
2313(  0.5   )
2314[  0.625 ]
2315_  0.75
2316_  0.875
2317";
2318        let mut engine = create_engine();
2319        let mut writer = BufferWriter::new();
2320        let mut stack = ValueStack::new(Vec::new());
2321        stack.wrapped_push(parse_item("-0.25"));
2322        stack.wrapped_push(parse_item("-0.125"));
2323        stack.wrapped_push(parse_series(vec![
2324            "0",
2325            "0.125",
2326            "0.25",
2327            "0.375",
2328        ]));
2329        stack.wrapped_push(parse_series(vec![
2330            "0.5",
2331            "0.625",
2332        ]));
2333        stack.wrapped_push(parse_item("0.75"));
2334        stack.wrapped_push(parse_item("0.875"));
2335        assert!(engine.limit_stack(&mut writer, &mut stack, Some(10)).is_ok());
2336        assert_eq!(writer.buffer, replace_multiline(expected));
2337    }
2338
2339    #[test]
2340    fn test_shows_stack_with_higher_limit() {
2341        let expected = "\
2342_ -0.25
2343_ -0.125
2344(  0     )
2345|  0.125 |
2346|  0.25  |
2347[  0.375 ]
2348(  0.5   )
2349[  0.625 ]
2350_  0.75
2351_  0.875
2352";
2353        let mut engine = create_engine();
2354        let mut writer = BufferWriter::new();
2355        let mut stack = ValueStack::new(Vec::new());
2356        stack.wrapped_push(parse_item("-0.25"));
2357        stack.wrapped_push(parse_item("-0.125"));
2358        stack.wrapped_push(parse_series(vec![
2359            "0",
2360            "0.125",
2361            "0.25",
2362            "0.375",
2363        ]));
2364        stack.wrapped_push(parse_series(vec![
2365            "0.5",
2366            "0.625",
2367        ]));
2368        stack.wrapped_push(parse_item("0.75"));
2369        stack.wrapped_push(parse_item("0.875"));
2370        assert!(engine.limit_stack(&mut writer, &mut stack, Some(12)).is_ok());
2371        assert_eq!(writer.buffer, replace_multiline(expected));
2372    }
2373
2374    #[test]
2375    fn test_shows_stack_with_no_limit() {
2376        let expected = "\
2377_ -0.25
2378_ -0.125
2379(  0     )
2380|  0.125 |
2381|  0.25  |
2382[  0.375 ]
2383(  0.5   )
2384[  0.625 ]
2385_  0.75
2386_  0.875
2387";
2388        let mut engine = create_engine();
2389        let mut writer = BufferWriter::new();
2390        let mut stack = ValueStack::new(Vec::new());
2391        stack.wrapped_push(parse_item("-0.25"));
2392        stack.wrapped_push(parse_item("-0.125"));
2393        stack.wrapped_push(parse_series(vec![
2394            "0",
2395            "0.125",
2396            "0.25",
2397            "0.375",
2398        ]));
2399        stack.wrapped_push(parse_series(vec![
2400            "0.5",
2401            "0.625",
2402        ]));
2403        stack.wrapped_push(parse_item("0.75"));
2404        stack.wrapped_push(parse_item("0.875"));
2405        assert!(engine.limit_stack(&mut writer, &mut stack, None).is_ok());
2406        assert_eq!(writer.buffer, replace_multiline(expected));
2407    }
2408
2409    #[test]
2410    fn test_shows_variables_sorted_by_name() {
2411        let expected = "\
24125 = five
24134 = four
24141 = one
24153 = three
24162 = two
2417";
2418        let mut engine = create_engine();
2419        let mut writer = BufferWriter::new();
2420        let mut stack = ValueStack::new(Vec::new());
2421        engine.interface.borrow_mut().insert_variable(String::from("one"), parse_value("1 = one"));
2422        engine.interface.borrow_mut().insert_variable(String::from("two"), parse_value("2 = two"));
2423        engine.interface.borrow_mut().insert_variable(String::from("three"), parse_value("3 = three"));
2424        engine.interface.borrow_mut().insert_variable(String::from("four"), parse_value("4 = four"));
2425        engine.interface.borrow_mut().insert_variable(String::from("five"), parse_value("5 = five"));
2426        assert!(parse_line(&mut engine, &mut writer, &mut stack, "set").is_ok());
2427        assert_eq!(writer.buffer, indent_multiline(expected));
2428    }
2429
2430    fn indent_multiline(lines: &str) -> String {
2431        lines.lines()
2432            .map(|x| format!("  {}\n", x))
2433            .collect::<Vec<String>>()
2434            .join("")
2435    }
2436
2437    fn replace_multiline(lines: &str) -> String {
2438        lines.lines()
2439            .map(|x| x.replace("_", " "))
2440            .map(|x| format!("{}\n", x))
2441            .collect::<Vec<String>>()
2442            .join("")
2443    }
2444
2445    fn create_engine() -> Engine<BufferWriter> {
2446        let config = Config::default();
2447        let chars = BracketChars {
2448            open: ('(', ')'),
2449            middle: ('|', '|'),
2450            close: ('[', ']'),
2451        };
2452        Engine::new(config, chars).unwrap().with_interact(true)
2453    }
2454
2455    fn parse_line(
2456        engine: &mut Engine<BufferWriter>,
2457        writer: &mut BufferWriter,
2458        stack: &mut ValueStack,
2459        line: &str,
2460    ) -> MyResult<()> {
2461        let result = engine.parse_line(writer, stack, line);
2462        if let Err(error) = &result {
2463            writeln!(writer, "{}", error)?;
2464        }
2465        result
2466    }
2467
2468    impl<W: Write> Engine<W> {
2469        pub fn with_interact(mut self, interact: bool) -> Self {
2470            self.interact = interact;
2471            self
2472        }
2473    }
2474}