mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge branch 'specs' into 'master'
Fix for arguments in mock stubs Closes #44 See merge request arctic-fox/spectator!28
This commit is contained in:
commit
e585c36207
12 changed files with 434 additions and 23 deletions
29
README.md
29
README.md
|
@ -361,10 +361,10 @@ Items not marked as completed may have partial implementations.
|
||||||
### How it Works (in a nutshell)
|
### How it Works (in a nutshell)
|
||||||
|
|
||||||
This shard makes extensive use of the Crystal macro system to build classes and modules.
|
This shard makes extensive use of the Crystal macro system to build classes and modules.
|
||||||
Each `describe` and `context` block creates a new module nested in its parent.
|
Each `describe` and `context` block creates a new class that inherits its parent.
|
||||||
The `it` block creates an example class.
|
The `it` block creates an method.
|
||||||
An instance of the example class is created to run the test.
|
An instance of the group class is created to run the test.
|
||||||
Each example class includes a context module, which contains all test values and hooks.
|
Each group class includes all test values and hooks.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
@ -379,11 +379,6 @@ Please make sure to run `crystal tool format` before submitting.
|
||||||
The CI build checks for properly formatted code.
|
The CI build checks for properly formatted code.
|
||||||
[Ameba](https://crystal-ameba.github.io/) is run to check for code style.
|
[Ameba](https://crystal-ameba.github.io/) is run to check for code style.
|
||||||
|
|
||||||
Tests must be written for any new functionality.
|
|
||||||
Macros that create types are not as easy to test,
|
|
||||||
so they are exempt for the current time.
|
|
||||||
However, please test all code locally with an example spec file.
|
|
||||||
|
|
||||||
Documentation is automatically generated and published to GitLab pages.
|
Documentation is automatically generated and published to GitLab pages.
|
||||||
It can be found here: https://arctic-fox.gitlab.io/spectator
|
It can be found here: https://arctic-fox.gitlab.io/spectator
|
||||||
|
|
||||||
|
@ -391,7 +386,17 @@ This project is developed on [GitLab](https://gitlab.com/arctic-fox/spectator),
|
||||||
and mirrored to [GitHub](https://github.com/icy-arctic-fox/spectator).
|
and mirrored to [GitHub](https://github.com/icy-arctic-fox/spectator).
|
||||||
Issues and PRs/MRs are accepted on both.
|
Issues and PRs/MRs are accepted on both.
|
||||||
|
|
||||||
Contributors
|
### Testing
|
||||||
------------
|
|
||||||
|
|
||||||
- [arctic-fox](https://gitlab.com/arctic-fox) Michael Miller - creator, maintainer
|
Tests must be written for any new functionality.
|
||||||
|
|
||||||
|
The `spec/` directory contains feature tests as well as unit tests.
|
||||||
|
These demonstrate small bits of functionality.
|
||||||
|
The feature tests are grouped into sub directories based on their type, they are:
|
||||||
|
|
||||||
|
- docs/ - Example snippets from Spectator's documentation.
|
||||||
|
- rspec/ - Examples from RSpec's documentation modified slightly to work with Spectator.
|
||||||
|
See: https://relishapp.com/rspec/
|
||||||
|
Additional sub directories in this directory represent the modules/projects of RSpec.
|
||||||
|
|
||||||
|
The other directories are for unit testing various parts of Spectator.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: spectator
|
name: spectator
|
||||||
version: 0.9.11
|
version: 0.9.13
|
||||||
description: |
|
description: |
|
||||||
A feature-rich spec testing framework for Crystal with similarities to RSpec.
|
A feature-rich spec testing framework for Crystal with similarities to RSpec.
|
||||||
|
|
||||||
|
|
23
spec/docs/getting_started_spec.cr
Normal file
23
spec/docs/getting_started_spec.cr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
require "../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe String do
|
||||||
|
subject { "foo" }
|
||||||
|
|
||||||
|
describe "#==" do
|
||||||
|
context "with the same value" do
|
||||||
|
let(value) { subject.dup }
|
||||||
|
|
||||||
|
it "is true" do
|
||||||
|
is_expected.to eq(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with a different value" do
|
||||||
|
let(value) { "bar" }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
is_expected.to_not eq(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
57
spec/docs/helper_methods_spec.cr
Normal file
57
spec/docs/helper_methods_spec.cr
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
Spectator.describe String do
|
||||||
|
# This is a helper method.
|
||||||
|
def random_string(length)
|
||||||
|
chars = ('a'..'z').to_a
|
||||||
|
String.build(length) do |builder|
|
||||||
|
length.times { builder << chars.sample }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#size" do
|
||||||
|
subject { random_string(10).size }
|
||||||
|
|
||||||
|
it "is the length of the string" do
|
||||||
|
is_expected.to eq(10)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Spectator.describe String do
|
||||||
|
# length is now pulled from value defined by `let`.
|
||||||
|
def random_string
|
||||||
|
chars = ('a'..'z').to_a
|
||||||
|
String.build(length) do |builder|
|
||||||
|
length.times { builder << chars.sample }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#size" do
|
||||||
|
let(length) { 10 } # random_string uses this.
|
||||||
|
subject { random_string.size }
|
||||||
|
|
||||||
|
it "is the length of the string" do
|
||||||
|
is_expected.to eq(length)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module StringHelpers
|
||||||
|
def random_string
|
||||||
|
chars = ('a'..'z').to_a
|
||||||
|
String.build(length) do |builder|
|
||||||
|
length.times { builder << chars.sample }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Spectator.describe String do
|
||||||
|
include StringHelpers
|
||||||
|
|
||||||
|
describe "#size" do
|
||||||
|
let(length) { 10 }
|
||||||
|
subject { random_string.size }
|
||||||
|
|
||||||
|
it "is the length of the string" do
|
||||||
|
is_expected.to eq(length)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
spec/docs/mocks/mocks_spec.cr
Normal file
30
spec/docs/mocks/mocks_spec.cr
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
class Phonebook
|
||||||
|
def find(name)
|
||||||
|
# Some expensive lookup call.
|
||||||
|
"+18005554321"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Resolver
|
||||||
|
def initialize(@phonebook : Phonebook)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find(name)
|
||||||
|
@phonebook.find(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Spectator.describe Resolver do
|
||||||
|
mock Phonebook do
|
||||||
|
stub find(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#find" do
|
||||||
|
it "can find number" do
|
||||||
|
pb = Phonebook.new
|
||||||
|
allow(pb).to receive(find).and_return("+18005551234")
|
||||||
|
resolver = Resolver.new(pb)
|
||||||
|
expect(resolver.find("Bob")).to eq("+18005551234")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
40
spec/docs/mocks/overview_spec.cr
Normal file
40
spec/docs/mocks/overview_spec.cr
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe "Doubles" do
|
||||||
|
double :my_double do
|
||||||
|
stub answer { 42 }
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "the answer to everything" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
expect(dbl.answer).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MyType
|
||||||
|
def answer
|
||||||
|
123
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Spectator.describe "Mocks" do
|
||||||
|
mock MyType do
|
||||||
|
stub answer { 42 }
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "the answer to everything" do
|
||||||
|
m = MyType.new
|
||||||
|
expect(m.answer).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Spectator.describe "Mocks and doubles" do
|
||||||
|
double :my_double do
|
||||||
|
stub answer : Int32 # Return type required, otherwise nil is assumed.
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "the answer to everything" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:answer).and_return(42)
|
||||||
|
expect(dbl.answer).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
166
spec/docs/mocks/stubs_spec.cr
Normal file
166
spec/docs/mocks/stubs_spec.cr
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe "Stubs" do
|
||||||
|
context "Implementing a Stub" do
|
||||||
|
double :my_double do
|
||||||
|
stub answer : Int32
|
||||||
|
stub do_something
|
||||||
|
end
|
||||||
|
|
||||||
|
it "knows the answer" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:answer).and_return(42)
|
||||||
|
expect(dbl.answer).to eq(42)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does something" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something)
|
||||||
|
expect(dbl.do_something).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and_return" do
|
||||||
|
double :my_double do
|
||||||
|
stub to_s : String
|
||||||
|
stub do_something
|
||||||
|
end
|
||||||
|
|
||||||
|
it "stringifies" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:to_s).and_return("foobar")
|
||||||
|
expect(dbl.to_s).to eq("foobar")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns gibberish" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:to_s).and_return("foo", "bar", "baz")
|
||||||
|
expect(dbl.to_s).to eq("foo")
|
||||||
|
expect(dbl.to_s).to eq("bar")
|
||||||
|
expect(dbl.to_s).to eq("baz")
|
||||||
|
expect(dbl.to_s).to eq("baz")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something).and_return
|
||||||
|
expect(dbl.do_something).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and_raise" do
|
||||||
|
double :my_double do
|
||||||
|
stub oops
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:oops).and_raise(DivisionByZeroError.new)
|
||||||
|
expect { dbl.oops }.to raise_error(DivisionByZeroError)
|
||||||
|
end
|
||||||
|
it "raises an error" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:oops).and_raise("Something broke")
|
||||||
|
expect { dbl.oops }.to raise_error(/Something broke/)
|
||||||
|
end
|
||||||
|
it "raises an error" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:oops).and_raise(ArgumentError, "Size must be > 0")
|
||||||
|
expect { dbl.oops }.to raise_error(ArgumentError, /Size/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and_call_original" do
|
||||||
|
class MyType
|
||||||
|
def foo
|
||||||
|
"foo"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mock MyType do
|
||||||
|
stub foo
|
||||||
|
end
|
||||||
|
|
||||||
|
it "calls the original" do
|
||||||
|
instance = MyType.new
|
||||||
|
allow(instance).to receive(:foo).and_call_original
|
||||||
|
expect(instance.foo).to eq("foo")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Short-hand for Multiple Stubs" do
|
||||||
|
double :my_double do
|
||||||
|
stub method_a : Symbol
|
||||||
|
stub method_b : Int32
|
||||||
|
stub method_c : String
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does something" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive_messages(method_a: :foo, method_b: 42, method_c: "foobar")
|
||||||
|
expect(dbl.method_a).to eq(:foo)
|
||||||
|
expect(dbl.method_b).to eq(42)
|
||||||
|
expect(dbl.method_c).to eq("foobar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Custom Implementation" do
|
||||||
|
double :my_double do
|
||||||
|
stub foo : String
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does something" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:foo) { "foo" }
|
||||||
|
expect(dbl.foo).to eq("foo")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Arguments" do
|
||||||
|
double :my_double do
|
||||||
|
stub add(a, b) { a + b }
|
||||||
|
stub do_something(arg) { arg } # Return the argument by default.
|
||||||
|
end
|
||||||
|
|
||||||
|
it "adds two numbers" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:add).and_return(7)
|
||||||
|
expect(dbl.add(1, 2)).to eq(7)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does basic matching" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something).with(1).and_return(42)
|
||||||
|
allow(dbl).to receive(:do_something).with(2).and_return(22)
|
||||||
|
expect(dbl.do_something(1)).to eq(42)
|
||||||
|
expect(dbl.do_something(2)).to eq(22)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can call the original" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something).with(1).and_return(42)
|
||||||
|
allow(dbl).to receive(:do_something).with(2).and_call_original
|
||||||
|
expect(dbl.do_something(1)).to eq(42)
|
||||||
|
expect(dbl.do_something(2)).to eq(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "falls back to the default" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something).and_return(22)
|
||||||
|
allow(dbl).to receive(:do_something).with(1).and_return(42)
|
||||||
|
expect(dbl.do_something(1)).to eq(42)
|
||||||
|
expect(dbl.do_something(2)).to eq(22)
|
||||||
|
expect(dbl.do_something(3)).to eq(22)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does advanced matching" do
|
||||||
|
dbl = double(:my_double)
|
||||||
|
allow(dbl).to receive(:do_something).with(Int32).and_return(42)
|
||||||
|
allow(dbl).to receive(:do_something).with(String).and_return("foobar")
|
||||||
|
allow(dbl).to receive(:do_something).with(/hi/).and_return("hello there")
|
||||||
|
expect(dbl.do_something(1)).to eq(42)
|
||||||
|
expect(dbl.do_something("foo")).to eq("foobar")
|
||||||
|
expect(dbl.do_something("hi there")).to eq("hello there")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
spec/docs/structure_spec.cr
Normal file
34
spec/docs/structure_spec.cr
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
require "../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe String do
|
||||||
|
let(normal_string) { "foobar" }
|
||||||
|
let(empty_string) { "" }
|
||||||
|
|
||||||
|
describe "#empty?" do
|
||||||
|
subject { string.empty? }
|
||||||
|
|
||||||
|
context "when empty" do
|
||||||
|
let(string) { empty_string }
|
||||||
|
|
||||||
|
it "is true" do
|
||||||
|
is_expected.to be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when not empty" do
|
||||||
|
let(string) { normal_string }
|
||||||
|
|
||||||
|
it "is false" do
|
||||||
|
is_expected.to be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Spectator.describe Bytes do
|
||||||
|
it "stores an array of bytes" do
|
||||||
|
bytes = Bytes.new(32)
|
||||||
|
bytes[0] = 42
|
||||||
|
expect(bytes[0]).to eq(42)
|
||||||
|
end
|
||||||
|
end
|
32
spec/docs/subject_spec.cr
Normal file
32
spec/docs/subject_spec.cr
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require "../spec_helper"
|
||||||
|
|
||||||
|
Spectator.describe "subject" do
|
||||||
|
subject(array1) { [1, 2, 3] }
|
||||||
|
subject(array2) { [4, 5, 6] }
|
||||||
|
|
||||||
|
it "has different elements" do
|
||||||
|
expect(array1).to_not eq(subject) # array2 would also work here.
|
||||||
|
end
|
||||||
|
|
||||||
|
let(string) { "foobar" }
|
||||||
|
|
||||||
|
it "isn't empty" do
|
||||||
|
expect(string.empty?).to be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is six characters" do
|
||||||
|
expect(string.size).to eq(6)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(array) { [0, 1, 2] }
|
||||||
|
|
||||||
|
it "modifies the array" do
|
||||||
|
array[0] = 42
|
||||||
|
expect(array).to eq([42, 1, 2])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't carry across tests" do
|
||||||
|
array[1] = 777
|
||||||
|
expect(array).to eq([0, 777, 2])
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,7 +6,7 @@ module Spectator
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
# Current version of the Spectator library.
|
# Current version of the Spectator library.
|
||||||
VERSION = "0.9.11"
|
VERSION = "0.9.13"
|
||||||
|
|
||||||
# Top-level describe method.
|
# Top-level describe method.
|
||||||
# All specs in a file must be wrapped in this call.
|
# All specs in a file must be wrapped in this call.
|
||||||
|
|
|
@ -50,12 +50,9 @@ module Spectator::Mocks
|
||||||
%}
|
%}
|
||||||
|
|
||||||
{% if body && !body.is_a?(Nop) %}
|
{% if body && !body.is_a?(Nop) %}
|
||||||
%source = ::Spectator::Source.new({{_file}}, {{_line}})
|
def {{receiver}}%method({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
%proc = ->{
|
|
||||||
{{body.body}}
|
{{body.body}}
|
||||||
}
|
end
|
||||||
%ds = ::Spectator::Mocks::ProcMethodStub.new({{name.symbolize}}, %source, %proc)
|
|
||||||
::Spectator::SpecBuilder.add_default_stub({{@type.name}}, %ds)
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
|
@ -66,8 +63,15 @@ module Spectator::Mocks
|
||||||
if (%stub = %harness.mocks.find_stub(self, %call))
|
if (%stub = %harness.mocks.find_stub(self, %call))
|
||||||
return %stub.call!(%args) { {{original}}({{args.splat}}) }
|
return %stub.call!(%args) { {{original}}({{args.splat}}) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{% if body && !body.is_a?(Nop) %}
|
||||||
|
%method({{args.splat}})
|
||||||
|
{% else %}
|
||||||
|
{{original}}({{args.splat}})
|
||||||
|
{% end %}
|
||||||
|
else
|
||||||
|
{{original}}({{args.splat}})
|
||||||
end
|
end
|
||||||
{{original}}({{args.splat}})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
|
@ -78,9 +82,18 @@ module Spectator::Mocks
|
||||||
if (%stub = %harness.mocks.find_stub(self, %call))
|
if (%stub = %harness.mocks.find_stub(self, %call))
|
||||||
return %stub.call!(%args) { {{original}}({{args.splat}}) { |*%ya| yield *%ya } }
|
return %stub.call!(%args) { {{original}}({{args.splat}}) { |*%ya| yield *%ya } }
|
||||||
end
|
end
|
||||||
end
|
|
||||||
{{original}}({{args.splat}}) do |*%yield_args|
|
{% if body && !body.is_a?(Nop) %}
|
||||||
yield *%yield_args
|
%method({{args.splat}}) { {{original}}({{args.splat}}) { |*%ya| yield *%ya } }
|
||||||
|
{% else %}
|
||||||
|
{{original}}({{args.splat}}) do |*%yield_args|
|
||||||
|
yield *%yield_args
|
||||||
|
end
|
||||||
|
{% end %}
|
||||||
|
else
|
||||||
|
{{original}}({{args.splat}}) do |*%yield_args|
|
||||||
|
yield *%yield_args
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
11
util/mirror-wiki.sh
Executable file
11
util/mirror-wiki.sh
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# Mirrors the contents of the GitLab wiki to GitHub.
|
||||||
|
git clone git@gitlab.com:arctic-fox/spectator.wiki.git
|
||||||
|
pushd spectator.wiki
|
||||||
|
git remote add github git@github.com:icy-arctic-fox/spectator.wiki.git
|
||||||
|
git fetch github
|
||||||
|
git push github master
|
||||||
|
popd
|
||||||
|
rm -rf spectator.wiki
|
Loading…
Reference in a new issue