-
Notifications
You must be signed in to change notification settings - Fork 842
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
Fix Naming Issues #30
Conversation
@@ -443,17 +438,17 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) { | |||
nil, | |||
}, | |||
}, | |||
Errors: []graphqlerrors.GraphQLFormattedError{ | |||
graphqlerrors.GraphQLFormattedError{ | |||
Errors: []FormattedError{ |
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.
@lenaten I think we should go for ErrFormatted
, is a Go convention to use Err
prefix for custom errors.
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.
@chris-ramon there are many things to improve but this pull request is the big one.
let's merge it, and refactor the little things later..
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.
good call, let's handle custom errors renaming on different pr's.
Thanks a lot! 🌟 for going ahead and work on this, appreciate reviews from anyone, thanks! |
@lenaten Thanks for taking up the daunting task for renaming / reorganizing the package. 👍🏻 My initial thoughts: 1) Tests package nameSince one of the major reasons for this refactor is to have a better API, can I propose that we use the It'll show how For e.g. package graphql_test
import (
"github.com/chris-ramon/graphql"
"reflect"
"testing"
)
... // truncated
func TestBasicGraphQLExample(t *testing.T) {
helloFieldResolved := func(p graphql.GQLFRParams) interface{} {
return "world"
}
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "RootQueryType",
Fields: graphql.FieldConfigMap{
"hello": &graphql.FieldConfig{
Description: "Returns `world`",
Type: graphql.String,
Resolve: helloFieldResolved,
},
},
}),
})
if err != nil {
t.Fatalf("wrong result, unexpected errors: %v", err.Error())
}
query := "{ hello }"
var expected interface{}
expected = map[string]interface{}{
"hello": "world",
}
resultChannel := make(chan *Result)
go graphql.Graphql(graphql.Params{
Schema: schema,
RequestString: query,
}, resultChannel)
result := <-resultChannel
if len(result.Errors) > 0 {
t.Fatalf("wrong result, unexpected errors: %v", result.Errors)
}
if !reflect.DeepEqual(result.Data, expected) {
t.Fatalf("wrong result, query: %v, graphql result diff: %v", query, Diff(expected, result))
}
} Any thoughts on this? 2) Separating internal implementation from public APIPreviously we had the following package structure internally:
I think this PR change is heading in the right direction with moving in the previous Can I propose that we separate the internal implementations from the public In other words, 99% of the time, there would be no reason for users to construct and deal with On the other side, we only expose public structs and methods in the By separating the implementation details and only expose/limit structs/methods that are truly public, we can easily overhaul the internals without worrying about breaking compatibility in the future. Also, it'll be less daunting to maintain than having 60+ files in a flat structure. So I'm proposing roughly the following package structure:
Appreciate any thoughts! |
@sogko thanks for your response. about the test package name, high level tests should be as your suggest but not the low level tests. about the project structure, I love to see the project structured like you suggested and I think it's should be the next move, but it's more complicated and time consuming thing to do now since it's cause many "cycle import" issues, and we need a clean API as soon as possible. |
Merge latest changes from HEAD
Merge latest changes from HEAD
Hi @lenaten Appreciate how much work you already put into this 👍🏻 I agree that clean API is necessary and would like to see move forward quickly. But personally, I don't feel easy about having that much files in the package root, I just imagine maintaining it would be a nightmare lol 💀 Regarding the import cycles, I see what you mean there. In fact, the structure I initially suggested would have cyclic dependencies (e.g Analysis using dependency graphI took some time to map out the dependency graph for the current package and the possible moves. Option 1: Move
|
@sogko I totally agree. thanks for your dependencies analysis, I'm on it.. |
@sogko I refactor like your suggestion and it's work fine but some of the tests still have "the cycle import" problem because they depends on graphql.Parse().. |
Hi @lenaten I've pulled your changes locally and took a look at it, and this seems like a good start 👍🏻 NotesImport cycles for testsI think this is where using the For e.g. in package visitor_test
import (
...
"github.com/chris-ramon/graphql-go"
"github.com/chris-ramon/graphql-go/language/ast"
"github.com/chris-ramon/graphql-go/language/visitor"
...
)
...
func TestVisitor_AllowsForEditingOnEnter(t *testing.T) {
query := `{ a, b, c { a, b, c } }`
astDoc := parse(t, query)
expectedQuery := `{ a, c { a, c } }`
expectedAST := parse(t, expectedQuery)
v := &visitor.VisitorOptions{
Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
switch node := p.Node.(type) {
case map[string]interface{}:
if testGetMapValueString(node, "Kind") == "Field" && testGetMapValueString(node, "Name.Value") == "b" {
return visitor.ActionUpdate, nil
}
}
return visitor.ActionNoChange, nil
},
}
editedAst := visitor.Visit(astDoc, v, nil)
if !reflect.DeepEqual(ASTToJSON(t, expectedAST), editedAst) {
t.Fatalf("Unexpected result, Diff: %v", Diff(expectedAST, editedAst))
}
}
|
@sogko actually your solution will work but I don't understand why tests of one package needs to be dependent on another package? maybe it's a sign of unnecessary coupling? |
Hi @lenaten Besides being a wonderful So test codes naturally depends on library code, but not the other way around. (i.e. Library code should not have access to test structs and methods.) For e.g
Black-box vs white-boxIn addition to that, the decision to put the test in the same package or in another For black-box testing: The tests won't have access to internal implementations, exactly what users of the library should not have access either. For white-box testing: I am not saying that we can't write the tests for exported APIs in white-box fashion, it is possible. But enforcing that the public APIs are written in black-box tests, we can have better assurances on the quality and allows for better maintainability. Testing for usabilityYou can look at the way the tests were written this way: besides testing for the correctness of a particular API, we also want to test its usability. Consider the following: package graphql
func TestForSomething(...) {
go Graphql(GraphqlParams{
Schema: schema,
RequestString: query,
}, resultChannel)
...
}
// vs
package graphql_test
import (
...
"github.com/chris-ramon/graphql-go"
)
func TestForSomething(...) {
go graphql.Graphql(graphql.GraphqlParams{
Schema: schema,
RequestString: query,
}, resultChannel)
...
} Both of the test are correct, but the second one allows us to actually use the library as we write the test. We can then feel the same excitement or worst, the same pains, as the user of this library. We could also see what imports the user needs to make in order to achieve something. (For e.g, previously we saw that every time user imports Share your thoughts on this 👍🏻 Cheers! |
Merge latest changes from HEAD
Merge latest changes from HEAD
- `visitor_test.go`: - Renamed package to `visitor_test` - Fixed minor previously missed find/replace - `printer_test.go`: - Renamed package to `printer_test` - Fixed minor previously missed find/replace - Fixed path to test kitchen-sink data - `schema_printer_test.go`: - Renamed package to `printer_test` - Fixed minor previously missed find/replace - Fixed path to test kitchen-sink data - `graphql_test.go` - Renamed package to `graphql_test` - Previously there was a hidden gotcha when the test was moved to `graphql` package - `StarWarsSchema` that was moved from `testutil` was defined in `init()` (which gets initialised when `testutil` gets imported) - `var Test` defined used the uninitialised `StarWarsSchema` variable. - Two solutions: 1) initialize `var Test` in `init()`, or 2) move test to `graphql_test` and `StarWarsSchema` gets initialized when `graphql` gets imported - Subtle, so I did both here.
``` $ go test ./... ok github.com/chris-ramon/graphql-go 0.177s ? github.com/chris-ramon/graphql-go/examples/http [no test files] ? github.com/chris-ramon/graphql-go/gqlerrors [no test files] ? github.com/chris-ramon/graphql-go/language/ast [no test files] ? github.com/chris-ramon/graphql-go/language/kinds [no test files] ok github.com/chris-ramon/graphql-go/language/lexer 0.017s ? github.com/chris-ramon/graphql-go/language/location [no test files] ok github.com/chris-ramon/graphql-go/language/parser 0.028s ok github.com/chris-ramon/graphql-go/language/printer 0.038s ? github.com/chris-ramon/graphql-go/language/source [no test files] ok github.com/chris-ramon/graphql-go/language/visitor 0.019s ```
- Separated test code from core library code (moved tests to `graphql_test`) ``` $ go test ./... ok github.com/chris-ramon/graphql-go 0.185s ? github.com/chris-ramon/graphql-go/examples/http [no test files] ? github.com/chris-ramon/graphql-go/gqlerrors [no test files] ? github.com/chris-ramon/graphql-go/language/ast [no test files] ? github.com/chris-ramon/graphql-go/language/kinds [no test files] ok github.com/chris-ramon/graphql-go/language/lexer 0.010s ? github.com/chris-ramon/graphql-go/language/location [no test files] ok github.com/chris-ramon/graphql-go/language/parser 0.028s ok github.com/chris-ramon/graphql-go/language/printer 0.043s ? github.com/chris-ramon/graphql-go/language/source [no test files] ok github.com/chris-ramon/graphql-go/language/visitor 0.016s ok github.com/chris-ramon/graphql-go/testutil 0.012s ```
@lenaten I've submitted a PR on your fork (lenaten#1) with the fix for the failed tests and restored the If you could kindly take a look and merge it into your Hopefully this can move the PR along a bit faster 👍🏻 Cheers! |
Fixed failed tests and restored `language/parser` and `testutil` packages
Awesome! thanks a lot for ur work on this guys! 🌟 Def agree on have black-box testing and changes looks good to me 👍 In regards renaming If this one is ready, feel free to merge it @sogko. |
Fix Naming Issues (Improve API for better readability and usability)
Hi,
I just refactor the whole project as described in issue #20 .
There are a lot of changes, and all tests passes expect one, needs help to figure out the reason.
e.g. Travis fail becasue the repo name changed from "graphql-go" to "graphql".