1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-26 17:06:54 +00:00

Merge branch 'master' into mc-1.14.x

This commit is contained in:
SquidDev 2019-06-15 08:00:20 +01:00
commit 57318b022d
26 changed files with 446 additions and 41 deletions

View File

@ -3,10 +3,6 @@
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd"> "https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions> <suppressions>
<!-- Has a public m_label field. We need to check if this is used in other projects before renaming it. -->
<suppress checks="MemberName" files=".*[\\/]TileComputerBase.java"
message="Name 'm_label' must match pattern .*" />
<!-- All the config options and method fields. --> <!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />

View File

@ -48,7 +48,7 @@ public class TileComputer extends TileComputerBase
{ {
ComputerFamily family = getFamily(); ComputerFamily family = getFamily();
ServerComputer computer = new ServerComputer( ServerComputer computer = new ServerComputer(
getWorld(), id, m_label, instanceID, family, getWorld(), id, label, instanceID, family,
ComputerCraft.terminalWidth_computer, ComputerCraft.terminalWidth_computer,
ComputerCraft.terminalHeight_computer ComputerCraft.terminalHeight_computer
); );

View File

@ -52,7 +52,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
private int m_instanceID = -1; private int m_instanceID = -1;
private int m_computerID = -1; private int m_computerID = -1;
protected String m_label = null; protected String label = null;
private boolean m_on = false; private boolean m_on = false;
boolean m_startOn = false; boolean m_startOn = false;
private boolean m_fresh = false; private boolean m_fresh = false;
@ -160,7 +160,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
m_fresh = false; m_fresh = false;
m_computerID = computer.getID(); m_computerID = computer.getID();
m_label = computer.getLabel(); label = computer.getLabel();
m_on = computer.isOn(); m_on = computer.isOn();
if( computer.hasOutputChanged() ) updateOutput(); if( computer.hasOutputChanged() ) updateOutput();
@ -181,7 +181,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
{ {
// Save ID, label and power state // Save ID, label and power state
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID ); if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
if( m_label != null ) nbt.putString( NBT_LABEL, m_label ); if( label != null ) nbt.putString( NBT_LABEL, label );
nbt.putBoolean( NBT_ON, m_on ); nbt.putBoolean( NBT_ON, m_on );
return super.write( nbt ); return super.write( nbt );
@ -194,7 +194,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
// Load ID, label and power state // Load ID, label and power state
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
m_label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_on = m_startOn = nbt.getBoolean( NBT_ON ); m_on = m_startOn = nbt.getBoolean( NBT_ON );
} }
@ -308,7 +308,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public final String getLabel() public final String getLabel()
{ {
return m_label; return label;
} }
@Override @Override
@ -325,9 +325,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public final void setLabel( String label ) public final void setLabel( String label )
{ {
if( getWorld().isRemote || Objects.equals( m_label, label ) ) return; if( getWorld().isRemote || Objects.equals( this.label, label ) ) return;
m_label = label; this.label = label;
ServerComputer computer = getServerComputer(); ServerComputer computer = getServerComputer();
if( computer != null ) computer.setLabel( label ); if( computer != null ) computer.setLabel( label );
markDirty(); markDirty();
@ -375,16 +375,15 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
protected void writeDescription( @Nonnull CompoundNBT nbt ) protected void writeDescription( @Nonnull CompoundNBT nbt )
{ {
super.writeDescription( nbt ); super.writeDescription( nbt );
if( label != null ) nbt.putString( NBT_LABEL, label );
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID ); if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
if( m_label != null ) nbt.putString( NBT_LABEL, m_label );
} }
@Override @Override
protected void readDescription( @Nonnull CompoundNBT nbt ) protected void readDescription( @Nonnull CompoundNBT nbt )
{ {
super.readDescription( nbt ); super.readDescription( nbt );
m_label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null; label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1; m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
} }
@ -395,7 +394,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
unload(); unload();
m_instanceID = copy.m_instanceID; m_instanceID = copy.m_instanceID;
m_computerID = copy.m_computerID; m_computerID = copy.m_computerID;
m_label = copy.m_label; label = copy.label;
m_on = copy.m_on; m_on = copy.m_on;
m_startOn = copy.m_startOn; m_startOn = copy.m_startOn;
updateBlock(); updateBlock();
@ -414,20 +413,20 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Override @Override
public ITextComponent getName() public ITextComponent getName()
{ {
return hasCustomName() ? new StringTextComponent( m_label ) : getBlockState().getBlock().getNameTextComponent(); return hasCustomName() ? new StringTextComponent( label ) : getBlockState().getBlock().getNameTextComponent();
} }
@Override @Override
public boolean hasCustomName() public boolean hasCustomName()
{ {
return !Strings.isNullOrEmpty( m_label ); return !Strings.isNullOrEmpty( label );
} }
@Nullable @Nullable
@Override @Override
public ITextComponent getCustomName() public ITextComponent getCustomName()
{ {
return hasCustomName() ? new StringTextComponent( m_label ) : null; return hasCustomName() ? new StringTextComponent( label ) : null;
} }
@Nonnull @Nonnull

View File

@ -106,7 +106,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
protected ServerComputer createComputer( int instanceID, int id ) protected ServerComputer createComputer( int instanceID, int id )
{ {
ServerComputer computer = new ServerComputer( ServerComputer computer = new ServerComputer(
getWorld(), id, m_label, instanceID, getFamily(), getWorld(), id, label, instanceID, getFamily(),
ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle
); );
computer.setPosition( getPos() ); computer.setPosition( getPos() );

View File

@ -5,3 +5,4 @@ ex:
"wget http://pastebin.com/raw/CxaWmPrX test" will download the file from the URL http://pastebin.com/raw/CxaWmPrX, and save it as "test". "wget http://pastebin.com/raw/CxaWmPrX test" will download the file from the URL http://pastebin.com/raw/CxaWmPrX, and save it as "test".
"wget http://example.org/test.lua/?foo=bar#qzu" will download the file from the URL http://example.org/test.lua/?foo=bar#qzu and save it as "test.lua" "wget http://example.org/test.lua/?foo=bar#qzu" will download the file from the URL http://example.org/test.lua/?foo=bar#qzu and save it as "test.lua"
"wget http://example.org/" will download the file from the URL http://example.org and save it as "example.org" "wget http://example.org/" will download the file from the URL http://example.org and save it as "example.org"
"wget run http://pastebin.com/raw/CxaWmPrX" will download the file from the URL http://pastebin.com/raw/CxaWmPrX and run it immediately.

View File

@ -8,6 +8,8 @@ Run "list" or "ls" to see all files in a directory.
You can delete files and directories with "delete" or "rm". You can delete files and directories with "delete" or "rm".
Use "pastebin put" to upload a program to pastebin. Use "pastebin put" to upload a program to pastebin.
Use "pastebin get" to download a program from pastebin. Use "pastebin get" to download a program from pastebin.
Use "pastebin run" to run a program from pastebin without saving it. Use "pastebin run" to run a program from pastebin.
Use the "edit" program to create and edit your programs. Use the "edit" program to create and edit your programs.
You can copy files with "copy" or "cp". You can copy files with "copy" or "cp".
You can use "wget run <url>" to run a program from the internet.
You can use "wget" to download a file from the internet.

View File

@ -15,6 +15,10 @@ if #tFiles > 0 then
elseif #tFiles == 1 then elseif #tFiles == 1 then
if fs.exists( sDest ) then if fs.exists( sDest ) then
printError( "Destination exists" ) printError( "Destination exists" )
elseif fs.isReadOnly( sDest ) then
printError( "Destination is read-only" )
elseif fs.getFreeSpace( sDest ) < fs.getSize( sFile ) then
printError( "Not enough space" )
else else
fs.copy( sFile, sDest ) fs.copy( sFile, sDest )
end end

View File

@ -2,14 +2,24 @@
local function printUsage() local function printUsage()
print( "Usage:" ) print( "Usage:" )
print( "wget <url> [filename]" ) print( "wget <url> [filename]" )
print( "wget run <url>" )
end end
local tArgs = { ... } local tArgs = { ... }
local run = false
if tArgs[1] == "run" then
table.remove( tArgs, 1 )
run = true
end
if #tArgs < 1 then if #tArgs < 1 then
printUsage() printUsage()
return return
end end
local url = table.remove( tArgs, 1 )
if not http then if not http then
printError( "wget requires http API" ) printError( "wget requires http API" )
printError( "Set http_enable to true in ComputerCraft.cfg" ) printError( "Set http_enable to true in ComputerCraft.cfg" )
@ -22,6 +32,13 @@ local function getFilename( sUrl )
end end
local function get( sUrl ) local function get( sUrl )
-- Check if the URL is valid
local ok, err = http.checkURL( url )
if not ok then
printError( err or "Invalid URL." )
return
end
write( "Connecting to " .. sUrl .. "... " ) write( "Connecting to " .. sUrl .. "... " )
local response = http.get( sUrl , nil , true ) local response = http.get( sUrl , nil , true )
@ -37,29 +54,34 @@ local function get( sUrl )
return sResponse return sResponse
end end
-- Determine file to download if run then
local sUrl = tArgs[1] local res = get(url)
if not res then return end
--Check if the URL is valid local func, err = load(res, getFilename(url), "t", _ENV)
local ok, err = http.checkURL( sUrl ) if not func then
if not ok then printError(err)
printError( err or "Invalid URL." ) return
return end
end
local sFile = tArgs[2] or getFilename( sUrl ) local ok, err = pcall(func, table.unpack(tArgs))
local sPath = shell.resolve( sFile ) if not ok then
if fs.exists( sPath ) then printError( err )
print( "File already exists" ) end
return else
end local sFile = tArgs[1] or getFilename( url )
local sPath = shell.resolve( sFile )
if fs.exists( sPath ) then
print( "File already exists" )
return
end
local res = get(url)
if not res then return end
-- Do the get
local res = get( sUrl )
if res then
local file = fs.open( sPath, "wb" ) local file = fs.open( sPath, "wb" )
file.write( res ) file.write( res )
file.close() file.close()
print( "Downloaded as "..sFile ) print( "Downloaded as " .. sFile )
end end

View File

@ -7,8 +7,15 @@ end
local sSource = shell.resolve( tArgs[1] ) local sSource = shell.resolve( tArgs[1] )
local sDest = shell.resolve( tArgs[2] ) local sDest = shell.resolve( tArgs[2] )
if fs.exists( sDest ) then if not fs.exists( sSource ) then
printError( "No matching files" )
return
elseif fs.exists( sDest ) then
printError( "Destination exists" ) printError( "Destination exists" )
return
elseif fs.isReadOnly( sDest ) then
printError( "Destination is read-only" )
return
end end
fs.move( sSource, sDest ) fs.move( sSource, sDest )

View File

@ -183,6 +183,12 @@ local function completeExec( shell, nIndex, sText, tPreviousText )
return completeMultipleChoice( sText, tCommands, true ) return completeMultipleChoice( sText, tCommands, true )
end end
end end
local tWgetOptions = { "run" }
local function completeWget( shell, nIndex, sText, tPreviousText )
if nIndex == 1 then
return completeMultipleChoice( sText, tWgetOptions, true )
end
end
shell.setCompletionFunction( "rom/programs/alias.lua", completeAlias ) shell.setCompletionFunction( "rom/programs/alias.lua", completeAlias )
shell.setCompletionFunction( "rom/programs/cd.lua", completeDir ) shell.setCompletionFunction( "rom/programs/cd.lua", completeDir )
shell.setCompletionFunction( "rom/programs/copy.lua", completeEitherEither ) shell.setCompletionFunction( "rom/programs/copy.lua", completeEitherEither )
@ -210,6 +216,7 @@ shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completeFile
shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completePastebin ) shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completePastebin )
shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completeChat ) shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completeChat )
shell.setCompletionFunction( "rom/programs/command/exec.lua", completeExec ) shell.setCompletionFunction( "rom/programs/command/exec.lua", completeExec )
shell.setCompletionFunction( "rom/programs/http/wget.lua", completeWget )
if turtle then if turtle then
local tGoOptions = { "left", "right", "forward", "back", "down", "up" } local tGoOptions = { "left", "right", "forward", "back", "down", "up" }

View File

@ -42,7 +42,7 @@ public class ResourceMountTest
files.sort( Comparator.naturalOrder() ); files.sort( Comparator.naturalOrder() );
assertEquals( assertEquals(
Arrays.asList( "apis", "autorun", "help", "modules", "programs", "startup.lua" ), Arrays.asList( "apis", "autorun", "help", "modules", "motd.txt", "programs", "startup.lua" ),
files files
); );
} }

View File

@ -49,6 +49,8 @@ local function push_state()
term = term.current(), term = term.current(),
input = io.input(), input = io.input(),
output = io.output(), output = io.output(),
dir = shell.dir(),
path = shell.path(),
stubs = stubs, stubs = stubs,
} }
end end
@ -65,6 +67,8 @@ local function pop_state(state)
term.redirect(state.term) term.redirect(state.term)
io.input(state.input) io.input(state.input)
io.output(state.output) io.output(state.output)
shell.setDir(state.dir)
shell.setPath(state.path)
end end
local error_mt = { __tostring = function(self) return self.message end } local error_mt = { __tostring = function(self) return self.message end }

View File

@ -0,0 +1,20 @@
local capture = require "test_helpers".capture_program
describe("The cd program", function()
it("cd into a directory", function()
shell.run("cd /rom/programs")
expect(shell.dir()):eq("rom/programs")
end)
it("cd into a not existing directory", function()
expect(capture(stub, "cd /rom/nothing"))
:matches { ok = true, output = "Not a directory\n", error = "" }
end)
it("displays the usage with no arguments", function()
expect(capture(stub, "cd"))
:matches { ok = true, output = "Usage: cd <path>\n", error = "" }
end)
end)

View File

@ -0,0 +1,40 @@
local capture = require "test_helpers".capture_program
describe("The copy program", function()
local function touch(file)
io.open(file, "w"):close()
end
it("copies a file", function()
touch("/test-files/copy/a.txt")
shell.run("copy /test-files/copy/a.txt /test-files/copy/b.txt")
expect(fs.exists("/test-files/copy/a.txt")):eq(true)
expect(fs.exists("/test-files/copy/b.txt")):eq(true)
end)
it("fails when copying a non-existent file", function()
expect(capture(stub, "copy nothing destination"))
:matches { ok = true, output = "", error = "No matching files\n" }
end)
it("fails when overwriting an existing file", function()
touch("/test-files/copy/c.txt")
expect(capture(stub, "copy /test-files/copy/c.txt /test-files/copy/c.txt"))
:matches { ok = true, output = "", error = "Destination exists\n" }
end)
it("fails when copying into read-only locations", function()
touch("/test-files/copy/d.txt")
expect(capture(stub, "copy /test-files/copy/d.txt /rom/test.txt"))
:matches { ok = true, output = "", error = "Destination is read-only\n" }
end)
it("displays the usage when given no arguments", function()
expect(capture(stub, "copy"))
:matches { ok = true, output = "Usage: cp <source> <destination>\n", error = "" }
end)
end)

View File

@ -0,0 +1,11 @@
local capture = require "test_helpers".capture_program
describe("The edit program", function()
it("displays its usage when given no argument", function()
multishell = nil
expect(capture(stub, "edit"))
:matches { ok = true, output = "Usage: edit <path>\n", error = "" }
end)
end)

View File

@ -0,0 +1,77 @@
local capture = require "test_helpers".capture_program
describe("The pastebin program", function()
local function setup_request()
stub(_G, "http", {
checkURL = function()
return true
end,
get = function()
return {
readAll = function()
return [[print("Hello", ...)]]
end,
close = function()
end,
getResponseHeaders = function()
local tHeader = {}
tHeader["Content-Type"] = "text/plain; charset=utf-8"
return tHeader
end
}
end,
post = function()
return {
readAll = function()
return "https://pastebin.com/abcde"
end,
close = function()
end,
}
end
})
end
it("downloads one file", function()
setup_request()
capture(stub, "pastebin", "get", "abcde", "testdown")
expect(fs.exists("/testdown")):eq(true)
end)
it("runs a program from the internet", function()
setup_request()
expect(capture(stub, "pastebin", "run", "abcde", "a", "b", "c"))
:matches { ok = true, output = "Connecting to pastebin.com... Success.\nHello a b c\n", error = "" }
end)
it("upload a program to pastebin", function()
setup_request()
local file = fs.open( "testup", "w" )
file.close()
expect(capture(stub, "pastebin", "put", "testup" ))
:matches { ok = true, output = "Connecting to pastebin.com... Success.\nUploaded as https://pastebin.com/abcde\nRun \"pastebin get abcde\" to download anywhere\n", error = "" }
end)
it("upload a not existing program to pastebin", function()
setup_request()
expect(capture(stub, "pastebin", "put", "nothing" ))
:matches { ok = true, output = "No such file\n", error = "" }
end)
it("displays its usage when given no arguments", function()
setup_request()
expect(capture(stub, "pastebin"))
:matches { ok = true, output = "Usages:\npastebin put <filename>\npastebin get <code> <filename>\npastebin run <code> <arguments>\n", error = "" }
end)
it("can be completed", function()
local complete = shell.getCompletionInfo()["rom/programs/http/pastebin.lua"].fnComplete
expect(complete(shell, 1, "", {})):same { "put ", "get ", "run " }
end)
end)

View File

@ -0,0 +1,53 @@
local capture = require "test_helpers".capture_program
describe("The wget program", function()
local function setup_request()
stub(_G, "http", {
checkURL = function()
return true
end,
get = function()
return {
readAll = function()
return [[print("Hello", ...)]]
end,
close = function()
end,
}
end
})
end
it("downloads one file", function()
setup_request()
capture(stub, "wget", "https://example.com")
expect(fs.exists("/example.com")):eq(true)
end)
it("downloads one file with given filename", function()
setup_request()
capture(stub, "wget", "https://example.com /test-files/download")
expect(fs.exists("/test-files/download")):eq(true)
end)
it("runs a program from the internet", function()
setup_request()
expect(capture(stub, "wget", "run", "http://test.com", "a", "b", "c"))
:matches { ok = true, output = "Connecting to http://test.com... Success.\nHello a b c\n", error = "" }
end)
it("displays its usage when given no arguments", function()
setup_request()
expect(capture(stub, "wget"))
:matches { ok = true, output = "Usage:\nwget <url> [filename]\nwget run <url>\n", error = "" }
end)
it("can be completed", function()
local complete = shell.getCompletionInfo()["rom/programs/http/wget.lua"].fnComplete
expect(complete(shell, 1, "", {})):same { "run " }
end)
end)

View File

@ -0,0 +1,11 @@
local capture = require "test_helpers".capture_program
describe("The id program", function()
it("displays computer id", function()
local id = os.getComputerID()
expect(capture(stub, "id"))
:matches { ok = true, output = "This is computer #"..id.."\n", error = "" }
end)
end)

View File

@ -0,0 +1,14 @@
local capture = require "test_helpers".capture_program
describe("The motd program", function()
it("displays MODT", function()
local file = fs.open("/modt_check.txt","w")
file.write("Hello World!")
file.close()
settings.set("motd.path","/modt_check.txt")
expect(capture(stub, "motd"))
:matches { ok = true, output = "Hello World!\n", error = "" }
end)
end)

View File

@ -0,0 +1,26 @@
local capture = require "test_helpers".capture_program
describe("The move program", function()
local function touch(file)
io.open(file, "w"):close()
end
it("move a file", function()
touch("/test-files/move/a.txt")
shell.run("move /test-files/move/a.txt /test-files/move/b.txt")
expect(fs.exists("/test-files/move/a.txt")):eq(false)
expect(fs.exists("/test-files/move/b.txt")):eq(true)
end)
it("try to move a not existing file", function()
expect(capture(stub, "move nothing destination"))
:matches { ok = true, output = "", error = "No matching files\n" }
end)
it("displays the usage with no arguments", function()
expect(capture(stub, "move"))
:matches { ok = true, output = "Usage: mv <source> <destination>\n", error = "" }
end)
end)

View File

@ -0,0 +1,40 @@
local capture = require "test_helpers".capture_program
describe("The rename program", function()
local function touch(file)
io.open(file, "w"):close()
end
it("can rename a file", function()
touch("/test-files/rename/a.txt")
shell.run("rename /test-files/rename/a.txt /test-files/rename/b.txt")
expect(fs.exists("/test-files/rename/a.txt")):eq(false)
expect(fs.exists("/test-files/rename/b.txt")):eq(true)
end)
it("fails when renaming a file which doesn't exist", function()
expect(capture(stub, "rename nothing destination"))
:matches { ok = true, output = "", error = "No matching files\n" }
end)
it("fails when overwriting an existing file", function()
touch("/test-files/rename/c.txt")
expect(capture(stub, "rename /test-files/rename/c.txt /test-files/rename/c.txt"))
:matches { ok = true, output = "", error = "Destination exists\n" }
end)
it("fails when copying to read-only locations", function()
touch("/test-files/rename/d.txt")
expect(capture(stub, "rename /test-files/rename/d.txt /rom/test.txt"))
:matches { ok = true, output = "", error = "Destination is read-only\n" }
end)
it("displays the usage when given no arguments", function()
expect(capture(stub, "rename"))
:matches { ok = true, output = "Usage: rename <source> <destination>\n", error = "" }
end)
end)

View File

@ -0,0 +1,29 @@
local capture = require "test_helpers".capture_program
describe("The set program", function()
it("displays all settings", function()
settings.clear()
settings.set("Test","Hello World!")
settings.set("123",456)
expect(capture(stub, "set"))
:matches { ok = true, output = '"123" is 456\n"Test" is "Hello World!"\n', error = "" }
end)
it("displays a single settings", function()
settings.clear()
settings.set("Test","Hello World!")
settings.set("123",456)
expect(capture(stub, "set Test"))
:matches { ok = true, output = '"Test" is "Hello World!"\n', error = "" }
end)
it("set a setting", function()
expect(capture(stub, "set Test Hello"))
:matches { ok = true, output = '"Test" set to "Hello"\n', error = "" }
expect(settings.get("Test")):eq("Hello")
end)
end)

View File

@ -27,6 +27,10 @@ describe("The shell", function()
shell.setDir(shell.dir()) shell.setDir(shell.dir())
expect.error(shell.setDir, nil):eq("bad argument #1 (expected string, got nil)") expect.error(shell.setDir, nil):eq("bad argument #1 (expected string, got nil)")
end) end)
it("not existing directory", function()
expect.error(shell.setDir, "/rom/nothing"):eq("Not a directory")
end)
end) end)
describe("shell.setPath", function() describe("shell.setPath", function()

View File

@ -0,0 +1,12 @@
local capture = require "test_helpers".capture_program
describe("The time program", function()
it("displays time", function()
local time = textutils.formatTime(os.time())
local day = os.day()
expect(capture(stub, "time"))
:matches { ok = true, output = "The time is "..time.." on Day "..day.."\n", error = "" }
end)
end)

View File

@ -0,0 +1,26 @@
local capture = require "test_helpers".capture_program
describe("The type program", function()
it("displays the usage with no arguments", function()
expect(capture(stub, "type"))
:matches { ok = true, output = "Usage: type <path>\n", error = "" }
end)
it("displays the output for a file", function()
expect(capture(stub, "type /rom/startup.lua"))
:matches { ok = true, output = "file\n", error = "" }
end)
it("displays the output for a directory", function()
expect(capture(stub, "type /rom"))
:matches { ok = true, output = "directory\n", error = "" }
end)
it("displays the output for a not existing path", function()
expect(capture(stub, "type /rom/nothing"))
:matches { ok = true, output = "No such path\n", error = "" }
end)
end)