spec/whirly_spec.rb in whirly-0.1.1 vs spec/whirly_spec.rb in whirly-0.2.0

- old
+ new

@@ -1,27 +1,248 @@ require_relative "../lib/whirly" require "minitest/autorun" +# require "irbtools/binding" +require "stringio" +def short_sleep + sleep 0.1 +end + +def medium_sleep + sleep 0.4 +end + +def long_sleep + sleep 1 +end + describe Whirly do - describe "usage" do + before do + Whirly.reset + @capture = StringIO.new + Whirly.configure(non_tty: true, stream: @capture) + end + + describe "General Usage" do it "outputs every frame of the spinner" do - spinner = { "frames" => ["first", "second", "third"], "interval" => 10 } + spinner = { "frames" => ["first", "second", "third"], "interval" => 5 } - assert_output /first.*second.*third/m do - Whirly.start(spinner: spinner, non_tty: true) - sleep 0.1 + Whirly.start(spinner: spinner) + short_sleep + Whirly.stop + + assert_match /first.*second.*third/m, @capture.string + end + + it "calls spinner proc instead of frames if proc is given" do + spinner = { "proc" => ->(){ "frame" }, "interval" => 5 } + + Whirly.start(spinner: spinner) + short_sleep + Whirly.stop + + assert_match /frame/, @capture.string + end + end + + describe "Status Updates" do + it "shows status text alongside spinner" do + Whirly.start + Whirly.status = "Fetching…" + medium_sleep + Whirly.status = "Updates…" + medium_sleep + Whirly.stop + + assert_match /Fetching.*Updates…/m, @capture.string + end + + it "shows initial status" do + Whirly.start(status: "Initial") + short_sleep + Whirly.stop + + assert_match /Initial/, @capture.string + end + end + + describe "Finishing" do + it "shows spinner finished frame if stop is set in spinner definition" do + spinner = { "frames" => ["first", "second", "third"], "stop" => "STOP", "interval" => 5 } + + Whirly.start(spinner: spinner) + short_sleep + Whirly.stop + + assert_match /STOP/, @capture.string + end + + it "shows spinner finished frame if stop frame is passed when stopping" do + spinner = { "frames" => ["first", "second", "third"], "interval" => 5 } + + Whirly.start(spinner: spinner) + short_sleep + Whirly.stop("STOP") + + assert_match /STOP/, @capture.string + end + + it "shows spinner finished frame if stop frame is passed when starting" do + spinner = { "frames" => ["first", "second", "third"], "interval" => 5 } + + Whirly.start(spinner: spinner, stop: "STOP") + short_sleep + Whirly.stop + + assert_match /STOP/, @capture.string + end + + it "appends newline when stopping" do + Whirly.start(hide_cursor: false) + short_sleep + Whirly.stop + + assert_match /\n\z/, @capture.string + end + + it "appends no newline when stopping when :append_newline option is false" do + Whirly.start(hide_cursor: false, append_newline: false) + short_sleep + Whirly.stop + + assert_match /[^\n]\z/, @capture.string + end + + it "removes the spinner after stopping when :remove_after_stop is true" do + Whirly.start(hide_cursor: false, remove_after_stop: true) + short_sleep + Whirly.stop + + assert_match /\e\[u\n\z/, @capture.string + end + end + + describe "Spinner" do + describe "Passing a Spinner" do + it "can be the name of a bundled spinner (whirly-spinners)" do + Whirly.start(spinner: "pencil") + medium_sleep Whirly.stop + + assert_match /✎/, @capture.string end + + it "can be the name of a bundled spinner (cli-spinners)" do + Whirly.start(spinner: "dots3") + medium_sleep + Whirly.stop + + assert_match /⠋/, @capture.string + end + + it "can be an Array of frames" do + Whirly.start(spinner: ["A", "B"]) + medium_sleep + Whirly.stop + + assert_match /A.*B/m, @capture.string + end + + it "can be an Enumerator of frames" do + Whirly.start(spinner: "A".."B") + medium_sleep + Whirly.stop + + assert_match /A.*B/m, @capture.string + end + + it "can be a Proc which generates frames" do + Whirly.start(spinner: ->(){ "frame" }) + medium_sleep + Whirly.stop + + assert_match /frame/m, @capture.string + end end - it "calls spinner proc instead of frames if proc is given" do - spinner = { "proc" => ->(){ "frame" }, "interval" => 10 } + describe "Frame Mode" do + it "can be set to random" do + spinner = { "frames" => "A".."H", "mode" => "random", "interval" => 10 } - assert_output /frame/ do - Whirly.start(spinner: spinner, non_tty: true) - sleep 0.1 + Whirly.start(spinner: spinner) + medium_sleep Whirly.stop + + refute /A.*B.*C.*D.*E.*F.*G.*H/m =~ @capture.string end + + it "can be set to reverse" do + spinner = { "frames" => "A".."H", "mode" => "reverse", "interval" => 10 } + + Whirly.start(spinner: spinner) + medium_sleep + Whirly.stop + + assert_match /H.*G.*F.*E.*D.*C.*B.*A/m, @capture.string + end + + it "can be set to swing" do + spinner = { "frames" => "A".."H", "mode" => "swing", "interval" => 10 } + + Whirly.start(spinner: spinner) + medium_sleep + Whirly.stop + + assert_match /A.*B.*C.*D.*E.*F.*G.*H.*G.*F.*E.*D.*C.*B.*A/m, @capture.string + end + end + end + + describe "Ansi Escape Mode" do + it "will use save and restore ANSI sequences as default (or when 'restore') is given" do + Whirly.start + short_sleep + Whirly.stop + assert_match /\e\[s.*\e\[u/m, @capture.string + end + + it "will use beginning of line and clear line ANSI sequences when 'line' is given" do + Whirly.start(ansi_escape_mode: 'line') + medium_sleep + Whirly.stop + assert_match /\e\[G.*\e\[1K/m, @capture.string + end + end + + describe "Positioning" do + it "will render spinner 1 line further below (useful for spinning while git cloning)" do + Whirly.start(position: "below") + short_sleep + Whirly.stop + + assert_match /\n.*\e\[1A/m, @capture.string + end + end + + describe "Configure and Reset" do + it "can be configured before starting" do + Whirly.configure spinner: "dots", interval: 5 + + Whirly.start + short_sleep + Whirly.stop + + assert_match /⠧/, @capture.string + end + + it "can be reset using .reset" do + Whirly.configure spinner: "dots", interval: 5 + Whirly.reset + + Whirly.start(non_tty: true, stream: @capture) + short_sleep + Whirly.stop + assert_match /\A[^⠧]+\z/, @capture.string end end describe ".enabled?" do it "returns false if whirly was not started yet" do