-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(#1417): Test API sketch. #1463
Conversation
feat(objectionary#1417): add FakeMaven class feat(objectionary#1417): simplify API code feat(objectionary#1417): add package-info.java
@volodya-lombrozo I would get rid of the interface here. It's test code, let's try to make it as short as possible. Verbosity is a sin in Java :) |
@volodya-lombrozo How would I execute |
@volodya-lombrozo @mximp as suggested before, I would go for this:
I think, we can handle this with just one class |
In this case I agree: since we don't need a hierarchy here - single class would be enough. |
@yegor256 @volodya-lombrozo Maybe we can allow
|
@mximp yes, definitely, I would defined it as |
|
* Maven compilation result. | ||
* @since 0.28.12 | ||
*/ | ||
public final class CompilationResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo it seems like we are doing here what Hamcrest matchers must do. I think it's better to stay with standard matchers for a while. Then, when we see that certain matchers are used very often, we will introduce our own. Making FakeMaven
do the assertion is a mix of concepts in one place, I would say (a violation of SRP, if you wish).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256
Well... I can remove it, I see that it definitely looks like overdesign, at lest of now, but I tried to avoid violation of SRP exactly by using CompilationResult
class. Also, I wanna hide complexity from programmers eyes. Just compare:
MatcherAssert.assertThat(
new Home(target).exists(
Paths.get(
String.format("%s/foo/x/main.%s", ParseMojo.DIR, TranspileMojo.EXT)
)
),
Matchers.is(true)
);
MatcherAssert.assertThat(
new TjSmart(
Catalogs.INSTANCE.make(foreign)
).getById("foo.x.main").exists("xmir"),
Matchers.is(true)
);
with:
MatcherAssert.assertThat(result, new XmirCreatedWell()));
looks beautiful, isn't?
Moreover, In some checks we have to know where target
dir is , where eo-foreign.json
is placed and etc. In other words, I need to know internal parts of FakeMaven
. What should I do? (Write a getter? :) By using CompilationResult
I can encapsulate all required internals.
It's a good question, actually :) like that:
Actually, if you take a look more precisely, you may notice the next facts:
By that reasons, I can conclude that we can have a simple |
@volodya-lombrozo maybe you can make |
Killer feature 👍🏻 :) |
@yegor256 @mximp I've removed redundant classes and added the killer feature (
MatcherAssert.assertThat(
new Home(maven.targetPath()).exists(
Paths.get(
String.format("%s/foo/x/main.%s", ParseMojo.DIR, TranspileMojo.EXT)
)
),
Matchers.is(true)
);
MatcherAssert.assertThat(
new TjSmart(
Catalogs.INSTANCE.make(maven.foreignPath())
).getById("foo.x.main").exists("xmir"),
Matchers.is(true)
); The same code appears several times (at least in
/**
* Path to compilation target directory.
* @return Path to target dir.
*/
public Path targetPath() {
return this.workspace.absolute(Paths.get("target"));
}
/**
* Path to 'eo-foreign.csv' or 'eo-foreign.json' file after all changes.
* @return Path to eo-foreign.* file.
*/
public Path foreignPath() {
return this.workspace.absolute(FakeMaven.FOREIGN_PATH);
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo what about suggestion above regarding .with()
method for props?
return this.workspace.absolute(FakeMaven.FOREIGN_PATH); | ||
} | ||
|
||
/** | ||
* Path to compilation target directory. | ||
* @return Path to target dir. | ||
* Creates eo-foreign.* file. In the future it is going to be a method for `MavenWorkspace` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo I believe it's better to create new issue for "future" plan. No need to have it in JavaDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mximp Sure. Removed.
@volodya-lombrozo why not do what I suggested earlier: make |
* @param value Attribute value. | ||
* @return The same maven instance. | ||
*/ | ||
public FakeMaven with(final TojoAttribute attribute, final Object value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo can't you just rename this method to withTojo
(or something similar) and get rid of this supplementary class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 fixed. with
-> withTojoAttribute
*/ | ||
public FakeMaven(final Path workspace) { | ||
this.workspace = new Home(workspace); | ||
this.params = this.defaultParams(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo to be honest, this looks wrong. Ctors must be code-free. When you have a need to put some code into ctor, your design is in trouble. Here, I would suggest to make a new method FakeMaven.withDefaults()
. The user must call it if they need defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 fixed.
* @return Workspace after executing Mojo. | ||
*/ | ||
public <T extends AbstractMojo> FakeMaven execute(final Class<T> mojo) { | ||
this.withEoForeign(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo this also looks wrong to me. Let's make our users call this. Now it's happening behind the scene and it's misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 Done.
But I disagree, because you expose implementation (again, it's about encapsulation):
- afaik, all tests will require
eo-foreign.csv
. What is the point to call it each time in each test the same way? - You are getting attached to the specific implementation through
eo-foreign
file, what if we decide to use a different approach? It will difficult to fix all that tests.
c428104
to
76576ea
Compare
@yegor256 please, check |
* @return Workspace with eo program. | ||
* @throws IOException If can't save eo program in workspace. | ||
*/ | ||
public FakeMaven forProgram(final String... program) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo why this is called forProgram
while other methods start with with
? Maybe withProgram
would be more logical?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 done
* @throws IOException If can't save eo program in workspace. | ||
*/ | ||
public FakeMaven forProgram(final String... program) throws IOException { | ||
final Path path = Paths.get(FakeMaven.PROGRAM_PATH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo I would make withProgram(String...)
method and then withFile(String, String)
method (the first argument is the path of the file and the second argument is the content). Then, withProgram
can use withFile
and you can get rid of static constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 done
*/ | ||
public FakeMaven withEoForeign() { | ||
final Tojo tojo = Catalogs.INSTANCE.make(this.foreignPath()) | ||
.add(FakeMaven.PROGRAM_ID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo static constants is a bad idea in general, unless you really mean something very "static". In this case, try to use supplementary methods, as I suggested above with withFile
and withProgram
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 done
@@ -0,0 +1,28 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo it's a single class FakeMaven
. Why do we need a package for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 done
@yegor256 check, please |
/** | ||
* Default eo-foreign.csv file format. | ||
*/ | ||
private static final String FOREIGN_FORMAT = "csv"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo you use these constants only once in the code, why do you make them as static literals? In general, try to stay away from static literals: https://www.yegor256.com/2015/07/06/public-static-literals.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 fixed.
@yegor256 please, check |
.add("foo.x.main"); | ||
tojo.set(AssembleMojo.ATTR_SCOPE, "compile") | ||
.set(AssembleMojo.ATTR_VERSION, "0.25.0") | ||
.set(AssembleMojo.ATTR_EO, this.workspace.absolute(this.prog)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@volodya-lombrozo don't you think that it would be better to add this line to the catalog when we call withProgram
? and then, get rid of this this.prog
attribute at all. in general, mutable attributes is a very strong signal that the design is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yegor256 yea, you right. It's much better. Thank you. Fixed.
@yegor256 Please, check. |
@rultor merge |
I've implemented a sketch for the future Test API. Notice how much we reduce the test code by encapsulating all properties, parameters, preparations, etc.
It's only the first and an approximate implementation.
@yegor256 @mximp provide your ideas, please.
Sketch for: #1417