Hands-On Test-Driven Development: Using Ruby, Ruby On Rails, and RSpec 1st Edition Greg Donald All Chapter Instant Download
Hands-On Test-Driven Development: Using Ruby, Ruby On Rails, and RSpec 1st Edition Greg Donald All Chapter Instant Download
com
https://ebookmeta.com/product/hands-on-test-driven-
development-using-ruby-ruby-on-rails-and-rspec-1st-edition-
greg-donald/
OR CLICK BUTTON
DOWNLOAD NOW
https://ebookmeta.com/product/hands-on-test-driven-development-using-
ruby-ruby-on-rails-and-rspec-1-converted-edition-greg-donald/
ebookmeta.com
https://ebookmeta.com/product/learn-rails-5-2-accelerated-web-
development-with-ruby-on-rails-stefan-wintermeyer/
ebookmeta.com
https://ebookmeta.com/product/ruby-on-rails-tutorial-6th-ed-6th-
edition-michael-hartl/
ebookmeta.com
https://ebookmeta.com/product/effective-python-penetration-
testing-1st-edition-rejah-rehim/
ebookmeta.com
https://ebookmeta.com/product/hero-code-star-kingdom-03-0-lindsay-
buroker-et-el/
ebookmeta.com
https://ebookmeta.com/product/railway-transportation-systems-design-
construction-and-operation-2nd-edition-christos-n-pyrgidis/
ebookmeta.com
https://ebookmeta.com/product/creative-haven-paradise-designs-
coloring-book-creative-haven-coloring-books-menten/
ebookmeta.com
https://ebookmeta.com/product/immortal-lord-2nd-edition-h-m-mcqueen/
ebookmeta.com
Rick Steves Belgium Bruges Brussels Antwerp Ghent Rick
Steves Gene Openshaw
https://ebookmeta.com/product/rick-steves-belgium-bruges-brussels-
antwerp-ghent-rick-steves-gene-openshaw-2/
ebookmeta.com
Hands-on
Test-Driven
Development
Using Ruby, Ruby on Rails, and RSpec
—
Greg Donald
Hands-on Test-Driven Development
Greg Donald
Hands-on Test-Driven
Development
Using Ruby, Ruby on Rails, and RSpec
Greg Donald
Clarksville, TN, USA
Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004, U.S.A. Phone
1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or visit www.springeronline.com. Apress Media,
LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance
Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint, paperback, or audio rights,
please e-mail [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also
available for most titles. For more information, reference our Print and eBook Bulk Sales web page at http://www.apress.com/
bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub (https://
github.com/Apress). For more detailed information, please visit https://www.apress.com/gp/services/source-code.
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
What Are We Building? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Our Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Why Another TDD Book? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
My Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Why You Should Trust Me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Audience and Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
How to Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 What Is Test-Driven Development? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Problems with Late Test Writing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
No Code Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Passing by Accident . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Code Spikes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
The Red-Green-Refactor Development Cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Red Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Green Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Refactor Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Wash, Rinse, and Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Advantages of Building Software Using TDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Code Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
No Broken Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Maintaining Focus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Acceptance Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Code Quality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Getting Started with Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Installing Homebrew . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Installing rbenv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Installing Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4 Getting Started with Ruby on Rails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Installing Bundler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Installing Ruby on Rails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Installing PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Installing Node.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
vii
viii Contents
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
About the Author
xi
About the Technical Reviewer
Eldon is a senior technologist, creator, and United States Marine Corps veteran. He’s the author
of two software development books. His career has allowed him to work across a wide variety of
technologies and domains. His career has taken him from working in successful startups in roles
ranging from senior developer to chief architect to working as a principal technologist for a global
software consulting firm, helping enterprises and companies rescue software projects and/or evolve
their software delivery capabilities.
These days, he works as a technical fellow with a mission of raising the bar of software
development globally for a technology company providing tools, AI, and research to advance the
rule of law.
Currently, he lives in Florida where he enjoys scuba diving and creating video content.
xiii
Introduction
1
Hello, and welcome! I’m very excited to share with you my book about test-driven software
development. I’ve been a software engineer for over 25 years, and I’ve seen the results of software
written using many different styles and techniques. It wasn’t so long ago that we didn’t even write tests
for our software. At some point, some very smart people realized that writing tests for our software
was actually a good idea. Our tests would provide us with confidence that our software worked as
expected and even more importantly keep us from getting phone calls in the middle of the night to fix
things that would break in production.
Not long after we started writing tests, some other very smart people realized that writing our tests
first would give us an opportunity to think about what we were going to write before we would write
it. It would give us a target to aim at, in effect. This was the birth of test-driven development (TDD).
TDD is a style of software development where we write our tests first, see that they are failing as
expected, and only then do we pursue writing the code to make those tests pass.
This is the central idea of my book. We will think about what we want to do, then we will capture
that idea with a properly failing test. We will then write the code to make the test pass. We will then
refactor our code to make it better, or prettier, or less repetitive, and then we will write another test.
We will repeat this process over and over until we have a fully functional web application.
Let’s get started!
As you pick up this book and look inside at the first few pages, you may be wondering, what exactly
are we going to build? I’m so glad you asked! We will build a fully functional blog! A “blog,” short
for “weblog” or “web log,” is a web application that allows its administrator (you) to post articles to
the Web. Instead of downloading premade blog software, for example, WordPress,1 we’re going to
build our own blog software from scratch.
We’ll be using the Ruby2 programming language and the Ruby on Rails3 web framework to build
everything. These are the best tools for the job, in my opinion. Ruby is a very expressive and powerful
programming language, and Ruby on Rails is a very powerful web framework.
1 https://wordpress.org/
2 https://ruby-lang.org/
3 https://rubyonrails.org/
© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2024 1
G. Donald, Hands-on Test-Driven Development,
https://doi.org/10.1007/978-1-4842-9748-3_1
2 1 Introduction
We’ll use the test-driven development (TDD) style of software design and engineering, which
means we’ll write failing tests first and only then write our implementation code to get our failing
tests passing.
We’ll use the RSpec4 testing framework to write our tests. RSpec describes itself as a tool for
performing “behavior-driven development” and is in fact the best tool available for testing Ruby
code. If you’ve never used RSpec before, don’t worry; in this book, I’ll cover more than enough to
get you started and productive.
Our blog will be a simple web application overall, but will be complex enough to demonstrate the
test-driven development style of software development. Our blog will allow us to create and update
pages as well as search them by keyword and tag them for easy categorization.
Let’s take a look at our database design next.
Our Database
We will use the PostgreSQL5 relational database management system (RDBMS) to store our blog’s
data. When it comes to free and open source databases, PostgreSQL is best in its class.
At the end of the book, our database design will look similar to the diagram in Figure 1-1.
4 https://rspec.info/
5 https://postgresql.org/
Why Another TDD Book? 3
We’ll go into much more detail about our database design in later chapters, but I want to give you
an initial idea of what we’ll be building early on. We will have database tables for users, pages, tags,
and images. Our image table is not connected to any of the other previously mentioned tables. Our tag
table is connected to our page table through our page_tags join table. Each of our pages will belong
to a single user. With this design, we can have more than one user, and each user can be an author of
many pages.
We will build up our database design as we go, adding new tables and columns as we need them,
as that’s the nature of practicing proper test-driven development.
The main goal of this book is to provide a practical, hands-on introduction to the test-driven style of
software design and engineering.
Many books on the topic of test-driven development have been written before this one. Some of
them are actually very good, but none of them were written in the practical, hands-on style of this
book. In fact, very few books are written in this style.
This book covers the building of an entire web application, from start to finish. Our focus
application, a blog, is the most practical thing I could think to build, given my audience of software
engineering readers. Every software engineer has their own online blog, right? A blog is simple
enough that it can be covered in a single book, but complex enough that it can be used to demonstrate
my favorite parts of RSpec while building a Ruby on Rails web application.
Most other TDD books are written in a small-problem sort of writing style. They cover single
topics, one at a time, barely more than a reference guide. They do not cover the entire process of
building a software application from start to finish, using TDD. As a result, they are, in my opinion,
less practical and much less useful for actually learning practical TDD.
My Motivation
About five years ago, I joined a team of software engineers who were busy working on a very
important (people’s lives were at stake) large-scale web application. They were several months into
it at the time, and there were deadlines. The application was being written in Ruby on Rails, and the
team was using TDD to build it. They were practicing Extreme Programming (XP),6 as described
by Kent Beck,7 pretty much to the letter. I had heard of TDD and XP before, but had never actually
practiced them. I had never even pair-programmed8 an entire day prior to joining the team. I was
eager to learn, and little did I know at the time that I was working with some of the best software
engineers I had ever met.
These girls and guys were amazingly agile. They refactored their code constantly. They were
always looking for ways to reduce code complexity and improve their processes. They
were constantly learning new things, and they were always teaching each other new things. They
were very passionate about their craft and passionate about leveling up their team even more so.
I soon realized I was in over my head. I was a n00b to the team, to TDD, and to XP. They did not
seem to care about any of that.
6 www.extremeprogramming.org/
7 http://wiki.c2.com/?KentBeck
8 http://wiki.c2.com/?PairProgramming
4 1 Introduction
They were very patient with me, and they were completely willing to teach me everything they
knew. They taught me how to practice proper TDD and XP. They taught me how to write failing tests
first and how to write code that is easy to test. They taught me how to write tests that supplied courage
for when I would later perform fearless refactoring.
Over the next couple of years, I became a much better software engineer. The first major change I
noticed in myself was how I had stopped worrying about code I had recently pushed into production.
I was no longer thinking about code breaking in production during my off hours or how these sorts
of breakages were often followed by an emergency phone call to hurry to fix things. I had stopped
worrying about code breaking because I knew my code was completely covered with well-written
tests and very unlikely to break.
Another change I noticed in myself was that I was writing cleaner code. I was writing code that
was easier to later understand. I was only writing the code that was necessary to get my tests into a
passing state. I got into a pattern of knowing that once my tests pass, my implementation work was
done. Moving on to refactor any ugliness or code duplication is my only next step before writing my
next failing test.
I’m telling you all of this because I want you to understand how I’ve come to learn and respect
test-driven development. I learned it by doing it, for many years, with a team of experts. I know that
developing software using TDD produces better software than not using TDD to develop software. I
know this because I have seen the final results with my own eyes.
I’ve been a computer programmer for a long time. If we’re counting uncompensated work, then I’ve
been programming since 1984, when I wrote my first bits of BASIC9 code on my grandpa’s TI-
99/4A,10 saving my work to a cassette tape. I went on to write more advanced programs and games
in BASIC at my junior high school, where we had Apple IIe11 computers in our computer lab. A few
years later, in high school, we had IBM PC clones12 in our computer lab, and it was at this time I
learned to program in Turbo Pascal.13
I joined the US Navy in 1990 and didn’t have much contact with computers for the next few years.
When I got out in 1995, I discovered the World Wide Web was a thing, and I became instantly hooked
on my newly found favorite hobby, building web pages. I taught myself HTML and enough Perl14
to be dangerous, and by late 1996, I had landed my first paid programming job as a web developer
working on Perl-based shopping cart software.
So if we’re counting compensated work, I’ve been a self-taught professional software engineer
since late 1996. I’ve written code in almost every major programming language and on many different
operating systems and platforms. My focus has been on web development for the most part, but I
also have significant experience working on mobile applications and games, in native code, for both
Android and iOS. I was an early publisher on Google’s Android platform, having the first published
Blackjack game there.
9 http://hopl.info/showlanguage.prx?exp=176
10 www.ti994.com/
11 www.old-computers.com/museum/computer.asp?st=1&c=83
12 www.ibm.com/ibm/history/exhibits/pc/pc_1.html
13 http://progopedia.com/implementation/turbo-pascal/
14 www.perl.org/
Other documents randomly have
different content
"No."
Grimes looked at the key critically. "H'm! A spring lock. Do you mind
opening this drawer?"
"Why should I open it? It's my private drawer." Betty thought of her
Marcus Aurelius and Bob's precious letter. Why should these sacred things
be dragged out by this vulgar detective?
"Oh, it's your private drawer, is it? Just the same, I must ask you to open
it, Miss Thompson."
"Very well," yielded the girl. "There!" She put the key in the lock and
turned it while Grimes watched her keenly.
"Certainly," bowed the prelate, and he pulled out the drawer to its full
length, then started back with a cry of amazement. "Good heavens!" He
drew forth a bundle of folded banknotes. "It's the stolen money," he
declared. "The exact amount! The identical notes! Five thousand pounds!"
Old Bunchester turned to the girl in deep concern. "My dear Miss
Thompson, this is exceedingly painful, exceedingly compromising. I beg
you most earnestly, in the interest of everyone, in your own interest, to tell
us how it comes that this money is found in your desk. You must explain
this mystery, indeed you must."
"Hold on!" cried Bob, springing forward, his whole face transfigured,
and here it was, in the words of Hiram Baxter, that the boy showed himself
a thoroughbred and took the five-bar gate in one clean leap. "Don't say a
word, Betty. Don't explain anything. You're the finest, pluckiest girl I ever
knew, and right now, without any explanation, I ask you to be my wife."
"Bob!" she cried, and her whole soul was in her eyes.
"It's all right, dear." He stood close beside her and drew her to him
protectingly. "There are two of us now." Then, turning to Grimes: "Go
ahead with your silly little game."
"All very pretty," sniffed the detective, while the bishop looked on in
purple amazement, "but, before we get through with our silly little game
you may not find it as silly as you think."
He strode across the library to the foot of the little stair and pointed to
the mezzanine door. "If Miss Thompson was so confident that Jenny Regan
was a deserving person why did she hide her in that room this morning?"
Grimes fixed his hard gaze on Betty. "Do you deny that you hid Hester
Storm, otherwise known as Jenny Regan, in that room?"
The girl eyed him steadily. "It's true," she said; "but—I can explain it."
Young Baxter started to his feet. "It isn't possible this Storm girl who's
been working here is—Jenny Regan?"
"If your lordship will give me a few moments," she said in a low tone,
"I can make everything clear. You don't mind, Bob? Just a few moments?"
Baxter bowed to her wish. "Of course I don't mind. Come on," he said
to Grimes.
"Not I," refused the latter. "Miss Thompson says she can make things
clear to his lordship. So can I. His lordship's purse was stolen by Hester
Storm, alias Jenny Regan, but this young woman," he swept Betty with a
cruel look, "was an accessory after the fact."
And the bishop said solemnly: "My dear sir, you are making an
incredible accusation. Miss Thompson is a lady—a friend of mine. I knew
her estimable father."
"I can only lay the facts before your lordship," shrugged the detective.
He went to the library door, and, motioning quickly, returned followed by
Hester Storm, who looked neither to the right nor the left, but held her eyes
straight down before her, as if studying the yellowish pattern in the carpet.
Betty watched her in surprise.
"That's a lie!" rang out Betty's swift denial. "Tell them it's a lie. You
must tell them," she appealed frantically to Hester.
But the Storm girl never moved; she never spoke; she never lifted her
eyes from the carpet.
"I wanted to tell the truth," insisted Betty, "but I had promised this poor
girl that I would do nothing until—until the detective had gone." Again she
appealed to Hester. "You know that is true. Tell them it's true."
But the Storm girl stood there like a frozen image, her lips closed, her
eyes cast down. And a sickening terror filled Betty's breast.
"Your lordship must see that there is a strong case against this young
woman." Grimes moved toward Betty with a grim tightening of the lips.
"You'll have to come with me." He laid a hand on her arm.
"Oh, I don't know," retorted Grimes. "I'm an officer of the law and——"
"My dear Mr. Baxter," reasoned the bishop, interposing his portly and
venerable presence between the excited adversaries, "believe me, we must
respect the majesty of the law."
"I tell you to step back," ordered the detective. "And you——" he faced
Miss Thompson, "consider yourself under arrest. If you have anything to
get ready you'd better do it. We start in——" he glanced at his watch, "in
ten minutes."
"I'm sorry, sir, but I've no choice. A crime has been committed, and—
there's evidence enough to hold her on if she was a cousin of the queen."
"Under arrest!" murmured Betty twining her fingers together piteously
and fixing her eyes on Hester.
At this moment the sound of carriage wheels was heard outside. Bob
went quickly to the window.
"It's Father," he said with a movement of relief. "Cheer up, Betty. Dad
will think of something."
A moment later Hiram Baxter entered the room. His face was ashen
gray. He looked broken and ill, but a flicker of the old bright smile spread
over his rugged face as he glanced about the room.
"One moment! Father, did you leave twenty-five thousand dollars in the
drawer of that desk?"
"No, Father, it's not a joke; it's very far from a joke. Did you leave it
there?"
"Twenty-five thousand dollars in that desk? Say, if you knew what I've
been through to-day! I've been scratchin' around down where the avenues
are paved with red-hot bricks, lookin' for twenty-five thousand dollars. And
I didn't find it, either. No, sir, I left no money in that desk. It ain't my desk,
anyway; it's Betty's desk."
"I'll tell him, dear," said Bob. "Father, I—I've asked Betty to be my
wife."
"Well, it ain't that that's makin' ye look like a funeral, is it?" drawled
Hiram. "Go on, now; let me have it."
Betty and Bob spoke at the same time, both pointing scornful fingers at
Grimes.
"Easy now! Not all at once. Say, Bish, you'd better tell it."
"That was stolen from you? Betty Thompson? No, no, no!" thundered
the old man.
"That is how we all feel, but, with the utmost regret I am forced to bear
witness that this exact sum and, I believe, the identical banknotes were
found in Miss Thompson's desk—there."
"Five thousand pounds? What does this mean, Betty? How did that
money get in your desk?"
"I—I don't know," the unhappy girl answered. Grimes looked at his
watch again. "No use of any more talk," he said gruffly. "It's time to start
and——" motioning to Betty, "you'll have to come with me."
"Better not interfere, sir. I've men outside to help me, and—I'm going to
take 'em. Come now." He caught Betty by the arm and marched her, half
fainting, toward the door.
At this moment Hester Storm lifted her eyes, opened her lips, and spoke
in a strange, low tone:
"Wait! You mustn't take her. She didn't steal the money. She had nothing
to do with it. I stole the money. I put it in that desk. I'm the one to take."
"Yes. I meant to steal it or—I meant to steal half of it, but—when you
sang that song about—her promise true, why—I thought how you'd been
good to me, and—trusted me, and—I sneaked in here and left the money.
The drawer was open, and I snapped it shut. Then, when I made my
getaway he pinched me." She turned to Grimes.
The detective lowered his head as if he was studying the girl through his
eyebrows.
"Sure I did. I lied. You know I lied. You don't think I'm stuck on gettin'
sent away for ten years, do ye? But if it's got to be her or me, well, I won't
have her sent away when all she's done is to treat me right and try to save
me. You can take that from Hester Storm."
"That's all right, Bish; but I want to know more about this." Hiram
turned to Hester, who was standing with bowed head and clasped hands.
"Well, fer a girl who talks about stealin'—I guess some o' the honest folks
could take lessons from you. Say, I didn't quite get that about how you
planned to steal half o' this money? Where did the half come in? Why didn't
ye plan to steal all of it?"
Then, little by little, with questions from Grimes and more questions
from Hiram the Storm girl told her story, sometimes in broken words, as her
feelings overpowered her, but in the main simply and bravely and truthfully,
as one who is strengthened by some higher power. She went back to her
childhood and spoke of her sister Rosalie. She told of her wanderings and
waywardness, then of her visit to Ippingford and her meeting with Horatio
Merle. Then, finally, of her efforts to return the money and of the
persecution she had suffered at the hands of Anton. She kept nothing back,
and she made no excuse for herself. She had sinned and it was right that she
should suffer.
As Hester finished her confession every heart went out to her in genuine
sympathy, and Grimes was seen to wipe his eyes.
"I want to say," he remarked, "that I've seen some strange cases in my
time, but when it comes to a woman trying to steal money over again that
she's stolen once so as to give it back—why, that's a new one on me."
"Ye can't ever tell what a woman's goin' to do," nodded Baxter.
"And now, my dear Miss Thompson, how shall I express my great joy
——" The bishop turned to Betty, and was about to launch forth into
another sounding period when Hiram Baxter interrupted him.
"Excuse me, Bish, fer breakin' in on yer speech, but—I've had a bad day
in town, and—if you don't mind takin' the detective into the next room and
finishin' up the details of this purse business with him, why——"
Baxter leaned back in his chair with signs of physical distress—"ye see,
I'm just about all in."
With anxious faces the young lovers stood beside the old man, who
smiled at them wearily.
"Children, I've got bad news fer ye, awful bad news for ye," he said.
"I've made the best fight I could, but that Henderson bunch, they've done
me up. Independent Copper broke twenty points to-day in the New York
market, and—I was long of the stock. My man cabled me the tip to sell, but
I never got it. I never got it. That cable was held up." He bent forward,
resting his big grizzled head on his hands in an attitude of utter despair. "It's
all off, children. It's all off."
One glance showed that something had happened, for her eyes fell on a
murmuring group gathered about Anton and the detective. And there in the
group, calmly smoking a cigarette, was Lionel Fitz-Brown.
"Lionel!" Betty called, addressing him by his Christian name for the
first time in her life. "Please come here—quick." And then, when he stood
before her, very indignantly: "The idea of your not coming to tell me!"
"Oh, Mr. Fitz-Brown," she wrung her hands beseechingly, "please tell
me if you got the cable off by twelve?"
Lionel laid a reflective forefinger along his nose. "By twelve? No. No, I
didn't."
"I go it off five minutes before twelve. Haw, haw, haw!" He fairly
doubled up in his enjoyment of this witticism.
Like a flash, Betty darted back to Hiram, thrilling with this good news.
And at the same moment Grimes entered, holding a cablegram in his hand.
"Beg your pardon, sir," he said respectfully to Baxter, "I've just arrested
your chauffeur, Anton Busch. He's a crook, Slippery Jake, sneak thief and
confidence man, wanted by the police in half dozen cities. He's been
working some deviltry here, sir. I've just found this cablegram on him. It's
addressed to you."
"I'm sorry, sir. I—I'll wait outside," and Grimes withdrew, his hard face
softened by a look of deep pity for the shattered old warrior.
Baxter sat still, looking at the yellow envelope. "Too late!" he muttered.
"Oh, if I'd only got this cablegram in time!"
"Guardy, I want to tell you something," Betty began, but Hiram paid no
attention.
"Nothing matters now," he went on bitterly. "I mustn't say that. I'm
happy about you two. Betty! Bob!" He joined their hands and held them
strongly. "It's what I've always dreamed of, but—I wanted to leave ye well
fixed and now——" The tears were coursing down his grizzled cheeks.
"We're ruined—ruined."
"No, no! We're not ruined. You mustn't say that, Guardy." The girl dared
not promise anything, for she did not know the result of her effort, but she
pointed hopefully to the unopened cablegram. "Why don't you open this?
Why don't you read it?"
He shook his head despairingly. "I know what it is. It's the notice that
I've been sold out and—everything's gone. God! If I'd only known! If I
could only have given the order to sell—even a few thousand shares."
With a listless movement Hiram ripped open the cable envelope and
drew out the yellow sheet. Betty thought her heart would stop beating as
she watched his face. Slowly the look of amazement came. He rubbed his
eyes and read the message again. Then he sprang to his feet with a great cry.
"What! It ain't possible! Listen to this!" In his excitement, Hiram almost
shouted the words written there before him. "'Congratulate you on your
splendid nerve. Executed order at once. Sold fifty thousand shares at top of
market and closed out with twenty points profit. Gramercy.' You hear that,
Bob? Read it! Am I crazy or—— No, no! There's something wrong. I didn't
show any splendid nerve. I didn't cable any order to sell fifty thousand
shares. There's some mistake."
"You?" gasped Hiram. "You cabled the order to sell fifty thousand
shares of Independent Copper stock for my account? Fifty thousand
shares?"
It was several moments before Betty could speak, and then, laughing
and crying hysterically, she told what she and Lionel had done.
"I should say it was splendid nerve," said Bob. And folding his big,
strong arms around her, "Betty, you darling!" he whispered.
She lay there happy in his arms and, looking up into his eyes with all
the fondness of her soul, answered shyly and sweetly, "Bob, my love."
And Hiram Baxter, wiping away his tears of joy, muttered to himself
(since no one else was paying any attention), "Holy cats! Is there anything a
woman won't do?"
THE END
*** END OF THE PROJECT GUTENBERG EBOOK THE BISHOP'S
PURSE ***
Updated editions will replace the previous one—the old editions will
be renamed.
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the terms
of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.
• You pay a royalty fee of 20% of the gross profits you derive from
the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
1.F.4. Except for the limited right of replacement or refund set forth in
paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.