Skip to content

Commit

Permalink
Add some tests (#100)
Browse files Browse the repository at this point in the history
* Add docs on how to install packages
* Add tests for #74 and #79
  • Loading branch information
f-f authored Feb 7, 2019
1 parent d66ac73 commit 6947bf1
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 43 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ PureScript package manager and build tool powered by [Dhall][dhall] and
- [Commands](#commands)
- [Package management](#package-management)
- [Listing available packages](#listing-available-packages)
- [Adding and overriding dependencies](#adding-and-overriding-dependencies)
- [Adding a dependency](#adding-a-dependency)
- [Adding and overriding dependencies in the Package Set](#adding-and-overriding-dependencies-in-the-package-set)
- [Upgrading the Package Set](#upgrading-the-package-set)
- [Building, bundling and testing a project](#building-bundling-and-testing-a-project)
- [FAQ](#faq)
Expand Down Expand Up @@ -186,7 +187,15 @@ with their versions and URLs) by running:
$ spago list-packages
```

#### Adding and overriding dependencies
#### Adding a dependency

You can add dependencies from your package-set by running:

```bash
$ spago install my-new-package another-package
```

#### Adding and overriding dependencies in the Package Set

Let's say I'm a user of the `simple-json` package. Now, let's say I stumble upon a bug
in there, but thankfully I figure how to fix it. So I clone it locally and add my fix.
Expand Down
49 changes: 18 additions & 31 deletions app/Spago/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -148,24 +148,10 @@ makeConfig force = do
echo "Found a \"psc-package.json\" file, migrating to a new Spago config.."
-- update the project name
withConfigAST $ \config -> config { rawName = PscPackage.name pscConfig }
-- check if all dependencies are in package set
config <- ensureConfig
-- try to update the dependencies (will fail if not found in package set)
let pscPackages = map PackageName $ PscPackage.depends pscConfig
let notInSet = mapMaybe
(\p -> case Map.lookup p (packages config) of
Just _ -> Nothing
Nothing -> Just p)
pscPackages
case notInSet of
-- If no packages are not in our set, add them to existing dependencies
[] -> withConfigAST $ addRawDeps $ pscPackages
pkgs -> echo
( "\nSome of the dependencies in your psc-package configuration "
<> "were not found in spacchetti's package set.\n"
<> "Aborting the port of dependencies to your new spago config. "
<> "We didn't find:\n"
<> (Text.intercalate "\n" $ map (\p -> "- " <> packageName p) pkgs)
<> "\n")
config <- ensureConfig
addDependencies config pscPackages


-- | Takes a function that manipulates the Dhall AST of the Config,
Expand All @@ -182,9 +168,9 @@ withConfigAST transform = do
configText <- T.readTextFile path

-- parse the config without resolving imports
expr <- case Parser.exprFromText mempty configText of
(header, expr) <- case Parser.exprAndHeaderFromText mempty configText of
Left err -> throwIO err
Right ast -> case Dhall.denote ast of
Right (header, ast) -> case Dhall.denote ast of
-- remove Note constructors, and check if config is a record
Dhall.RecordLit ks -> do
rawConfig <- pure $ do
Expand All @@ -209,7 +195,7 @@ withConfigAST transform = do
$ fmap Dhall.toTextLit
$ fmap packageName rawDeps
mkNewAST _ v = v
pure $ Dhall.RecordLit $ Dhall.Map.mapWithKey mkNewAST ks
pure (header, Dhall.RecordLit $ Dhall.Map.mapWithKey mkNewAST ks)

e -> throwIO $ Dhall.ConfigIsNotRecord e

Expand All @@ -218,7 +204,7 @@ withConfigAST transform = do
resolvedExpr <- Dhall.Import.load expr
case Dhall.TypeCheck.typeOf resolvedExpr of
Left err -> throwIO err
Right _ -> T.writeTextFile path $ Dhall.pretty expr
Right _ -> T.writeTextFile path $ Dhall.prettyWithHeader header expr <> "\n"

where
toPkgsList
Expand All @@ -239,8 +225,10 @@ addRawDeps :: [PackageName] -> RawConfig -> RawConfig
addRawDeps newDeps config = config
{ rawDeps = List.sort $ List.nub (newDeps <> (rawDeps config)) }

-- | Adds the `name` dependency to the "dependencies" list in the Config,
-- sorts the dependencies, and writes the Config to file.
-- | Try to add the `newPackages` to the "dependencies" list in the Config.
-- It will not add any dependency if any of them is not in the package set.
-- If everything is fine instead, it will add the new deps, sort all the
-- dependencies, and write the Config back to file.
addDependencies :: Config -> [PackageName] -> IO ()
addDependencies config newPackages = do
let notInPackageSet = mapMaybe
Expand All @@ -249,15 +237,14 @@ addDependencies config newPackages = do
Nothing -> Just p)
newPackages
case notInPackageSet of
-- If no packages are not in our set, add them to existing dependencies
-- If none of the newPackages are outside of the set, add them to existing dependencies
[] -> withConfigAST $ addRawDeps newPackages
pkgs -> echo
( "\nSome of the dependencies you tried to add "
<> "were not found in spacchetti's package set.\n"
<> "Not adding new dependencies to your new spago config. "
<> "We didn't find:\n"
<> (Text.intercalate "\n" $ map (\p -> "- " <> packageName p) pkgs)
<> "\n")
pkgs -> echo $ "\nSome of the dependencies you tried to add "
<> "were not found in spacchetti's package set.\n"
<> "Not adding new dependencies to your new spago config. "
<> "We didn't find:\n"
<> (Text.intercalate "\n" $ map (\p -> "- " <> packageName p) pkgs)
<> "\n"



Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/spago-install-failure.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name =
"aaa"
, dependencies =
[ "effect", "console" ]
, packages =
./packages.dhall
}
11 changes: 11 additions & 0 deletions test/fixtures/spago-install-success.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name =
"aaa"
, dependencies =
[ "console", "effect", "foreign", "simple-json" ]
, packages =
./packages.dhall
}
6 changes: 5 additions & 1 deletion test/fixtures/spago-psc-failure.dhall
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name =
"aaa"
, dependencies =
[ "effect", "console" ]
, packages =
./packages.dhall
}
}
6 changes: 5 additions & 1 deletion test/fixtures/spago-psc-success.dhall
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name =
"aaa"
, dependencies =
[ "console", "effect", "prelude" ]
, packages =
./packages.dhall
}
}
9 changes: 9 additions & 0 deletions test/fixtures/test-output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
🍝
You should add some tests.
Installing 3 dependencies.
"prelude" already installed
"console" already installed
"effect" already installed
Installation complete.
Build succeeded.
Tests succeeded.
52 changes: 46 additions & 6 deletions test/spago-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import json
import time
from utils import expect_success, expect_failure, fail, run_for, check_fixture


Expand All @@ -17,6 +18,8 @@
"Spago should refuse to overwrite an existing project without -f"
)



# Here we check that spago does not overwrite any source files we might have
expect_success(
['rm', 'spago.dhall', 'packages.dhall'],
Expand All @@ -37,6 +40,8 @@
"Spago should always succeed in doing init with force"
)



# Here we check that spago can import a project from psc-package
with open('psc-package.json', 'w') as pscfile:
data = { "name": "aaa", "depends": [ "prelude" ], "set": "foo", "source": "bar" }
Expand All @@ -48,6 +53,7 @@
os.rename('spago.dhall', 'spago-psc-success.dhall')
check_fixture('spago-psc-success.dhall')


# But should not import dependencies that are not in the package-set
with open('psc-package.json', 'w') as pscfile:
data = { "name": "aaa", "depends": [ "prelude", "foo", "bar" ], "set": "foo", "source": "bar" }
Expand All @@ -60,30 +66,50 @@
check_fixture('spago-psc-failure.dhall')



## spago install

# Run `install` once and kill it soon to simulate failure
run_for(0.5, ['spago', 'install', '-j', '3'])

# Sleep for some time, as the above might take time to cleanup old processes
time.sleep(1)

expect_success(
['spago', 'install'],
"Subsequent installs should succeed anyways"
)


## spago build
expect_success(
['spago', 'install', 'simple-json', 'foreign'],
"Spago should be able to add dependencies"
)
os.rename('spago.dhall', 'spago-install-success.dhall')
check_fixture('spago-install-success.dhall')

expect_success(
['spago', 'build', '--', '-o myOutput'],
"Spago should pass options to purs"
['spago', 'install', 'foobar'],
"Spago should not add dependencies that are not in the package set"
)
assert os.path.isdir('myOutput') == True
os.rename('spago.dhall', 'spago-install-failure.dhall')
check_fixture('spago-install-failure.dhall')




## spago build

expect_success(
['spago', 'build'],
"Spago should build successfully"
)

expect_success(
['spago', 'build', '--', '-o myOutput'],
"Spago should pass options to purs"
)
assert os.path.isdir('myOutput') == True

os.mkdir('another_source_path')
os.rename('src/Main.purs', 'another_source_path/Main.purs')
expect_success(
Expand All @@ -92,14 +118,22 @@
)
os.rename('another_source_path/Main.purs', 'src/Main.purs')




## spago test

#### Note: here we check that the tests effectively run, by matching on the expected output

expect_success(
['spago', 'test'],
"Spago should test successfully"
"test-output.txt"
)




## spago bundle

expect_success(
Expand All @@ -110,6 +144,8 @@
check_fixture('bundle.js')




## spago make-module

expect_success(
Expand All @@ -120,11 +156,15 @@
check_fixture('module.js')





## Cleanup after tests

expect_success(
['rm', '-rf', '.spago', 'src', 'test', 'packages.dhall', 'spago.dhall', 'bundle.js',
'module.js', 'output', 'myOutput', 'another_source_path', 'psc-package.json',
'spago-psc-success.dhall', 'spago-psc-failure.dhall'],
'spago-psc-success.dhall', 'spago-psc-failure.dhall', 'spago-install-success.dhall',
'spago-install-failure.dhall'],
"Cleanup should empty the project folder"
)
16 changes: 14 additions & 2 deletions test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,27 @@ def fail(msg):
exit(1)


def call(expected_code, command, failure_msg):
def call(expected_code, command, failure_msg, expected_output_fixture=None):
"""
Try to run a command and exit if fails
"""
try:
return subprocess.check_output(command, stderr=subprocess.STDOUT).decode('utf-8')
except subprocess.CalledProcessError as e:
if e.returncode == expected_code:
return e.output.decode('utf-8')
out = e.output.decode('utf-8')

# Optionally check the output matches
if expected_output_fixture is not None:
with open('../fixtures/' + expected_output_fixture, 'r', encoding='utf-8') as expected:
expected_str = ''.join(expected.readlines())
if expected_str == out:
return out
else:
print("Output doesn't match fixture!\n\n")
print(out)
print('\n\n')
print(expected_str)
else:
print("FAILURE: " + failure_msg)
print("Program output:")
Expand Down

0 comments on commit 6947bf1

Please sign in to comment.